vidspotai-shared 1.0.113 → 1.0.114

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.
Files changed (55) hide show
  1. package/lib/globals/types.d.ts +9 -1
  2. package/lib/globals/types.d.ts.map +1 -1
  3. package/lib/globals/types.js +9 -0
  4. package/lib/libs/index.d.ts +1 -0
  5. package/lib/libs/index.d.ts.map +1 -1
  6. package/lib/libs/index.js +1 -0
  7. package/lib/libs/mediaStore.d.ts +3 -31
  8. package/lib/libs/mediaStore.d.ts.map +1 -1
  9. package/lib/libs/mediaStore.js +16 -140
  10. package/lib/libs/storage/GcsBackend.d.ts +9 -0
  11. package/lib/libs/storage/GcsBackend.d.ts.map +1 -0
  12. package/lib/libs/storage/GcsBackend.js +42 -0
  13. package/lib/libs/storage/MediaStorage.d.ts +80 -0
  14. package/lib/libs/storage/MediaStorage.d.ts.map +1 -0
  15. package/lib/libs/storage/MediaStorage.js +105 -0
  16. package/lib/libs/storage/R2Backend.d.ts +23 -0
  17. package/lib/libs/storage/R2Backend.d.ts.map +1 -0
  18. package/lib/libs/storage/R2Backend.js +156 -0
  19. package/lib/libs/storage/StorageBackend.d.ts +41 -0
  20. package/lib/libs/storage/StorageBackend.d.ts.map +1 -0
  21. package/lib/libs/storage/StorageBackend.js +2 -0
  22. package/lib/libs/storage/index.d.ts +5 -0
  23. package/lib/libs/storage/index.d.ts.map +1 -0
  24. package/lib/libs/storage/index.js +20 -0
  25. package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts.map +1 -1
  26. package/lib/services/agent/tools/generateAvatarVideo.tool.js +3 -5
  27. package/lib/services/aiGen/providers/alibaba/alibaba.d.ts.map +1 -1
  28. package/lib/services/aiGen/providers/alibaba/alibaba.js +5 -11
  29. package/lib/services/aiGen/providers/bytedance/bytedance.service.d.ts.map +1 -1
  30. package/lib/services/aiGen/providers/bytedance/bytedance.service.js +5 -0
  31. package/lib/services/aiGen/providers/elevenlabs/elevenlabs.service.d.ts.map +1 -1
  32. package/lib/services/aiGen/providers/elevenlabs/elevenlabs.service.js +3 -7
  33. package/lib/services/aiGen/providers/google/google.service.d.ts.map +1 -1
  34. package/lib/services/aiGen/providers/google/google.service.js +7 -4
  35. package/lib/services/aiGen/providers/google/googleMusic.d.ts.map +1 -1
  36. package/lib/services/aiGen/providers/google/googleMusic.js +3 -7
  37. package/lib/services/aiGen/providers/kling/kling.service.d.ts +16 -7
  38. package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
  39. package/lib/services/aiGen/providers/kling/kling.service.js +2 -2
  40. package/lib/services/aiGen/providers/kling/klingImage.service.d.ts.map +1 -1
  41. package/lib/services/aiGen/providers/kling/klingImage.service.js +3 -5
  42. package/lib/services/aiGen/providers/kling/klingStatus.d.ts +1 -1
  43. package/lib/services/aiGen/providers/kling/klingStatus.d.ts.map +1 -1
  44. package/lib/services/aiGen/providers/kling/klingStatus.js +8 -19
  45. package/lib/services/aiGen/providers/minimax/minimax.service.d.ts.map +1 -1
  46. package/lib/services/aiGen/providers/minimax/minimax.service.js +7 -17
  47. package/lib/services/aiGen/providers/openai/openai.service.d.ts.map +1 -1
  48. package/lib/services/aiGen/providers/openai/openai.service.js +5 -13
  49. package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
  50. package/lib/services/aiGen/providers/pixverse/pixverse.service.js +5 -0
  51. package/lib/services/aiGen/providers/runway/runway.service.d.ts.map +1 -1
  52. package/lib/services/aiGen/providers/runway/runway.service.js +5 -10
  53. package/lib/services/gcp/uploadAudioBuffer.d.ts.map +1 -1
  54. package/lib/services/gcp/uploadAudioBuffer.js +4 -0
  55. package/package.json +1 -1
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.R2Backend = void 0;
37
+ /**
38
+ * Cloudflare R2 backend — zero-egress mirror (and the future primary).
39
+ * ====================================================================
40
+ *
41
+ * Today R2 is a best-effort MIRROR: the `cdn.vidspotai.com` Worker serves
42
+ * objects from R2 when present (free egress) and falls back to GCS otherwise.
43
+ * When GCS is decommissioned this becomes the primary — hence the full backend
44
+ * surface (write/read-url/delete) even though only writes run today.
45
+ *
46
+ * Canonical GCS-style paths are remapped into R2's clean taxonomy via `toR2Key`
47
+ * — the SAME transform the Worker looks objects up by, so migrate-side and
48
+ * lookup-side can never disagree.
49
+ *
50
+ * The `@aws-sdk/client-s3` import is LAZY (dynamic) so it stays out of the shared
51
+ * package's module import graph — that package is already heavy at import time
52
+ * and this must not add to Cloud Function cold start (memory/project_shared_lazy_load).
53
+ */
54
+ const promises_1 = require("fs/promises");
55
+ const r2KeyMap_1 = require("../r2KeyMap");
56
+ const logger_1 = require("../../utils/logger");
57
+ const R2_BUCKET = process.env.R2_BUCKET || "vidspot-media";
58
+ /** CDN host the Worker serves R2 from — the future delivery URL base. */
59
+ function cdnBase() {
60
+ return (process.env.MEDIA_CDN_BASE ||
61
+ process.env.NEXT_PUBLIC_MEDIA_CDN_BASE ||
62
+ "https://cdn.vidspotai.com").replace(/\/+$/, "");
63
+ }
64
+ function r2Config() {
65
+ return {
66
+ accessKeyId: process.env.CLOUDFLARE_R2_ACCESS_KEY_ID || process.env.R2_ACCESS_KEY_ID,
67
+ secretAccessKey: process.env.CLOUDFLARE_R2_SECRET_ACCESS_KEY ||
68
+ process.env.R2_SECRET_ACCESS_KEY,
69
+ endpoint: process.env.CLOUDFLARE_R2_S3_ENDPOINT || process.env.R2_S3_ENDPOINT,
70
+ };
71
+ }
72
+ class R2Backend {
73
+ constructor() {
74
+ this.name = "r2";
75
+ // Lazily-built singleton S3 client (only when the first R2 op actually runs).
76
+ this.client = null;
77
+ this.init = null;
78
+ }
79
+ /** True once creds+endpoint are present; a missing config is logged once. */
80
+ async getClient() {
81
+ if (this.client)
82
+ return this.client;
83
+ if (this.init)
84
+ return this.init;
85
+ this.init = (async () => {
86
+ const { accessKeyId, secretAccessKey, endpoint } = r2Config();
87
+ if (!accessKeyId || !secretAccessKey || !endpoint) {
88
+ logger_1.logger.warn("R2Backend: creds/endpoint missing — R2 ops will no-op");
89
+ return null;
90
+ }
91
+ const { S3Client: Client } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-s3")));
92
+ this.client = new Client({
93
+ region: "auto",
94
+ endpoint,
95
+ credentials: { accessKeyId, secretAccessKey },
96
+ });
97
+ return this.client;
98
+ })();
99
+ return this.init;
100
+ }
101
+ async write(key, body, contentType) {
102
+ const client = await this.getClient();
103
+ if (!client)
104
+ return;
105
+ const { PutObjectCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-s3")));
106
+ const r2Key = (0, r2KeyMap_1.toR2Key)(key);
107
+ await client.send(new PutObjectCommand({
108
+ Bucket: R2_BUCKET,
109
+ Key: r2Key,
110
+ Body: body,
111
+ ContentType: contentType,
112
+ }));
113
+ logger_1.logger.info("R2Backend: wrote object", { key, r2Key });
114
+ }
115
+ async writeFromFile(key, localPath, contentType) {
116
+ // Mirror-only path: read the already-validated local file and PutObject.
117
+ // Only runs when mirroring is enabled, so buffering the clip here is fine.
118
+ const body = await (0, promises_1.readFile)(localPath);
119
+ await this.write(key, body, contentType);
120
+ return body.byteLength;
121
+ }
122
+ /**
123
+ * Mirror an object already stored elsewhere (GCS) straight through, without
124
+ * buffering it in process memory — for objects a caller never downloads to
125
+ * a local file (e.g. a resumable-upload completion, which only has a GCS
126
+ * read stream). A single PutObject with an explicit ContentLength handles
127
+ * up to 5GiB without multipart, comfortably covering our upload ceiling.
128
+ */
129
+ async writeFromReadable(key, stream, contentType, size) {
130
+ const client = await this.getClient();
131
+ if (!client)
132
+ return;
133
+ const { PutObjectCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-s3")));
134
+ const r2Key = (0, r2KeyMap_1.toR2Key)(key);
135
+ await client.send(new PutObjectCommand({
136
+ Bucket: R2_BUCKET,
137
+ Key: r2Key,
138
+ Body: stream,
139
+ ContentType: contentType,
140
+ ContentLength: size,
141
+ }));
142
+ logger_1.logger.info("R2Backend: wrote object from stream", { key, r2Key, size });
143
+ }
144
+ /** Delivery URL once R2 is primary: the CDN host + clean key. */
145
+ async signedReadUrl(key) {
146
+ return `${cdnBase()}/${(0, r2KeyMap_1.toR2Key)(key)}`;
147
+ }
148
+ async delete(key) {
149
+ const client = await this.getClient();
150
+ if (!client)
151
+ return;
152
+ const { DeleteObjectCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-s3")));
153
+ await client.send(new DeleteObjectCommand({ Bucket: R2_BUCKET, Key: (0, r2KeyMap_1.toR2Key)(key) }));
154
+ }
155
+ }
156
+ exports.R2Backend = R2Backend;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Storage backend contract.
3
+ * =========================
4
+ *
5
+ * One narrow interface every object-storage implementation (GCS today, R2
6
+ * tomorrow, anything after) satisfies. `MediaStorage` composes backends behind
7
+ * this contract, so swapping the store — or flipping which one is primary — is a
8
+ * change in ONE place (`MediaStorage`), never at the ~30 write call sites.
9
+ *
10
+ * Keys are **canonical object paths** (the GCS-style key we've always used, e.g.
11
+ * `final_videos/<id>.mp4`). Each backend owns the mapping from that canonical
12
+ * path into its own keyspace (R2 remaps via `toR2Key`; GCS is identity). This
13
+ * keeps callers backend-agnostic — they pass one path and never think about R2's
14
+ * clean taxonomy.
15
+ */
16
+ import type { Readable } from "stream";
17
+ export interface IStorageBackend {
18
+ /** Human name for logs (e.g. "gcs", "r2"). */
19
+ readonly name: string;
20
+ /** Write in-memory bytes at `key`. */
21
+ write(key: string, body: Buffer, contentType: string): Promise<void>;
22
+ /**
23
+ * Stream a local file to `key` without buffering it whole in memory (large
24
+ * videos). Returns the stored object size so callers can integrity-check the
25
+ * upload against the local size.
26
+ */
27
+ writeFromFile(key: string, localPath: string, contentType: string): Promise<number>;
28
+ /** A durable read URL for `key` (far-future signed URL, or CDN host). */
29
+ signedReadUrl(key: string): Promise<string>;
30
+ /** Delete `key`. Best-effort; implementations may no-op on "not found". */
31
+ delete(key: string): Promise<void>;
32
+ /**
33
+ * Stream an already-open Readable (e.g. another backend's read stream)
34
+ * straight to `key`, without buffering it whole. Optional — only backends
35
+ * that mirror content already stored elsewhere need it (R2). `size` must be
36
+ * the exact byte length; S3-compatible PutObject requires it up front for a
37
+ * streaming body.
38
+ */
39
+ writeFromReadable?(key: string, stream: Readable, contentType: string, size: number): Promise<void>;
40
+ }
41
+ //# sourceMappingURL=StorageBackend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StorageBackend.d.ts","sourceRoot":"","sources":["../../../src/libs/storage/StorageBackend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,sCAAsC;IACtC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErE;;;;OAIG;IACH,aAAa,CACX,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB,yEAAyE;IACzE,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5C,2EAA2E;IAC3E,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC;;;;;;OAMG;IACH,iBAAiB,CAAC,CAChB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,QAAQ,EAChB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ export * from "./StorageBackend";
2
+ export * from "./GcsBackend";
3
+ export * from "./R2Backend";
4
+ export * from "./MediaStorage";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/libs/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./StorageBackend"), exports);
18
+ __exportStar(require("./GcsBackend"), exports);
19
+ __exportStar(require("./R2Backend"), exports);
20
+ __exportStar(require("./MediaStorage"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"generateAvatarVideo.tool.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/tools/generateAvatarVideo.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAkB,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAY5E,OAAO,EAAgB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE/D;;;;;;;;;;;;;;;;;GAiBG;AAEH,QAAA,MAAM,WAAW;;;;;;;;;;;;;;iBAwEb,CAAC;AAEL,QAAA,MAAM,YAAY;;;;iBAQhB,CAAC;AAEH,eAAO,MAAM,uBAAuB,EAAE,cAAc,CAClD,OAAO,WAAW,EAClB,OAAO,YAAY,CAqIpB,CAAC"}
1
+ {"version":3,"file":"generateAvatarVideo.tool.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/tools/generateAvatarVideo.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAkB,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAY5E,OAAO,EAAgB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE/D;;;;;;;;;;;;;;;;;GAiBG;AAEH,QAAA,MAAM,WAAW;;;;;;;;;;;;;;iBAwEb,CAAC;AAEL,QAAA,MAAM,YAAY;;;;iBAQhB,CAAC;AAEH,eAAO,MAAM,uBAAuB,EAAE,cAAc,CAClD,OAAO,WAAW,EAClB,OAAO,YAAY,CAmIpB,CAAC"}
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateAvatarVideoTool = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const aiModels_1 = require("../../../globals/aiModels");
6
- const firebase_1 = require("../../../libs/firebase");
6
+ const storage_1 = require("../../../libs/storage");
7
7
  const avatarProviderFactory_1 = require("../../avatarGen/avatarProviderFactory");
8
8
  const types_1 = require("../../aiGen/types");
9
9
  const rateLimiter_1 = require("../../rateLimiter");
@@ -193,10 +193,8 @@ exports.generateAvatarVideoTool = {
193
193
  ttsLimiter.releaseSlot();
194
194
  }
195
195
  const filePath = `agent-avatar-audio/${ctx.userId}/${ctx.agentRunId}-${Date.now()}.${ttsResult.extension}`;
196
- const file = (0, firebase_1.getBucket)().file(filePath);
197
- await file.save(ttsResult.audioBuffer, { contentType: ttsResult.mimeType });
198
- const [signedUrl] = await file.getSignedUrl({ action: "read", expires: "03-09-2491" });
199
- audioUrl = signedUrl;
196
+ // mediaStorage: GCS write + best-effort R2 mirror (zero-egress delivery).
197
+ audioUrl = await storage_1.mediaStorage.put(filePath, ttsResult.audioBuffer, ttsResult.mimeType);
200
198
  }
201
199
  // Hold the byo-media model slot through return — host's TaskPoller releases
202
200
  // when the task settles. Release here on submit error.
@@ -1 +1 @@
1
- {"version":3,"file":"alibaba.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/alibaba/alibaba.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAoGlB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAiBpB;AAED,qBAAa,cAAe,SAAQ,wBAAwB;IAE1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;;IAiBjC;;;;OAIG;YACW,OAAO;IAwDf,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA+E3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,EACzB,QAAQ,GACT,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA0EjD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA4EjC;;;OAGG;YACW,iBAAiB;IA4C/B;;;OAGG;YACW,kBAAkB;IA6DhC,aAAa,CAAC,EACZ,QAAQ,EACR,UAAU,EACV,WAAW,EACX,QAAQ,EACR,SAAiB,EACjB,SAAa,EACb,WAAW,GACZ,EAAE,iBAAiB,GAAG,MAAM;CAoB9B"}
1
+ {"version":3,"file":"alibaba.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/alibaba/alibaba.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAoGlB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAiBpB;AAED,qBAAa,cAAe,SAAQ,wBAAwB;IAE1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;;IAiBjC;;;;OAIG;YACW,OAAO;IAwDf,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA+E3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,EACzB,QAAQ,GACT,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAqEjD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA0EjC;;;OAGG;YACW,iBAAiB;IA4C/B;;;OAGG;YACW,kBAAkB;IA6DhC,aAAa,CAAC,EACZ,QAAQ,EACR,UAAU,EACV,WAAW,EACX,QAAQ,EACR,SAAiB,EACjB,SAAa,EACb,WAAW,GACZ,EAAE,iBAAiB,GAAG,MAAM;CAoB9B"}
@@ -9,7 +9,7 @@ const axios_1 = __importDefault(require("axios"));
9
9
  const types_1 = require("../../../../globals/types");
10
10
  const baseAiGenProvider_service_1 = require("../baseAiGenProvider.service");
11
11
  const aiModels_1 = require("../../../../globals/aiModels");
12
- const firebase_1 = require("../../../../libs/firebase");
12
+ const storage_1 = require("../../../../libs/storage");
13
13
  const helpers_1 = require("./helpers");
14
14
  const helpers_2 = require("../../helpers");
15
15
  const utils_1 = require("../../../../utils");
@@ -271,18 +271,14 @@ class AlibabaService extends baseAiGenProvider_service_1.BaseAiGenProviderServic
271
271
  }
272
272
  // console.log("Alibaba video URL:", videoUrl);
273
273
  const filePath = `${outputFilePath}/${outputFilename}.mp4`;
274
- const file = (0, firebase_1.getBucket)().file(filePath);
275
274
  try {
276
275
  const videoResp = await axios_1.default.get(videoUrl, {
277
276
  responseType: "arraybuffer",
278
277
  timeout: this.timeout,
279
278
  });
280
279
  const buffer = Buffer.from(videoResp.data);
281
- await file.save(buffer, { contentType: "video/mp4" });
282
- const [signedUrl] = await file.getSignedUrl({
283
- action: "read",
284
- expires: "03-09-2491",
285
- });
280
+ // mediaStorage: GCS write + best-effort R2 mirror (zero-egress delivery).
281
+ const signedUrl = await storage_1.mediaStorage.put(filePath, buffer, "video/mp4");
286
282
  return {
287
283
  videoUrl: signedUrl,
288
284
  status: types_1.EVideoSceneStatus.COMPLETED,
@@ -370,16 +366,14 @@ class AlibabaService extends baseAiGenProvider_service_1.BaseAiGenProviderServic
370
366
  if (!remoteUrls.length) {
371
367
  throw new Error("DashScope image returned no URLs");
372
368
  }
373
- const bucket = (0, firebase_1.getBucket)();
374
369
  const ts = Date.now();
375
370
  const urls = [];
376
371
  for (let i = 0; i < remoteUrls.length; i++) {
377
372
  const remoteUrl = remoteUrls[i];
378
373
  const bytes = Buffer.from(await (await axios_1.default.get(remoteUrl, { responseType: "arraybuffer", timeout: this.timeout })).data);
379
374
  const path = `images/dashscope/${ts}-${Math.random().toString(36).slice(2, 8)}-${i}.png`;
380
- const file = bucket.file(path);
381
- await file.save(bytes, { contentType: "image/png" });
382
- const [signed] = await file.getSignedUrl({ action: "read", expires: "03-09-2491" });
375
+ // mediaStorage: GCS write + best-effort R2 mirror (zero-egress delivery).
376
+ const signed = await storage_1.mediaStorage.put(path, bytes, "image/png");
383
377
  urls.push(signed);
384
378
  }
385
379
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"bytedance.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/bytedance/bytedance.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAUlB,qBAAa,gBAAiB,SAAQ,wBAAwB;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CACsD;IAI9E,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,WAAW;IAIb,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA2M3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA4HjD,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CAyEjD"}
1
+ {"version":3,"file":"bytedance.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/bytedance/bytedance.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAWlB,qBAAa,gBAAiB,SAAQ,wBAAwB;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CACsD;IAI9E,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,WAAW;IAIb,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA2M3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAiIjD,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CAyEjD"}
@@ -10,6 +10,7 @@ const helpers_1 = require("../../helpers");
10
10
  const aiModels_1 = require("../../../../globals/aiModels");
11
11
  const types_1 = require("../../../../globals/types");
12
12
  const firebase_1 = require("../../../../libs/firebase");
13
+ const storage_1 = require("../../../../libs/storage");
13
14
  const helpers_2 = require("../../../../utils/helpers");
14
15
  const errors_1 = require("../../../../utils/errors");
15
16
  const logger_1 = require("../../../../utils/logger");
@@ -278,6 +279,10 @@ class ByteDanceService extends baseAiGenProvider_service_1.BaseAiGenProviderServ
278
279
  },
279
280
  },
280
281
  });
