@ttt-productions/media-processing-core 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"run-pipeline.d.ts","sourceRoot":"","sources":["../src/run-pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,qBAAqB,EACrB,mBAAmB,EAEpB,MAAM,gCAAgC,CAAC;AAIxC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAK/D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,YAAY,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACpE;AAiBD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA8K5F"}
1
+ {"version":3,"file":"run-pipeline.d.ts","sourceRoot":"","sources":["../src/run-pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,qBAAqB,EACrB,mBAAmB,EAEpB,MAAM,gCAAgC,CAAC;AAIxC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAK/D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,YAAY,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACpE;AAiBD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAiL5F"}
@@ -125,26 +125,10 @@ export async function runMediaPipeline(args) {
125
125
  onProgress?.({ phase: "done", percent: result.ok ? 1 : 0 });
126
126
  return result;
127
127
  }
128
- // Persist outputs
129
- onProgress?.({ phase: "persist_outputs", percent: 0 });
130
- const totalOut = result.outputs.length;
131
- let outIdx = 0;
132
- for (const out of result.outputs) {
133
- if (signal?.aborted) {
134
- return { ok: false, mediaType: result.mediaType, error: { code: "processing_canceled", message: "Processing canceled." } };
135
- }
136
- onProgress?.({ phase: "persist_outputs", percent: totalOut ? outIdx / totalOut : 0, detail: { key: out.key } });
137
- if (!out.path)
138
- continue;
139
- const persisted = await io.output.writeFromFile(out.path, out.key);
140
- if (persisted.url)
141
- out.url = persisted.url;
142
- if (persisted.path)
143
- out.path = persisted.path;
144
- outIdx += 1;
145
- }
146
- onProgress?.({ phase: "persist_outputs", percent: 1 });
147
- // POST moderation (processed outputs)
128
+ // POST moderation (processed outputs) — runs on the LOCAL output paths
129
+ // BEFORE any final persistence, so rejected output never reaches the
130
+ // final store (R2 / emulator). Ordering is load-bearing — see
131
+ // ttt-prod docs/design/media-assets-and-protected-serving.md.
148
132
  let mOut;
149
133
  if (moderation?.moderateOutput) {
150
134
  onProgress?.({ phase: "moderation_output", percent: 0 });
@@ -169,6 +153,25 @@ export async function runMediaPipeline(args) {
169
153
  };
170
154
  }
171
155
  }
156
+ // Persist outputs — only after input AND output moderation both passed.
157
+ onProgress?.({ phase: "persist_outputs", percent: 0 });
158
+ const totalOut = result.outputs.length;
159
+ let outIdx = 0;
160
+ for (const out of result.outputs) {
161
+ if (signal?.aborted) {
162
+ return { ok: false, mediaType: result.mediaType, error: { code: "processing_canceled", message: "Processing canceled." } };
163
+ }
164
+ onProgress?.({ phase: "persist_outputs", percent: totalOut ? outIdx / totalOut : 0, detail: { key: out.key } });
165
+ if (!out.path)
166
+ continue;
167
+ const persisted = await io.output.writeFromFile(out.path, out.key);
168
+ if (persisted.url)
169
+ out.url = persisted.url;
170
+ if (persisted.path)
171
+ out.path = persisted.path;
172
+ outIdx += 1;
173
+ }
174
+ onProgress?.({ phase: "persist_outputs", percent: 1 });
172
175
  const merged = mergeModeration(mIn ?? undefined, mOut ?? undefined);
173
176
  if (merged)
174
177
  result.moderation = merged;
