1+ // Camera payload validation and artifact writers for node media commands.
12import * as fs from "node:fs/promises" ;
23import * as path from "node:path" ;
34import { fetchWithSsrFGuard } from "../infra/net/fetch-guard.js" ;
@@ -15,8 +16,10 @@ import {
1516const MAX_CAMERA_URL_DOWNLOAD_BYTES = 250 * 1024 * 1024 ;
1617const MAX_CAMERA_BASE64_BYTES = MAX_CAMERA_URL_DOWNLOAD_BYTES ;
1718
19+ /** Camera orientation accepted by node camera commands. */
1820export type CameraFacing = "front" | "back" ;
1921
22+ /** Validated still-image payload from `nodes camera snap`. */
2023export type CameraSnapPayload = {
2124 format : string ;
2225 base64 ?: string ;
@@ -25,6 +28,7 @@ export type CameraSnapPayload = {
2528 height : number ;
2629} ;
2730
31+ /** Validated video payload from `nodes camera clip`. */
2832export type CameraClipPayload = {
2933 format : string ;
3034 base64 ?: string ;
@@ -33,6 +37,7 @@ export type CameraClipPayload = {
3337 hasAudio : boolean ;
3438} ;
3539
40+ /** Validate and normalize an unknown camera still-image payload. */
3641export function parseCameraSnapPayload ( value : unknown ) : CameraSnapPayload {
3742 const obj = asRecord ( value ) ;
3843 const format = asString ( obj . format ) ;
@@ -46,6 +51,7 @@ export function parseCameraSnapPayload(value: unknown): CameraSnapPayload {
4651 return { format, ...( base64 ? { base64 } : { } ) , ...( url ? { url } : { } ) , width, height } ;
4752}
4853
54+ /** Validate and normalize an unknown camera clip payload. */
4955export function parseCameraClipPayload ( value : unknown ) : CameraClipPayload {
5056 const obj = asRecord ( value ) ;
5157 const format = asString ( obj . format ) ;
@@ -59,6 +65,7 @@ export function parseCameraClipPayload(value: unknown): CameraClipPayload {
5965 return { format, ...( base64 ? { base64 } : { } ) , ...( url ? { url } : { } ) , durationMs, hasAudio } ;
6066}
6167
68+ /** Build a deterministic temp path for a camera artifact. */
6269export function cameraTempPath ( opts : {
6370 kind : "snap" | "clip" ;
6471 facing ?: CameraFacing ;
@@ -76,6 +83,7 @@ export function cameraTempPath(opts: {
7683 return path . join ( tmpDir , `${ cliName } -camera-${ opts . kind } ${ facingPart } -${ id } ${ ext } ` ) ;
7784}
7885
86+ /** Download a node-hosted media URL to disk after HTTPS, host, redirect, and size checks. */
7987export async function writeUrlToFile (
8088 filePath : string ,
8189 url : string ,
@@ -95,6 +103,7 @@ export async function writeUrlToFile(
95103 ) ;
96104 }
97105
106+ // The node host is allowed even when private because the RPC response supplied its remote IP.
98107 const policy = {
99108 allowPrivateNetwork : true ,
100109 allowedHostnames : [ expectedHost ] ,
@@ -184,6 +193,7 @@ function estimateDecodedBase64Bytes(base64: string): number {
184193 return Math . floor ( ( normalized . length * 3 ) / 4 ) - padding ;
185194}
186195
196+ /** Decode a base64 media payload to disk with preflight and post-decode size checks. */
187197export async function writeBase64ToFile (
188198 filePath : string ,
189199 base64 : string ,
@@ -201,6 +211,7 @@ export async function writeBase64ToFile(
201211 return { path : filePath , bytes : buf . length } ;
202212}
203213
214+ /** Require the node remote IP needed to validate URL-backed camera payloads. */
204215export function requireNodeRemoteIp ( remoteIp ?: string ) : string {
205216 const normalized = remoteIp ?. trim ( ) ;
206217 if ( ! normalized ) {
@@ -209,6 +220,7 @@ export function requireNodeRemoteIp(remoteIp?: string): string {
209220 return normalized ;
210221}
211222
223+ /** Write either a URL-backed or base64-backed camera payload to disk. */
212224export async function writeCameraPayloadToFile ( params : {
213225 filePath : string ;
214226 payload : { url ?: string ; base64 ?: string } ;
@@ -228,6 +240,7 @@ export async function writeCameraPayloadToFile(params: {
228240 throw new Error ( params . invalidPayloadMessage ?? "invalid camera payload" ) ;
229241}
230242
243+ /** Write a camera clip payload to a generated temp file and return its path. */
231244export async function writeCameraClipPayloadToFile ( params : {
232245 payload : CameraClipPayload ;
233246 facing : CameraFacing ;
0 commit comments