282
+ // mediaStorage: best-effort R2 mirror (zero-egress delivery). GCS keeps the
283
+ // firebaseStorage download-token URL as the stored system-of-record URL; the
284
+ // CDN Worker resolves either URL family to the same R2 object.
285
+ await storage_1.mediaStorage.mirrorBytes(filePath, buffer, "video/mp4");
281
286
  const publicVideoUrl = `https://firebasestorage.googleapis.com/v0/b/${bucket.name}` +
282
287
  `/o/${encodeURIComponent(filePath)}?alt=media&token=${downloadToken}`;
283
288
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"elevenlabs.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/elevenlabs/elevenlabs.service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAGlB;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,wBAAwB;IAClE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAE1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAWhC;;;OAGG;IACG,oBAAoB,CACxB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC;IA0D/B,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAiB,EAAE,EAAE,iBAAiB,GAAG,MAAM;CAkBpF"}
1
+ {"version":3,"file":"elevenlabs.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/elevenlabs/elevenlabs.service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAGlB;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,wBAAwB;IAClE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAE1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAWhC;;;OAGG;IACG,oBAAoB,CACxB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC;IAsD/B,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAiB,EAAE,EAAE,iBAAiB,GAAG,MAAM;CAkBpF"}
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ElevenLabsAiGenService = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  const aiModels_1 = require("../../../../globals/aiModels");
9
- const firebase_1 = require("../../../../libs/firebase");
9
+ const storage_1 = require("../../../../libs/storage");
10
10
  const baseAiGenProvider_service_1 = require("../baseAiGenProvider.service");