@@ -1 +1 @@
1
- {"version":3,"file":"run-pipeline.js","sourceRoot":"","sources":["../src/run-pipeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-pipeline.js","sourceRoot":"","sources":["../src/run-pipeline.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,14 @@
1
1
  import type { MediaIO } from "../io/types.js";
2
- export interface CreateFirebaseMediaIOArgs {
2
+ import type { MediaObjectStore } from "./storage-ops.js";
3
+ export interface CreateObjectStoreMediaIOArgs {
4
+ /** Firebase Storage staging path of the uploaded source file. */
3
5
  inputStoragePath: string;
4
- outputStorageBasePath: string;
6
+ /** Store receiving the processed outputs (R2 or emulator). */
7
+ outputStore: MediaObjectStore;
8
+ /** Key prefix for outputs, e.g. `mediaAssets/{mediaAssetId}`. */
9
+ outputKeyPrefix: string;
10
+ /** Optional mime hint for the input. */
11
+ inputMime?: string;
5
12
  }
6
- export declare function createFirebaseMediaIO(args: CreateFirebaseMediaIOArgs): MediaIO;
13
+ export declare function createObjectStoreMediaIO(args: CreateObjectStoreMediaIOArgs): MediaIO;
7
14
  //# sourceMappingURL=firebase-media-io.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"firebase-media-io.d.ts","sourceRoot":"","sources":["../../src/server/firebase-media-io.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,MAAM,WAAW,yBAAyB;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAwB9E"}
1
+ {"version":3,"file":"firebase-media-io.d.ts","sourceRoot":"","sources":["../../src/server/firebase-media-io.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,WAAW,4BAA4B;IAC3C,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,WAAW,EAAE,gBAAgB,CAAC;IAC9B,iEAAiE;IACjE,eAAe,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,4BAA4B,GAAG,OAAO,CAkBpF"}
@@ -1,27 +1,23 @@
1
- // Firebase Storage MediaIO adapter for the media-processing pipeline.
2
- //
3
- // Internals delegate to `uploadFileToStorage` so URL construction and
4
- // token attachment have a single source of truth.
1
+ // MediaIO adapter: reads the staged upload from Firebase Storage, writes
2
+ // processed outputs through a MediaObjectStore (R2 in deployed envs, the
3
+ // Storage emulator locally). Output keys are extension-less:
4
+ // `${outputKeyPrefix}/${outputKey}` meaning lives in the asset registry,
5
+ // not the key. Writes return the object key; no URLs anywhere.
5
6
  import { getStorage } from "firebase-admin/storage";
6
- import { uploadFileToStorage } from "./storage-ops.js";
7
- export function createFirebaseMediaIO(args) {
7
+ export function createObjectStoreMediaIO(args) {
8
8
  const bucket = getStorage().bucket();
9
9
  return {
10
10
  input: {
11
+ mime: args.inputMime,
11
12
  async readToFile(localPath) {
12
13
  await bucket.file(args.inputStoragePath).download({ destination: localPath });
13
14
  },
14
15
  },
15
16
  output: {
16
17
  async writeFromFile(localPath, outputKey) {
17
- const ext = localPath.split(".").pop() || "";
18
- const destinationPath = `${args.outputStorageBasePath}/${outputKey}.${ext}`;
19
- const result = await uploadFileToStorage({
20
- bucket,
21
- localPath,
22
- destinationPath,
23
- });
24
- return { url: result.url, path: result.path };
18
+ const key = `${args.outputKeyPrefix}/${outputKey}`;
19
+ const result = await args.outputStore.putFile({ localPath, key });
20
+ return { path: result.key };
25
21
  },
26
22
  },
27
23
  };
@@ -1 +1 @@
1
- {"version":3,"file":"firebase-media-io.js","sourceRoot":"","sources":["../../src/server/firebase-media-io.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,sEAAsE;AACtE,kDAAkD;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAOvD,MAAM,UAAU,qBAAqB,CAAC,IAA+B;IACnE,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC,MAAM,EAAE,CAAC;IAErC,OAAO;QACL,KAAK,EAAE;YACL,KAAK,CAAC,UAAU,CAAC,SAAiB;gBAChC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;YAChF,CAAC;SACF;QACD,MAAM,EAAE;YACN,KAAK,CAAC,aAAa,CAAC,SAAiB,EAAE,SAAiB;gBACtD,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;gBAC7C,MAAM,eAAe,GAAG,GAAG,IAAI,CAAC,qBAAqB,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;gBAE5E,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;oBACvC,MAAM;oBACN,SAAS;oBACT,eAAe;iBAChB,CAAC,CAAC;gBAEH,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;YAChD,CAAC;SACF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"firebase-media-io.js","sourceRoot":"","sources":["../../src/server/firebase-media-io.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,yEAAyE;AACzE,6DAA6D;AAC7D,2EAA2E;AAC3E,+DAA+D;AAE/D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAepD,MAAM,UAAU,wBAAwB,CAAC,IAAkC;IACzE,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC,MAAM,EAAE,CAAC;IAErC,OAAO;QACL,KAAK,EAAE;YACL,IAAI,EAAE,IAAI,CAAC,SAAS;YACpB,KAAK,CAAC,UAAU,CAAC,SAAiB;gBAChC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;YAChF,CAAC;SACF;QACD,MAAM,EAAE;YACN,KAAK,CAAC,aAAa,CAAC,SAAiB,EAAE,SAAiB;gBACtD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,eAAe,IAAI,SAAS,EAAE,CAAC;gBACnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;gBAClE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;YAC9B,CAAC;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -1,4 +1,3 @@
1
- export * from "./build-download-url.js";
2
1
  export * from "./storage-ops.js";
3
2
  export * from "./firebase-media-io.js";
4
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC"}
@@ -1,4 +1,3 @@
1
- export * from "./build-download-url.js";
2
1
  export * from "./storage-ops.js";
3
2
  export * from "./firebase-media-io.js";
4
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC"}
@@ -1,45 +1,60 @@
1
1
  import type { getStorage } from "firebase-admin/storage";
2
2
  /** Firebase Admin Storage Bucket — inferred to avoid @google-cloud/storage dep. */
3
3
  export type Bucket = ReturnType<ReturnType<typeof getStorage>["bucket"]>;
4
- export interface StorageWriteResult {
5
- url: string;
6
- path: string;
7
- token: string;
4
+ export interface ObjectWriteResult {
5
+ key: string;
6
+ sizeBytes: number;
7
+ contentType: string;
8
8
  }
9
- /**
10
- * Upload a local file to Storage. Generates a download token, attaches it
11
- * to the file's metadata, and returns the emulator-aware download URL.
12
- *
13
- * Use this for: pipeline outputs (sharp, ffmpeg) and any other "local file
14
- * Storage" flow.
15
- */
16
- export declare function uploadFileToStorage(args: {
17
- bucket: Bucket;
18
- localPath: string;
19
- destinationPath: string;
20
- contentType?: string;
21
- cacheControl?: string;
22
- }): Promise<StorageWriteResult>;
23
- /**
24
- * Move or copy a file already in Storage to a new location. Generates a
25
- * fresh download token at the destination, attaches it, and returns the
26
- * emulator-aware download URL.
27
- *
28
- * Use this for any "Storage Storage" relocation flow.
29
- */
30
- export declare function relocateStorageFile(args: {
31
- bucket: Bucket;
32
- fromPath: string;
33
- toPath: string;
34
- mode: "move" | "copy";
35
- }): Promise<StorageWriteResult>;
36
- /**
37
- * Attach a fresh download token to a file already at its final Storage
38
- * location. Use when the file is already in place and only needs a token
39
- * (e.g., content-moderation rejection where the file was renamed earlier).
40
- */
41
- export declare function attachDownloadToken(args: {
9
+ export interface ObjectReadResult {
10
+ sizeBytes: number;
11
+ contentType: string;
12
+ }
13
+ export interface MediaObjectStore {
14
+ /** Upload a local file to the store at `key`. */
15
+ putFile(args: {
16
+ localPath: string;
17
+ key: string;
18
+ contentType?: string;
19
+ }): Promise<ObjectWriteResult>;
20
+ /** Server-side copy within the store. */
21
+ copy(args: {
22
+ fromKey: string;
23
+ toKey: string;
24
+ }): Promise<{
25
+ key: string;
26
+ }>;
27
+ /**
28
+ * Download an object's bytes from the store to a local file (streamed, so a
29
+ * large video never sits fully in memory). Used by safety evidence capture to
30
+ * pull prod media — which in deployed envs lives in R2 — before writing it into
31
+ * the separate (GCS) evidence vault: capture is inherently read-here-then-write,
32
+ * NOT a server-side copy, because source and vault are different backends.
33
+ */
34
+ readToFile(args: {
35
+ key: string;
36
+ localPath: string;
37
+ }): Promise<ObjectReadResult>;
38
+ /** Delete an object. Missing objects are a no-op, not an error. */
39
+ delete(key: string): Promise<void>;
40
+ }
41
+ export interface CreateR2ObjectStoreArgs {
42
+ accountId: string;
43
+ accessKeyId: string;
44
+ secretAccessKey: string;
45
+ bucket: string;
46
+ /** Override for tests; defaults to the real R2 S3 endpoint. */
47
+ endpoint?: string;
48
+ /** Override fetch for tests. */
49
+ fetchImpl?: typeof fetch;
50
+ }
51
+ export declare function createR2ObjectStore(args: CreateR2ObjectStoreArgs): MediaObjectStore;
52
+ export interface CreateEmulatorObjectStoreArgs {
42
53
  bucket: Bucket;
43
- storagePath: string;
44
- }): Promise<StorageWriteResult>;
54
+ /** Fixed token attached to every object so deterministic emulator URLs work
55
+ * (token URLs bypass rules in the emulator). Pass the app's constant. */
56
+ downloadToken: string;
57
+ }
58
+ export declare function createFirebaseEmulatorObjectStore(args: CreateEmulatorObjectStoreArgs): MediaObjectStore;
59
+ export declare function getMimeFromExt(ext: string): string;
45
60
  //# sourceMappingURL=storage-ops.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage-ops.d.ts","sourceRoot":"","sources":["../../src/server/storage-ops.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,mFAAmF;AACnF,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;AAEzE,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAID;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAmB9B;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAkB9B;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAY9B"}
1
+ {"version":3,"file":"storage-ops.d.ts","sourceRoot":"","sources":["../../src/server/storage-ops.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,mFAAmF;AACnF,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;AAEzE,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,OAAO,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpG,yCAAyC;IACzC,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzE;;;;;;OAMG;IACH,UAAU,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAChF,mEAAmE;IACnE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAQD,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,gBAAgB,CAuEnF;AAcD,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf;6EACyE;IACzE,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,6BAA6B,GAAG,gBAAgB,CA2CvG;AAQD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAsBlD"}
@@ -1,81 +1,144 @@
1
- // Storage write operationschokepoint for every file-storage side-effect
2
- // in the system. Inline `bucket.upload()`, `bucket.file().move()`,
3
- // `bucket.file().copy()`, and `setMetadata({ firebaseStorageDownloadTokens })`
4
- // calls are forbidden outside this module.
1
+ // Final-media object-store chokepoint — every final-media write/copy/delete in
2
+ // the system goes through a MediaObjectStore. Inline storage-provider calls for
3
+ // FINAL media are forbidden outside this module. (Upload STAGING stays plain
4
+ // Firebase Storage and is not this module's concern.)
5
5
  //
6
- // Every operation generates a fresh download token, attaches it to the file's
7
- // metadata, and returns a `StorageWriteResult` with the emulator-aware URL.
8
- import { randomUUID } from "node:crypto";
9
- import { buildFirebaseDownloadUrl } from "./build-download-url.js";
10
- const DEFAULT_CACHE_CONTROL = "public, max-age=31536000";
11
- /**
12
- * Upload a local file to Storage. Generates a download token, attaches it
13
- * to the file's metadata, and returns the emulator-aware download URL.
14
- *
15
- * Use this for: pipeline outputs (sharp, ffmpeg) and any other "local file
16
- * Storage" flow.
17
- */
18
- export async function uploadFileToStorage(args) {
19
- const token = randomUUID();
20
- const contentType = args.contentType ?? getMimeFromExt(extractExt(args.localPath));
21
- await args.bucket.upload(args.localPath, {
22
- destination: args.destinationPath,
23
- metadata: {
24
- contentType,
25
- cacheControl: args.cacheControl ?? DEFAULT_CACHE_CONTROL,
26
- metadata: { firebaseStorageDownloadTokens: token },
27
- },
6
+ // There are two implementations:
7
+ // - R2 (S3-compatible) for deployed environments the only place final user
8
+ // media lives in prod/dev; bytes are served exclusively by the gateway Worker.
9
+ // - Firebase Storage emulator for local dev/tests — objects get a FIXED
10
+ // caller-supplied download token so deterministic emulator URLs work with
11
+ // zero Cloudflare involvement. Production NEVER mints download tokens.
12
+ //
13
+ // Writes return `{ key }` never URLs. Display URLs are built at render time
14
+ // from asset refs (see ttt-core media-asset-url).
15
+ import { createReadStream, createWriteStream } from "node:fs";
16
+ import { stat } from "node:fs/promises";
17
+ import { Readable } from "node:stream";
18
+ import { pipeline } from "node:stream/promises";
19
+ import { AwsClient } from "aws4fetch";
20
+ const DEFAULT_CACHE_CONTROL = "public, max-age=31536000, immutable";
21
+ export function createR2ObjectStore(args) {
22
+ const endpoint = (args.endpoint ?? `https://${args.accountId}.r2.cloudflarestorage.com`).replace(/\/$/, "");
23
+ const client = new AwsClient({
24
+ accessKeyId: args.accessKeyId,
25
+ secretAccessKey: args.secretAccessKey,
26
+ service: "s3",
27
+ region: "auto",
28
28
  });
29
+ const doFetch = args.fetchImpl ?? fetch;
30
+ const objectUrl = (key) => `${endpoint}/${args.bucket}/${key.split("/").map(encodeURIComponent).join("/")}`;
31
+ async function signedFetch(url, init) {
32
+ const signed = await client.sign(url, { ...init, aws: { allHeaders: true } });
33
+ return doFetch(signed, { ...(init.body ? { duplex: "half" } : {}) });
34
+ }
29
35
  return {
30
- url: buildFirebaseDownloadUrl(args.bucket.name, args.destinationPath, token),
31
- path: args.destinationPath,
32
- token,
36
+ async putFile({ localPath, key, contentType }) {
37
+ const { size } = await stat(localPath);
38
+ const ct = contentType ?? getMimeFromExt(extractExt(localPath));
39
+ const res = await signedFetch(objectUrl(key), {
40
+ method: "PUT",
41
+ headers: {
42
+ "content-type": ct,
43
+ "content-length": String(size),
44
+ "cache-control": DEFAULT_CACHE_CONTROL,
45
+ },
46
+ body: createReadStream(localPath),
47
+ });
48
+ if (!res.ok) {
49
+ throw new Error(`R2 putFile failed for ${key}: ${res.status} ${await safeText(res)}`);
50
+ }
51
+ return { key, sizeBytes: size, contentType: ct };
52
+ },
53
+ async copy({ fromKey, toKey }) {
54
+ const res = await signedFetch(objectUrl(toKey), {
55
+ method: "PUT",
56
+ headers: {
57
+ "x-amz-copy-source": `/${args.bucket}/${fromKey.split("/").map(encodeURIComponent).join("/")}`,
58
+ },
59
+ });
60
+ if (!res.ok) {
61
+ throw new Error(`R2 copy failed ${fromKey} -> ${toKey}: ${res.status} ${await safeText(res)}`);
62
+ }
63
+ return { key: toKey };
64
+ },
65
+ async readToFile({ key, localPath }) {
66
+ const res = await signedFetch(objectUrl(key), { method: "GET" });
67
+ if (!res.ok || !res.body) {
68
+ throw new Error(`R2 readToFile failed for ${key}: ${res.status} ${await safeText(res)}`);
69
+ }
70
+ const contentType = res.headers.get("content-type") ?? "application/octet-stream";
71
+ // res.body is a web ReadableStream; stream it to disk so large media never
72
+ // sits fully in memory.
73
+ await pipeline(Readable.fromWeb(res.body), createWriteStream(localPath));
74
+ const { size } = await stat(localPath);
75
+ return { sizeBytes: size, contentType };
76
+ },
77
+ async delete(key) {
78
+ const res = await signedFetch(objectUrl(key), { method: "DELETE" });
79
+ // S3 DELETE returns 204 even for missing keys; anything else non-ok is real.
80
+ if (!res.ok && res.status !== 404) {
81
+ throw new Error(`R2 delete failed for ${key}: ${res.status} ${await safeText(res)}`);
82
+ }
83
+ },
33
84
  };
34
85
  }
35
- /**
36
- * Move or copy a file already in Storage to a new location. Generates a
37
- * fresh download token at the destination, attaches it, and returns the
38
- * emulator-aware download URL.
39
- *
40
- * Use this for any "Storage → Storage" relocation flow.
41
- */
42
- export async function relocateStorageFile(args) {
43
- const token = randomUUID();
44
- if (args.mode === "move") {
45
- await args.bucket.file(args.fromPath).move(args.toPath);
86
+ async function safeText(res) {
87
+ try {
88
+ return (await res.text()).slice(0, 500);
46
89
  }
47
- else {
48
- await args.bucket.file(args.fromPath).copy(args.bucket.file(args.toPath));
90
+ catch {
91
+ return "<no body>";
49
92
  }
50
- await args.bucket.file(args.toPath).setMetadata({
51
- metadata: { firebaseStorageDownloadTokens: token },
52
- });
53
- return {
54
- url: buildFirebaseDownloadUrl(args.bucket.name, args.toPath, token),
55
- path: args.toPath,
56
- token,
57
- };
58
93
  }
59
- /**
60
- * Attach a fresh download token to a file already at its final Storage
61
- * location. Use when the file is already in place and only needs a token
62
- * (e.g., content-moderation rejection where the file was renamed earlier).
63
- */
64
- export async function attachDownloadToken(args) {
65
- const token = randomUUID();
66
- await args.bucket.file(args.storagePath).setMetadata({
67
- metadata: { firebaseStorageDownloadTokens: token },
68
- });
94
+ export function createFirebaseEmulatorObjectStore(args) {
95
+ const { bucket, downloadToken } = args;
69
96
  return {
70
- url: buildFirebaseDownloadUrl(args.bucket.name, args.storagePath, token),
71
- path: args.storagePath,
72
- token,
97
+ async putFile({ localPath, key, contentType }) {
98
+ const { size } = await stat(localPath);
99
+ const ct = contentType ?? getMimeFromExt(extractExt(localPath));
100
+ await bucket.upload(localPath, {
101
+ destination: key,
102
+ metadata: {
103
+ contentType: ct,
104
+ cacheControl: DEFAULT_CACHE_CONTROL,
105
+ metadata: { firebaseStorageDownloadTokens: downloadToken },
106
+ },
107
+ });
108
+ return { key, sizeBytes: size, contentType: ct };
109
+ },
110
+ async copy({ fromKey, toKey }) {
111
+ await bucket.file(fromKey).copy(bucket.file(toKey));
112
+ await bucket.file(toKey).setMetadata({
113
+ metadata: { firebaseStorageDownloadTokens: downloadToken },
114
+ });
115
+ return { key: toKey };
116
+ },
117
+ async readToFile({ key, localPath }) {
118
+ const file = bucket.file(key);
119
+ await file.download({ destination: localPath });
120
+ const [meta] = await file.getMetadata();
121
+ const { size } = await stat(localPath);
122
+ const contentType = meta.contentType ?? "application/octet-stream";
123
+ return { sizeBytes: size, contentType };
124
+ },
125
+ async delete(key) {
126
+ try {
127
+ await bucket.file(key).delete();
128
+ }
129
+ catch (e) {
130
+ if (e?.code === 404 || /No such object/i.test(String(e?.message)))
131
+ return;
132
+ throw e;
133
+ }
134
+ },
73
135
  };
74
136
  }
137
+ // ---------------------------------------------------------------------------
75
138
  function extractExt(localPath) {
76
139
  return localPath.split(".").pop() || "";
77
140
  }
78
- function getMimeFromExt(ext) {
141
+ export function getMimeFromExt(ext) {
79
142
  switch (ext.toLowerCase()) {
80
143
  case "jpg":
81
144
  case "jpeg":
@@ -1 +1 @@
1
- {"version":3,"file":"storage-ops.js","sourceRoot":"","sources":["../../src/server/storage-ops.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage-ops.js","sourceRoot":"","sources":["../../src/server/storage-ops.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/media-processing-core",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ttt-productions/ttt-packages.git",
@@ -31,7 +31,8 @@
31
31
  "prepublishOnly": "npm run clean && npm run build"
32
32
  },
33
33
  "dependencies": {
34
- "@ttt-productions/media-schemas": "^0.10.0",
34
+ "@ttt-productions/media-schemas": "^0.12.0",
35
+ "aws4fetch": "^1.0.20",
35
36
  "sharp": "^0.34.1"
36
37
  },
37
38
  "peerDependencies": {
@@ -1,2 +0,0 @@
1
- export declare function buildFirebaseDownloadUrl(bucketName: string, storagePath: string, downloadToken: string): string;
2
- //# sourceMappingURL=build-download-url.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build-download-url.d.ts","sourceRoot":"","sources":["../../src/server/build-download-url.ts"],"names":[],"mappings":"AAYA,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,GACpB,MAAM,CAOR"}
@@ -1,20 +0,0 @@
1
- // Single source of truth for Firebase Storage download URL construction.
2
- //
3
- // Emulator awareness: when `FIREBASE_STORAGE_EMULATOR_HOST` is set (the
4
- // Firebase Admin SDK auto-sets this when the Storage emulator is running),
5
- // constructed URLs target the local emulator. Otherwise they target the
6
- // production Firebase Storage CDN. This is critical for E2E tests — without
7
- // it, browsers running against the emulator fetch production URLs and 404.
8
- //
9
- // Every download URL produced anywhere in the system MUST come from this
10
- // function. Inline construction (`https://firebasestorage.googleapis.com/...`)
11
- // is forbidden — it bypasses the emulator branch and breaks E2E tests.
12
- export function buildFirebaseDownloadUrl(bucketName, storagePath, downloadToken) {
13
- const encodedPath = encodeURIComponent(storagePath);
14
- const emulatorHost = process.env.FIREBASE_STORAGE_EMULATOR_HOST;
15
- const baseUrl = emulatorHost
16
- ? `http://${emulatorHost}`
17
- : "https://firebasestorage.googleapis.com";
18
- return `${baseUrl}/v0/b/${bucketName}/o/${encodedPath}?alt=media&token=${downloadToken}`;
19
- }
20
- //# sourceMappingURL=build-download-url.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build-download-url.js","sourceRoot":"","sources":["../../src/server/build-download-url.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,EAAE;AACF,wEAAwE;AACxE,2EAA2E;AAC3E,wEAAwE;AACxE,4EAA4E;AAC5E,2EAA2E;AAC3E,EAAE;AACF,yEAAyE;AACzE,+EAA+E;AAC/E,uEAAuE;AAEvE,MAAM,UAAU,wBAAwB,CACtC,UAAkB,EAClB,WAAmB,EACnB,aAAqB;IAErB,MAAM,WAAW,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC;IAChE,MAAM,OAAO,GAAG,YAAY;QAC1B,CAAC,CAAC,UAAU,YAAY,EAAE;QAC1B,CAAC,CAAC,wCAAwC,CAAC;IAC7C,OAAO,GAAG,OAAO,SAAS,UAAU,MAAM,WAAW,oBAAoB,aAAa,EAAE,CAAC;AAC3F,CAAC"}