@stack0/sdk 0.5.17 → 0.6.1

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.
@@ -1003,6 +1003,7 @@ var CDN = class {
1003
1003
  const params = new URLSearchParams();
1004
1004
  if (request.projectSlug) params.set("projectSlug", request.projectSlug);
1005
1005
  if (request.environment) params.set("environment", request.environment);
1006
+ if (request.folder) params.set("folder", request.folder);
1006
1007
  if (request.periodStart) {
1007
1008
  const date = request.periodStart instanceof Date ? request.periodStart.toISOString() : request.periodStart;
1008
1009
  params.set("periodStart", date);
@@ -1062,6 +1063,36 @@ var CDN = class {
1062
1063
  const query = params.toString();
1063
1064
  return this.http.get(`/cdn/usage/storage-breakdown${query ? `?${query}` : ""}`);
1064
1065
  }
1066
+ /**
1067
+ * Get total stored bytes for a project or folder, derived assets included.
1068
+ *
1069
+ * Totals uploads plus everything the pipelines derived from them — video renditions, HLS
1070
+ * segments and manifests, thumbnails, GIFs — in one call. Use this to meter a plan limit:
1071
+ * paging `list()` and summing `size` counts uploads only, and an HLS ladder typically runs
1072
+ * well past the size of the source it came from.
1073
+ *
1074
+ * Check `unmeasuredAssets`. A nonzero value means some assets have derivatives whose bytes
1075
+ * have not been measured, so `totalBytes` is a floor rather than the full number.
1076
+ *
1077
+ * @example
1078
+ * ```typescript
1079
+ * const usage = await cdn.getStorageUsage({
1080
+ * projectSlug: 'my-project',
1081
+ * folder: '/customers/acme',
1082
+ * });
1083
+ * console.log(`${usage.totalFormatted} across ${usage.objectCount} objects`);
1084
+ * console.log(` uploads: ${usage.breakdown.originals.bytesFormatted}`);
1085
+ * console.log(` derived: ${usage.breakdown.derived.bytesFormatted}`);
1086
+ * ```
1087
+ */
1088
+ async getStorageUsage(request = {}) {
1089
+ const params = new URLSearchParams();
1090
+ if (request.projectSlug) params.set("projectSlug", request.projectSlug);
1091
+ if (request.environment) params.set("environment", request.environment);
1092
+ if (request.folder) params.set("folder", request.folder);
1093
+ const query = params.toString();
1094
+ return this.http.get(`/cdn/usage/storage${query ? `?${query}` : ""}`);
1095
+ }
1065
1096
  convertUsageDates(usage) {
1066
1097
  if (typeof usage.periodStart === "string") {
1067
1098
  usage.periodStart = new Date(usage.periodStart);
@@ -1338,6 +1369,112 @@ var CDN = class {
1338
1369
  return this.convertMergeJobDates(job);
1339
1370
  }
1340
1371
  // ============================================================================
1372
+ // Video Render Methods
1373
+ // ============================================================================
1374
+ /**
1375
+ * Render a declarative video spec into a video asset
1376
+ *
1377
+ * The spec describes scenes, layers, timing and media as data. There are no
1378
+ * compositions to write and no code to upload — Stack0 owns the renderer.
1379
+ *
1380
+ * `@stack0/video-spec` has the full types, validation and worked examples;
1381
+ * validating locally before you POST turns a round trip into a type error.
1382
+ *
1383
+ * @example
1384
+ * ```typescript
1385
+ * const job = await cdn.createRenderJob({
1386
+ * projectSlug: 'my-project',
1387
+ * spec: {
1388
+ * canvas: { width: 1080, height: 1920, fps: 30 },
1389
+ * audio: [{ src: musicAssetId, volume: 0.34 }],
1390
+ * scenes: [
1391
+ * {
1392
+ * id: 'hook',
1393
+ * duration: 2.5,
1394
+ * layers: [
1395
+ * { type: 'image', src: afterImageAssetId, zoom: { from: 1, to: 1.06 } },
1396
+ * { type: 'caption', text: 'i told my mom\nthe kitchen exploded', position: 'upperThird' },
1397
+ * ],
1398
+ * },
1399
+ * {
1400
+ * // No duration: the thread derives its own length from the messages
1401
+ * id: 'payoff',
1402
+ * layers: [
1403
+ * {
1404
+ * type: 'messageThread',
1405
+ * recipient: 'Mom',
1406
+ * imageSrc: afterImageAssetId,
1407
+ * messages: [
1408
+ * { sender: 'recipient', text: 'you home?', history: true },
1409
+ * { sender: 'user', text: '[IMAGE]' },
1410
+ * { sender: 'recipient', text: 'WHAT IS THAT' },
1411
+ * ],
1412
+ * },
1413
+ * ],
1414
+ * },
1415
+ * ],
1416
+ * },
1417
+ * webhookUrl: 'https://your-app.com/webhook',
1418
+ * });
1419
+ * console.log(job.durationInFrames); // known before rendering starts
1420
+ * ```
1421
+ */
1422
+ async createRenderJob(request) {
1423
+ const response = await this.http.post("/cdn/video/render", request);
1424
+ return this.convertRenderJobDates(response);
1425
+ }
1426
+ /**
1427
+ * Get a render job by ID with output asset details
1428
+ *
1429
+ * @example
1430
+ * ```typescript
1431
+ * const job = await cdn.getRenderJob('job-id');
1432
+ * if (job.status === 'completed' && job.outputAsset) {
1433
+ * console.log(`Output video: ${job.outputAsset.cdnUrl}`);
1434
+ * }
1435
+ * ```
1436
+ */
1437
+ async getRenderJob(jobId) {
1438
+ const response = await this.http.get(`/cdn/video/render/${jobId}`);
1439
+ return this.convertRenderJobDates(response);
1440
+ }
1441
+ /**
1442
+ * List render jobs with optional filters
1443
+ */
1444
+ async listRenderJobs(request) {
1445
+ const params = new URLSearchParams();
1446
+ params.set("projectSlug", request.projectSlug);
1447
+ if (request.status) params.set("status", request.status);
1448
+ if (request.limit) params.set("limit", request.limit.toString());
1449
+ if (request.offset) params.set("offset", request.offset.toString());
1450
+ const response = await this.http.get(`/cdn/video/render?${params.toString()}`);
1451
+ return {
1452
+ ...response,
1453
+ jobs: response.jobs.map((job) => this.convertRenderJobDates(job))
1454
+ };
1455
+ }
1456
+ /**
1457
+ * Cancel a pending or processing render job
1458
+ */
1459
+ async cancelRenderJob(jobId) {
1460
+ return this.http.post(`/cdn/video/render/${jobId}/cancel`, {});
1461
+ }
1462
+ convertRenderJobDates(job) {
1463
+ if (typeof job.createdAt === "string") {
1464
+ job.createdAt = new Date(job.createdAt);
1465
+ }
1466
+ if (job.updatedAt && typeof job.updatedAt === "string") {
1467
+ job.updatedAt = new Date(job.updatedAt);
1468
+ }
1469
+ if (job.startedAt && typeof job.startedAt === "string") {
1470
+ job.startedAt = new Date(job.startedAt);
1471
+ }
1472
+ if (job.completedAt && typeof job.completedAt === "string") {
1473
+ job.completedAt = new Date(job.completedAt);
1474
+ }
1475
+ return job;
1476
+ }
1477
+ // ============================================================================
1341
1478
  // S3 Import Methods
1342
1479
  // ============================================================================
1343
1480
  /**