11
11
  const helpers_1 = require("../../../../utils/helpers");
12
12
  /**
@@ -50,12 +50,8 @@ class ElevenLabsAiGenService extends baseAiGenProvider_service_1.BaseAiGenProvid
50
50
  });
51
51
  const buffer = Buffer.from(resp.data);
52
52
  const path = `sfx/elevenlabs/${params.outputFilename}.mp3`;
53
- const file = (0, firebase_1.getBucket)().file(path);
54
- await file.save(buffer, { contentType: "audio/mpeg" });
55
- const [signed] = await file.getSignedUrl({
56
- action: "read",
57
- expires: "03-09-2491",
58
- });
53
+ // mediaStorage: GCS write + best-effort R2 mirror (zero-egress delivery).
54
+ const signed = await storage_1.mediaStorage.put(path, buffer, "audio/mpeg");
59
55
  return {
60
56
  audioUrl: signed,
61
57
  mimeType: "audio/mpeg",
@@ -1 +1 @@
1
- {"version":3,"file":"google.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/google/google.service.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AA+ElB,qBAAa,aAAc,SAAQ,wBAAwB;IAKzD,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAK;;IAQ/C;;;;;;;;;OASG;IACG,YAAY,CAChB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,oBAAoB,CAAC;IAoChC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAoCvB;;;;OAIG;YACW,kBAAkB;IAsC1B,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA2T3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA8J3C,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;YAiBnB,cAAc;IAuK5B;;;;;;OAMG;IACH;;;;OAIG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAIjC,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAY,EAAE,UAAmB,EAAE,SAAiB,EAAE,SAAa,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,iBAAiB,GAAG,MAAM;CA8BpJ"}
1
+ {"version":3,"file":"google.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/google/google.service.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AA+ElB,qBAAa,aAAc,SAAQ,wBAAwB;IAKzD,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAK;;IAQ/C;;;;;;;;;OASG;IACG,YAAY,CAChB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,oBAAoB,CAAC;IAoChC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAoCvB;;;;OAIG;YACW,kBAAkB;IAsC1B,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA2T3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAmK3C,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;YAiBnB,cAAc;IAqK5B;;;;;;OAMG;IACH;;;;OAIG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAIjC,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAY,EAAE,UAAmB,EAAE,SAAiB,EAAE,SAAa,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,iBAAiB,GAAG,MAAM;CA8BpJ"}
@@ -10,6 +10,7 @@ const promises_1 = __importDefault(require("fs/promises"));
10
10
  const aiModels_1 = require("../../../../globals/aiModels");
11
11
  const types_1 = require("../../../../globals/types");
12
12
  const firebase_1 = require("../../../../libs/firebase");
13
+ const storage_1 = require("../../../../libs/storage");
13
14
  const helpers_1 = require("../../../../utils/helpers");
14
15
  const logger_1 = require("../../../../utils/logger");
15
16
  const errors_1 = require("../../../../utils/errors");
@@ -579,6 +580,10 @@ class GoogleService extends baseAiGenProvider_service_1.BaseAiGenProviderService
579
580
  action: "read",
580
581
  expires: "03-09-2491",
581
582
  });
583
+ // mediaStorage: best-effort R2 mirror of the integrity-validated local clip
584
+ // (zero-egress delivery) — the GCS streaming write above stays the guarded
585
+ // system-of-record; this only runs when R2_WRITE_ENABLED. Before cleanup.
586
+ await storage_1.mediaStorage.mirrorFromFile(filePath, localPath, "video/mp4");
582
587
  // Optionally clean up local file
583
588
  await promises_1.default
584
589
  .unlink(localPath)
@@ -752,7 +757,6 @@ class GoogleService extends baseAiGenProvider_service_1.BaseAiGenProviderService
752
757
  // platform/SDK regression isn't muted by the branch above.
753
758
  throw new Error("Google image generation returned no image bytes");
754
759
  }
755
- const bucket = (0, firebase_1.getBucket)();
756
760
  const ts = Date.now();
757
761
  const urls = [];
758
762
  for (let i = 0; i < allBytes.length; i++) {
@@ -760,9 +764,8 @@ class GoogleService extends baseAiGenProvider_service_1.BaseAiGenProviderService
760
764
  const { bytes, mime } = item;
761
765
  const ext = (mime.split("/")[1] ?? "png").toLowerCase();
762
766
  const path = `images/google/${ts}-${Math.random().toString(36).slice(2, 8)}-${i}.${ext}`;
763
- const file = bucket.file(path);
764
- await file.save(bytes, { contentType: mime });
765
- const [signed] = await file.getSignedUrl({ action: "read", expires: "03-09-2491" });
767
+ // mediaStorage: GCS write + best-effort R2 mirror (zero-egress delivery).
768
+ const signed = await storage_1.mediaStorage.put(path, bytes, mime);
766
769
  urls.push(signed);
767
770
  }
768
771
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"googleMusic.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/google/googleMusic.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAmEhC"}
1
+ {"version":3,"file":"googleMusic.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/google/googleMusic.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CA+DhC"}
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateGoogleMusic = generateGoogleMusic;
4
4
  const google_auth_library_1 = require("google-auth-library");
5
5
  const aiModels_1 = require("../../../../globals/aiModels");
6
- const firebase_1 = require("../../../../libs/firebase");
6
+ const storage_1 = require("../../../../libs/storage");
7
7
  /**
8
8
  * Lyria 2 (Vertex AI) music generation. Standalone — does NOT use the
9
9
  * GoogleGenAI (Gemini Developer API) client; it auths via ADC and hits the
@@ -63,12 +63,8 @@ async function generateGoogleMusic(params) {
63
63
  }
64
64
  const buffer = Buffer.from(audioB64, "base64");
65
65
  const path = `music/lyria/${params.outputFilename}.wav`;
66
- const file = (0, firebase_1.getBucket)().file(path);
67
- await file.save(buffer, { contentType: "audio/wav" });
68
- const [signed] = await file.getSignedUrl({
69
- action: "read",
70
- expires: "03-09-2491",
71
- });
66
+ // mediaStorage: GCS write + best-effort R2 mirror (zero-egress delivery).
67
+ const signed = await storage_1.mediaStorage.put(path, buffer, "audio/wav");
72
68
  return {
73
69
  audioUrl: signed,
74
70
  mimeType: "audio/wav",
@@ -1,19 +1,28 @@
1
1
  import { BaseAiGenProviderService } from "../baseAiGenProvider.service";
2
2
  import { CreditUsageParams, VideoGenerationParams, VideoGenerationResult, VideoStatusParams, VideoStatusResult } from "../types";
3
3
  /**
4
- * Kling runs TWO incompatible auth schemes, split by API surface. Verified
5
- * against the live API 2026-07-22.
4
+ * Kling runs TWO auth schemes. Verified against the live API 2026-07-22,
5
+ * re-verified 2026-09-16.
6
6
  *
7
7
  * "jwt" — the legacy AK/SK flow: an HS256 JWT signed per request from
8
8
  * KLING_ACCESS_KEY + KLING_SECRET_KEY. Accepted by every
9
9
  * /v1/videos/*, /v1/images/* and /account/* endpoint.
10
10
  *
11
- * "apiKey" — a static console-issued key sent verbatim as a bearer token,
12
- * required by the API 2.0 surface (/text-to-video/*,
13
- * /image-to-video/*, /tasks). Presenting a JWT there returns
14
- * HTTP 401 code 1002: "The current API does not support AK/SK;
15
- * please go to the console to create API key."
11
+ * "apiKey" — a static console-issued key sent verbatim as a bearer token.
12
+ * Required by the API 2.0 surface (/text-to-video/*,
13
+ * /image-to-video/*, /tasks) — JWT is REJECTED there (HTTP 401
14
+ * code 1002). Live-verified 2026-09-16 (curl against
15
+ * /v1/videos/text2video with a real submit) that it is ALSO
16
+ * accepted on every legacy /v1/videos/* endpoint — it is a
17
+ * strict superset of what JWT can auth, not a turbo-only key.
16
18
  * Created at https://kling.ai/dev/api-key → env KLING_API_KEY.
19
+ *
20
+ * Default is "apiKey", not "jwt": the AK/SK account is the one that hit
21
+ * ACCOUNT_QUOTA_EXCEEDED (Kling code 1102) in prod (2026-09-16), and rotating
22
+ * KLING_API_KEY alone did nothing for it because only the turbo path used
23
+ * that key — every other model kept authing against the same exhausted AK/SK
24
+ * account. Making apiKey the default routes ALL Kling traffic onto the new
25
+ * key/account; "jwt" is kept only as an explicit opt-in fallback.
17
26
  */
18
27
  export type KlingAuthMode = "jwt" | "apiKey";
19
28
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"kling.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/kling.service.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAyBlB;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE7C;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,wBAAwB;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAW;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IASxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkD;IAC9E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmD;;YAWlE,OAAO;IAiCf,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA+EjC;;;;;;;;OAQG;YACW,kBAAkB;IAgChC;;;;OAIG;YACW,WAAW;YA6BX,iBAAiB;YA6BjB,qBAAqB;YAgCrB,eAAe;YAkDf,mBAAmB;YAgCnB,uBAAuB;IAsI/B,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAiB7E;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAiBxB,cAAc,IAAI,MAAM;IAexB,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CAGjD"}
1
+ {"version":3,"file":"kling.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/kling.service.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAyBlB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE7C;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,wBAAwB;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAW;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IASxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkD;IAC9E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmD;;YAWlE,OAAO;IAiCf,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA+EjC;;;;;;;;OAQG;YACW,kBAAkB;IAgChC;;;;OAIG;YACW,WAAW;YA6BX,iBAAiB;YA6BjB,qBAAqB;YAgCrB,eAAe;YAkDf,mBAAmB;YAgCnB,uBAAuB;IAsI/B,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAiB7E;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAiBxB,cAAc,IAAI,MAAM;IAexB,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CAGjD"}
@@ -43,7 +43,7 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
43
43
  throw new Error("Missing KLING_SECRET_KEY or KLING_ACCESS_KEY in environment variables");
44
44
  }
45
45
  }
46
- async request(endpoint, method, body, timeout = this.generateTimeout, authMode = "jwt") {
46
+ async request(endpoint, method, body, timeout = this.generateTimeout, authMode = "apiKey") {
47
47
  const config = {
48
48
  method,
49
49
  url: `${this.baseUrl}${endpoint}`,
@@ -247,7 +247,7 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
247
247
  });
248
248
  return { task: task.data.task_id, status: types_1.EVideoSceneStatus.TRIGGERED };
249
249
  }
250
- async requestWithTimeoutRetry(endpoint, method, body, maxAttempts = 4, timeout = this.statusTimeout, authMode = "jwt") {
250
+ async requestWithTimeoutRetry(endpoint, method, body, maxAttempts = 4, timeout = this.statusTimeout, authMode = "apiKey") {
251
251
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
252
252
  try {
253
253
  return await this.request(endpoint, method, body, timeout, authMode);
@@ -1 +1 @@
1
- {"version":3,"file":"klingImage.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/klingImage.service.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AA2C3F,qBAAa,iBAAkB,SAAQ,wBAAwB;IAC7D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAE/D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IAExC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IAEtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IAErC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAGxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkD;IAC9E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmD;;IAWhF,OAAO,CAAC,cAAc;YAUR,OAAO;YA6BP,mBAAmB;YAsCnB,uBAAuB;YAmCvB,aAAa;YA+Bb,eAAe;IAmBvB,aAAa,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAuClF,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAa,EAAE,SAAiB,EAAE,WAAW,EAAE,EAAE,iBAAiB,GAAG,MAAM;CAStG"}
1
+ {"version":3,"file":"klingImage.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/klingImage.service.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AA2C3F,qBAAa,iBAAkB,SAAQ,wBAAwB;IAC7D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAE/D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IAExC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IAEtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IAErC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAGxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkD;IAC9E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmD;;IAWhF,OAAO,CAAC,cAAc;YAUR,OAAO;YA6BP,mBAAmB;YAsCnB,uBAAuB;YAmCvB,aAAa;YA+Bb,eAAe;IAiBvB,aAAa,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAuClF,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAa,EAAE,SAAiB,EAAE,WAAW,EAAE,EAAE,iBAAiB,GAAG,MAAM;CAStG"}
@@ -20,7 +20,7 @@ const https_1 = __importDefault(require("https"));
20
20
  const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
21
21
  const enums_1 = require("../../../../globals/aiModels/enums");
22
22
  const aiModels_1 = require("../../../../globals/aiModels");
23
- const firebase_1 = require("../../../../libs/firebase");
23
+ const storage_1 = require("../../../../libs/storage");
24
24
  const logger_1 = require("../../../../utils/logger");
25
25
  const helpers_1 = require("../../../../utils/helpers");
26
26
  const baseAiGenProvider_service_1 = require("../baseAiGenProvider.service");
@@ -153,11 +153,9 @@ class KlingImageService extends baseAiGenProvider_service_1.BaseAiGenProviderSer
153
153
  const contentType = response.headers.get("content-type") ?? "image/jpeg";
154
154
  const ext = contentType.split("/")[1]?.split(";")[0] ?? "jpg";
155
155
  const bytes = Buffer.from(await response.arrayBuffer());
156
- const bucket = (0, firebase_1.getBucket)();
157
156
  const path = `images/kling/${Date.now()}-${Math.random().toString(36).slice(2, 8)}-${idx}.${ext}`;
158
- const file = bucket.file(path);
159
- await file.save(bytes, { contentType });
160
- const [signed] = await file.getSignedUrl({ action: "read", expires: "03-09-2491" });
157
+ // mediaStorage: GCS write + best-effort R2 mirror (zero-egress delivery).
158
+ const signed = await storage_1.mediaStorage.put(path, bytes, contentType);
161
159
  return signed;
162
160
  }
163
161
  // ─── Public interface ──────────────────────────────────────────────────────
@@ -16,7 +16,7 @@ export declare function parseKlingDurationSec(raw: unknown): number | undefined;
16
16
  export interface KlingStatusDeps {
17
17
  /** Bound KlingService.requestWithTimeoutRetry. */
18
18
  request: <T>(endpoint: string, method: "POST" | "GET", body?: any, maxAttempts?: number, timeout?: number,
19
- /** "apiKey" for the API 2.0 surface (/tasks); defaults to the AK/SK JWT. */
19
+ /** Defaults to "apiKey" (see KlingAuthMode); pass "jwt" to force the legacy AK/SK flow. */
20
20
  authMode?: KlingAuthMode) => Promise<T>;
21
21
  /** Submit-endpoint timeout (also used for the potentially-large video download). */
22
22
  generateTimeout: number;
@@ -1 +1 @@
1
- {"version":3,"file":"klingStatus.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/klingStatus.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD;;;;;GAKG;AACH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAItE;AAED,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,OAAO,EAAE,CAAC,CAAC,EACT,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GAAG,KAAK,EACtB,IAAI,CAAC,EAAE,GAAG,EACV,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM;IAChB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,aAAa,KACrB,OAAO,CAAC,CAAC,CAAC,CAAC;IAChB,oFAAoF;IACpF,eAAe,EAAE,MAAM,CAAC;CACzB;AA4ED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,eAAe,EACrB,EAAE,IAAI,EAAE,cAAc,EAAE,cAAyB,EAAE,EAAE,iBAAiB,GACrE,OAAO,CAAC,iBAAiB,CAAC,CA4D5B;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,eAAe,EACrB,EAAE,IAAI,EAAE,cAAc,EAAE,cAAyB,EAAE,EAAE,iBAAiB,GACrE,OAAO,CAAC,iBAAiB,CAAC,CAgF5B;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,eAAe,EACrB,EAAE,IAAI,EAAE,cAAc,EAAE,cAAyB,EAAE,EAAE,iBAAiB,GACrE,OAAO,CAAC,iBAAiB,CAAC,CA2G5B"}
1
+ {"version":3,"file":"klingStatus.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/klingStatus.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD;;;;;GAKG;AACH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAItE;AAED,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,OAAO,EAAE,CAAC,CAAC,EACT,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GAAG,KAAK,EACtB,IAAI,CAAC,EAAE,GAAG,EACV,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM;IAChB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,aAAa,KACrB,OAAO,CAAC,CAAC,CAAC,CAAC;IAChB,oFAAoF;IACpF,eAAe,EAAE,MAAM,CAAC;CACzB;AA6ED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,eAAe,EACrB,EAAE,IAAI,EAAE,cAAc,EAAE,cAAyB,EAAE,EAAE,iBAAiB,GACrE,OAAO,CAAC,iBAAiB,CAAC,CA4D5B;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,eAAe,EACrB,EAAE,IAAI,EAAE,cAAc,EAAE,cAAyB,EAAE,EAAE,iBAAiB,GACrE,OAAO,CAAC,iBAAiB,CAAC,CA2E5B;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,eAAe,EACrB,EAAE,IAAI,EAAE,cAAc,EAAE,cAAyB,EAAE,EAAE,iBAAiB,GACrE,OAAO,CAAC,iBAAiB,CAAC,CAuG5B"}