@transloadit/node 4.3.0 → 4.3.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.
package/dist/tus.js CHANGED
@@ -4,11 +4,13 @@ import debug from 'debug';
4
4
  import pMap from 'p-map';
5
5
  import { Upload } from 'tus-js-client';
6
6
  const log = debug('transloadit');
7
- export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize, uploadConcurrency, onProgress, signal, uploadUrls, }) {
7
+ const logWarn = debug('transloadit:warn');
8
+ export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize, uploadConcurrency, onProgress, signal, uploadUrls, uploadBehavior = 'await', }) {
8
9
  const streamLabels = Object.keys(streamsMap);
9
10
  let totalBytes = 0;
10
11
  let lastEmittedProgress = 0;
11
12
  const sizes = {};
13
+ const uploadUrlsResult = { ...(uploadUrls ?? {}) };
12
14
  const haveUnknownLengthStreams = streamLabels.some((label) => !streamsMap[label]?.path);
13
15
  // Initialize size data
14
16
  await pMap(streamLabels, async (label) => {
@@ -27,6 +29,8 @@ export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize,
27
29
  }
28
30
  }, { concurrency: 5, signal });
29
31
  const uploadProgresses = {};
32
+ const completionPromises = [];
33
+ const uploadUrlPromises = [];
30
34
  async function uploadSingleStream(label) {
31
35
  uploadProgresses[label] = 0;
32
36
  const streamInfo = streamsMap[label];
@@ -64,7 +68,42 @@ export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize,
64
68
  }
65
69
  };
66
70
  const filename = path ? basename(path) : label;
67
- await new Promise((resolvePromise, rejectPromise) => {
71
+ if (uploadBehavior === 'none' && uploadUrls?.[label]) {
72
+ uploadUrlsResult[label] = uploadUrls[label];
73
+ uploadUrlPromises.push(Promise.resolve());
74
+ completionPromises.push(Promise.resolve());
75
+ return;
76
+ }
77
+ let urlResolved = false;
78
+ let resolveUrl = () => { };
79
+ let rejectUrl = () => { };
80
+ const uploadUrlPromise = new Promise((resolve, reject) => {
81
+ resolveUrl = () => {
82
+ if (urlResolved)
83
+ return;
84
+ urlResolved = true;
85
+ resolve();
86
+ };
87
+ rejectUrl = (err) => {
88
+ if (urlResolved)
89
+ return;
90
+ urlResolved = true;
91
+ reject(err);
92
+ };
93
+ });
94
+ let resolveCompletion = () => { };
95
+ let rejectCompletion = () => { };
96
+ const completionPromise = new Promise((resolve, reject) => {
97
+ resolveCompletion = resolve;
98
+ rejectCompletion = reject;
99
+ });
100
+ uploadUrlPromises.push(uploadUrlPromise);
101
+ completionPromises.push(completionPromise);
102
+ if (uploadUrls?.[label]) {
103
+ uploadUrlsResult[label] = uploadUrls[label];
104
+ resolveUrl();
105
+ }
106
+ const startPromise = new Promise((resolvePromise, rejectPromise) => {
68
107
  if (!assembly.assembly_ssl_url) {
69
108
  rejectPromise(new Error('assembly_ssl_url is not present in the assembly status'));
70
109
  return;
@@ -76,16 +115,21 @@ export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize,
76
115
  }
77
116
  // Wrap resolve/reject to clean up abort listener
78
117
  let abortHandler;
79
- const resolve = (payload) => {
118
+ const resolve = (_payload) => {
80
119
  if (abortHandler)
81
120
  signal?.removeEventListener('abort', abortHandler);
82
- resolvePromise(payload);
121
+ resolveCompletion();
122
+ resolveUrl();
123
+ resolvePromise();
83
124
  };
84
125
  const reject = (err) => {
85
126
  if (abortHandler)
86
127
  signal?.removeEventListener('abort', abortHandler);
128
+ rejectCompletion(err);
129
+ rejectUrl(err);
87
130
  rejectPromise(err);
88
131
  };
132
+ let tusUpload;
89
133
  const tusOptions = {
90
134
  endpoint: assembly.tus_url,
91
135
  uploadUrl: uploadUrls?.[label],
@@ -97,6 +141,17 @@ export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize,
97
141
  onError: reject,
98
142
  onProgress: onTusProgress,
99
143
  onSuccess: resolve,
144
+ onUploadUrlAvailable: () => {
145
+ const url = tusUpload?.url;
146
+ if (url) {
147
+ uploadUrlsResult[label] = url;
148
+ }
149
+ resolveUrl();
150
+ if (uploadBehavior === 'none') {
151
+ tusUpload.abort();
152
+ resolveCompletion();
153
+ }
154
+ },
100
155
  };
101
156
  // tus-js-client doesn't like undefined/null
102
157
  if (size != null)
@@ -105,7 +160,7 @@ export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize,
105
160
  tusOptions.chunkSize = chunkSize;
106
161
  if (uploadLengthDeferred)
107
162
  tusOptions.uploadLengthDeferred = uploadLengthDeferred;
108
- const tusUpload = new Upload(stream, tusOptions);
163
+ tusUpload = new Upload(stream, tusOptions);
109
164
  // Handle abort signal
110
165
  if (signal) {
111
166
  abortHandler = () => {
@@ -116,8 +171,27 @@ export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize,
116
171
  }
117
172
  tusUpload.start();
118
173
  });
119
- log(label, 'upload done');
174
+ if (uploadBehavior === 'await') {
175
+ await startPromise;
176
+ log(label, 'upload done');
177
+ return;
178
+ }
179
+ startPromise.catch((err) => {
180
+ logWarn('Background upload failed', err);
181
+ });
182
+ await uploadUrlPromise;
183
+ log(label, 'upload started');
120
184
  }
121
185
  await pMap(streamLabels, uploadSingleStream, { concurrency: uploadConcurrency, signal });
186
+ await Promise.all(uploadUrlPromises);
187
+ if (uploadBehavior === 'await') {
188
+ await Promise.all(completionPromises);
189
+ }
190
+ else {
191
+ Promise.allSettled(completionPromises).catch((err) => {
192
+ logWarn('Background upload failed', err);
193
+ });
194
+ }
195
+ return { uploadUrls: uploadUrlsResult };
122
196
  }
123
197
  //# sourceMappingURL=tus.js.map
package/dist/tus.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tus.js","sourceRoot":"","sources":["../src/tus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEpC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,IAAI,MAAM,OAAO,CAAA;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAItC,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC,CAAA;AAiBhC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,EACnC,UAAU,EACV,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,UAAU,GACY;IACtB,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAE5C,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,mBAAmB,GAAG,CAAC,CAAA;IAE3B,MAAM,KAAK,GAA2B,EAAE,CAAA;IAExC,MAAM,wBAAwB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAA;IAEvF,uBAAuB;IACvB,MAAM,IAAI,CACR,YAAY,EACZ,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,yCAAyC;QACzC,IAAI,MAAM,EAAE,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAA;QAEtD,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QACpC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,oCAAoC,KAAK,EAAE,CAAC,CAAA;QAC9D,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAA;QAE3B,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAA;YACjC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;YACnB,UAAU,IAAI,IAAI,CAAA;QACpB,CAAC;IACH,CAAC,EACD,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,CAC3B,CAAA;IAED,MAAM,gBAAgB,GAA2B,EAAE,CAAA;IAEnD,KAAK,UAAU,kBAAkB,CAAC,KAAa;QAC7C,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAE3B,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QACpC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,oCAAoC,KAAK,EAAE,CAAC,CAAA;QAC9D,CAAC;QACD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAA;QACnC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;QAEzB,IAAI,SAAS,GAAG,kBAAkB,CAAA;QAClC,IAAI,oBAA6B,CAAA;QACjC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAA;QAClC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACzB,0EAA0E;YAC1E,oFAAoF;YACpF,oBAAoB,GAAG,IAAI,CAAA;YAC3B,IAAI,SAAS,KAAK,MAAM,CAAC,iBAAiB;gBAAE,SAAS,GAAG,IAAI,CAAA;QAC9D,CAAC;QAED,MAAM,aAAa,GAAG,CAAC,aAAqB,EAAQ,EAAE;YACpD,gBAAgB,CAAC,KAAK,CAAC,GAAG,aAAa,CAAA;YAEvC,uCAAuC;YACvC,IAAI,aAAa,GAAG,CAAC,CAAA;YACrB,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;gBAC7B,aAAa,IAAI,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YAC3C,CAAC;YAED,gCAAgC;YAChC,IAAI,mBAAmB,GAAG,aAAa,EAAE,CAAC;gBACxC,mBAAmB,GAAG,aAAa,CAAA;gBACnC,oEAAoE;gBACpE,yEAAyE;gBACzE,UAAU,CAAC;oBACT,aAAa;oBACb,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;iBAC9D,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAA;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;QAE9C,MAAM,IAAI,OAAO,CAAmB,CAAC,cAAc,EAAE,aAAa,EAAE,EAAE;YACpE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;gBAC/B,aAAa,CAAC,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC,CAAA;gBAClF,OAAM;YACR,CAAC;YAED,2CAA2C;YAC3C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;gBACpB,aAAa,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAA;gBAC1C,OAAM;YACR,CAAC;YAED,iDAAiD;YACjD,IAAI,YAAsC,CAAA;YAC1C,MAAM,OAAO,GAAG,CAAC,OAAyB,EAAE,EAAE;gBAC5C,IAAI,YAAY;oBAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;gBACpE,cAAc,CAAC,OAAO,CAAC,CAAA;YACzB,CAAC,CAAA;YACD,MAAM,MAAM,GAAG,CAAC,GAAY,EAAE,EAAE;gBAC9B,IAAI,YAAY;oBAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;gBACpE,aAAa,CAAC,GAAG,CAAC,CAAA;YACpB,CAAC,CAAA;YAED,MAAM,UAAU,GAAkB;gBAChC,QAAQ,EAAE,QAAQ,CAAC,OAAO;gBAC1B,SAAS,EAAE,UAAU,EAAE,CAAC,KAAK,CAAC;gBAC9B,QAAQ,EAAE;oBACR,YAAY,EAAE,QAAQ,CAAC,gBAAgB;oBACvC,SAAS,EAAE,KAAK;oBAChB,QAAQ;iBACT;gBACD,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,aAAa;gBACzB,SAAS,EAAE,OAAO;aACnB,CAAA;YACD,4CAA4C;YAC5C,IAAI,IAAI,IAAI,IAAI;gBAAE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAA;YAC9C,IAAI,SAAS;gBAAE,UAAU,CAAC,SAAS,GAAG,SAAS,CAAA;YAC/C,IAAI,oBAAoB;gBAAE,UAAU,CAAC,oBAAoB,GAAG,oBAAoB,CAAA;YAEhF,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;YAEhD,sBAAsB;YACtB,IAAI,MAAM,EAAE,CAAC;gBACX,YAAY,GAAG,GAAG,EAAE;oBAClB,SAAS,CAAC,KAAK,EAAE,CAAA;oBACjB,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAA;gBACrC,CAAC,CAAA;gBACD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;YAChE,CAAC;YAED,SAAS,CAAC,KAAK,EAAE,CAAA;QACnB,CAAC,CAAC,CAAA;QAEF,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,CAAA;IAC3B,CAAC;IAED,MAAM,IAAI,CAAC,YAAY,EAAE,kBAAkB,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC,CAAA;AAC1F,CAAC"}
1
+ {"version":3,"file":"tus.js","sourceRoot":"","sources":["../src/tus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEpC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,IAAI,MAAM,OAAO,CAAA;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAItC,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC,CAAA;AAChC,MAAM,OAAO,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAA;AAoBzC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,EACnC,UAAU,EACV,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,UAAU,EACV,cAAc,GAAG,OAAO,GACF;IACtB,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAE5C,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,mBAAmB,GAAG,CAAC,CAAA;IAE3B,MAAM,KAAK,GAA2B,EAAE,CAAA;IACxC,MAAM,gBAAgB,GAA2B,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,CAAA;IAE1E,MAAM,wBAAwB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAA;IAEvF,uBAAuB;IACvB,MAAM,IAAI,CACR,YAAY,EACZ,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,yCAAyC;QACzC,IAAI,MAAM,EAAE,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAA;QAEtD,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QACpC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,oCAAoC,KAAK,EAAE,CAAC,CAAA;QAC9D,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAA;QAE3B,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAA;YACjC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;YACnB,UAAU,IAAI,IAAI,CAAA;QACpB,CAAC;IACH,CAAC,EACD,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,CAC3B,CAAA;IAED,MAAM,gBAAgB,GAA2B,EAAE,CAAA;IAEnD,MAAM,kBAAkB,GAAyB,EAAE,CAAA;IACnD,MAAM,iBAAiB,GAAyB,EAAE,CAAA;IAElD,KAAK,UAAU,kBAAkB,CAAC,KAAa;QAC7C,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAE3B,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QACpC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,oCAAoC,KAAK,EAAE,CAAC,CAAA;QAC9D,CAAC;QACD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAA;QACnC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;QAEzB,IAAI,SAAS,GAAG,kBAAkB,CAAA;QAClC,IAAI,oBAA6B,CAAA;QACjC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAA;QAClC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACzB,0EAA0E;YAC1E,oFAAoF;YACpF,oBAAoB,GAAG,IAAI,CAAA;YAC3B,IAAI,SAAS,KAAK,MAAM,CAAC,iBAAiB;gBAAE,SAAS,GAAG,IAAI,CAAA;QAC9D,CAAC;QAED,MAAM,aAAa,GAAG,CAAC,aAAqB,EAAQ,EAAE;YACpD,gBAAgB,CAAC,KAAK,CAAC,GAAG,aAAa,CAAA;YAEvC,uCAAuC;YACvC,IAAI,aAAa,GAAG,CAAC,CAAA;YACrB,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;gBAC7B,aAAa,IAAI,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YAC3C,CAAC;YAED,gCAAgC;YAChC,IAAI,mBAAmB,GAAG,aAAa,EAAE,CAAC;gBACxC,mBAAmB,GAAG,aAAa,CAAA;gBACnC,oEAAoE;gBACpE,yEAAyE;gBACzE,UAAU,CAAC;oBACT,aAAa;oBACb,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;iBAC9D,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAA;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;QAE9C,IAAI,cAAc,KAAK,MAAM,IAAI,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,gBAAgB,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;YAC3C,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;YACzC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;YAC1C,OAAM;QACR,CAAC;QAED,IAAI,WAAW,GAAG,KAAK,CAAA;QACvB,IAAI,UAAU,GAAe,GAAG,EAAE,GAAE,CAAC,CAAA;QACrC,IAAI,SAAS,GAAyB,GAAG,EAAE,GAAE,CAAC,CAAA;QAC9C,MAAM,gBAAgB,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7D,UAAU,GAAG,GAAG,EAAE;gBAChB,IAAI,WAAW;oBAAE,OAAM;gBACvB,WAAW,GAAG,IAAI,CAAA;gBAClB,OAAO,EAAE,CAAA;YACX,CAAC,CAAA;YACD,SAAS,GAAG,CAAC,GAAG,EAAE,EAAE;gBAClB,IAAI,WAAW;oBAAE,OAAM;gBACvB,WAAW,GAAG,IAAI,CAAA;gBAClB,MAAM,CAAC,GAAG,CAAC,CAAA;YACb,CAAC,CAAA;QACH,CAAC,CAAC,CAAA;QAEF,IAAI,iBAAiB,GAAe,GAAG,EAAE,GAAE,CAAC,CAAA;QAC5C,IAAI,gBAAgB,GAAyB,GAAG,EAAE,GAAE,CAAC,CAAA;QACrD,MAAM,iBAAiB,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC9D,iBAAiB,GAAG,OAAO,CAAA;YAC3B,gBAAgB,GAAG,MAAM,CAAA;QAC3B,CAAC,CAAC,CAAA;QAEF,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;QACxC,kBAAkB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAE1C,IAAI,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,gBAAgB,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;YAC3C,UAAU,EAAE,CAAA;QACd,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,OAAO,CAAO,CAAC,cAAc,EAAE,aAAa,EAAE,EAAE;YACvE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;gBAC/B,aAAa,CAAC,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC,CAAA;gBAClF,OAAM;YACR,CAAC;YAED,2CAA2C;YAC3C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;gBACpB,aAAa,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAA;gBAC1C,OAAM;YACR,CAAC;YAED,iDAAiD;YACjD,IAAI,YAAsC,CAAA;YAC1C,MAAM,OAAO,GAAG,CAAC,QAA0B,EAAE,EAAE;gBAC7C,IAAI,YAAY;oBAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;gBACpE,iBAAiB,EAAE,CAAA;gBACnB,UAAU,EAAE,CAAA;gBACZ,cAAc,EAAE,CAAA;YAClB,CAAC,CAAA;YACD,MAAM,MAAM,GAAG,CAAC,GAAY,EAAE,EAAE;gBAC9B,IAAI,YAAY;oBAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;gBACpE,gBAAgB,CAAC,GAAY,CAAC,CAAA;gBAC9B,SAAS,CAAC,GAAY,CAAC,CAAA;gBACvB,aAAa,CAAC,GAAG,CAAC,CAAA;YACpB,CAAC,CAAA;YAED,IAAI,SAAiB,CAAA;YACrB,MAAM,UAAU,GAAkB;gBAChC,QAAQ,EAAE,QAAQ,CAAC,OAAO;gBAC1B,SAAS,EAAE,UAAU,EAAE,CAAC,KAAK,CAAC;gBAC9B,QAAQ,EAAE;oBACR,YAAY,EAAE,QAAQ,CAAC,gBAAgB;oBACvC,SAAS,EAAE,KAAK;oBAChB,QAAQ;iBACT;gBACD,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,aAAa;gBACzB,SAAS,EAAE,OAAO;gBAClB,oBAAoB,EAAE,GAAG,EAAE;oBACzB,MAAM,GAAG,GAAG,SAAS,EAAE,GAAG,CAAA;oBAC1B,IAAI,GAAG,EAAE,CAAC;wBACR,gBAAgB,CAAC,KAAK,CAAC,GAAG,GAAG,CAAA;oBAC/B,CAAC;oBACD,UAAU,EAAE,CAAA;oBACZ,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;wBAC9B,SAAS,CAAC,KAAK,EAAE,CAAA;wBACjB,iBAAiB,EAAE,CAAA;oBACrB,CAAC;gBACH,CAAC;aACF,CAAA;YACD,4CAA4C;YAC5C,IAAI,IAAI,IAAI,IAAI;gBAAE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAA;YAC9C,IAAI,SAAS;gBAAE,UAAU,CAAC,SAAS,GAAG,SAAS,CAAA;YAC/C,IAAI,oBAAoB;gBAAE,UAAU,CAAC,oBAAoB,GAAG,oBAAoB,CAAA;YAEhF,SAAS,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;YAE1C,sBAAsB;YACtB,IAAI,MAAM,EAAE,CAAC;gBACX,YAAY,GAAG,GAAG,EAAE;oBAClB,SAAS,CAAC,KAAK,EAAE,CAAA;oBACjB,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAA;gBACrC,CAAC,CAAA;gBACD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;YAChE,CAAC;YAED,SAAS,CAAC,KAAK,EAAE,CAAA;QACnB,CAAC,CAAC,CAAA;QAEF,IAAI,cAAc,KAAK,OAAO,EAAE,CAAC;YAC/B,MAAM,YAAY,CAAA;YAClB,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,CAAA;YACzB,OAAM;QACR,CAAC;QAED,YAAY,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACzB,OAAO,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAA;QAC1C,CAAC,CAAC,CAAA;QAEF,MAAM,gBAAgB,CAAA;QACtB,GAAG,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAA;IAC9B,CAAC;IAED,MAAM,IAAI,CAAC,YAAY,EAAE,kBAAkB,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC,CAAA;IAExF,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;IAEpC,IAAI,cAAc,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;IACvC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACnD,OAAO,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAA;QAC1C,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAA;AACzC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transloadit/node",
3
- "version": "4.3.0",
3
+ "version": "4.3.1",
4
4
  "description": "Node.js SDK for Transloadit",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -52,7 +52,7 @@ import type {
52
52
  import { lintAssemblyInstructions as lintAssemblyInstructionsInternal } from './lintAssemblyInstructions.ts'
53
53
  import PaginationStream from './PaginationStream.ts'
54
54
  import PollingTimeoutError from './PollingTimeoutError.ts'
55
- import type { Stream } from './tus.ts'
55
+ import type { Stream, UploadBehavior } from './tus.ts'
56
56
  import { sendTusRequest } from './tus.ts'
57
57
 
58
58
  // See https://github.com/sindresorhus/got/tree/v11.8.6?tab=readme-ov-file#errors
@@ -66,11 +66,30 @@ export {
66
66
  TimeoutError,
67
67
  UploadError,
68
68
  } from 'got'
69
-
69
+ export { goldenTemplates } from './alphalib/goldenTemplates.ts'
70
70
  export type { AssemblyStatus } from './alphalib/types/assemblyStatus.ts'
71
71
  export * from './apiTypes.ts'
72
72
  export { InconsistentResponseError, ApiError }
73
+ export { mergeTemplateContent } from './alphalib/templateMerge.ts'
74
+ export type {
75
+ Base64Strategy,
76
+ InputFile,
77
+ PrepareInputFilesOptions,
78
+ PrepareInputFilesResult,
79
+ UploadInput,
80
+ UrlStrategy,
81
+ } from './inputFiles.ts'
82
+ export { prepareInputFiles } from './inputFiles.ts'
73
83
  export type { LintAssemblyInstructionsResult, LintFatalLevel } from './lintAssemblyInstructions.ts'
84
+ export type {
85
+ RobotHelp,
86
+ RobotHelpOptions,
87
+ RobotListItem,
88
+ RobotListOptions,
89
+ RobotListResult,
90
+ RobotParamHelp,
91
+ } from './robots.ts'
92
+ export { getRobotHelp, listRobots } from './robots.ts'
74
93
 
75
94
  const log = debug('transloadit')
76
95
  const logWarn = debug('transloadit:warn')
@@ -80,6 +99,12 @@ export interface UploadProgress {
80
99
  totalBytes?: number | undefined
81
100
  }
82
101
 
102
+ export type { UploadBehavior }
103
+
104
+ export type AssemblyStatusWithUploadUrls = AssemblyStatus & {
105
+ upload_urls?: Record<string, string>
106
+ }
107
+
83
108
  const { version } = packageJson
84
109
 
85
110
  export type AssemblyProgress = (assembly: AssemblyStatus) => void
@@ -157,6 +182,7 @@ interface AssemblyUploadOptions {
157
182
  uploads?: {
158
183
  [name: string]: Readable | IntoStreamInput
159
184
  }
185
+ uploadBehavior?: UploadBehavior
160
186
  waitForCompletion?: boolean
161
187
  chunkSize?: number
162
188
  uploadConcurrency?: number
@@ -237,7 +263,7 @@ export interface SmartCDNUrlOptions {
237
263
  export type Fields = Record<string, string | number>
238
264
 
239
265
  // A special promise that lets the user immediately get the assembly ID (synchronously before the request is sent)
240
- interface CreateAssemblyPromise extends Promise<AssemblyStatus> {
266
+ interface CreateAssemblyPromise extends Promise<AssemblyStatusWithUploadUrls> {
241
267
  assemblyId: string
242
268
  }
243
269
 
@@ -273,9 +299,19 @@ function checkResult<T>(result: T | { error: string }): asserts result is T {
273
299
  }
274
300
  }
275
301
 
276
- export interface Options {
302
+ type AuthKeySecret = {
277
303
  authKey: string
278
304
  authSecret: string
305
+ authToken?: undefined
306
+ }
307
+
308
+ type AuthToken = {
309
+ authToken: string
310
+ authKey?: string
311
+ authSecret?: string
312
+ }
313
+
314
+ type BaseOptions = {
279
315
  endpoint?: string
280
316
  maxRetries?: number
281
317
  timeout?: number
@@ -283,11 +319,15 @@ export interface Options {
283
319
  validateResponses?: boolean
284
320
  }
285
321
 
322
+ export type Options = BaseOptions & (AuthKeySecret | AuthToken)
323
+
286
324
  export class Transloadit {
287
325
  private _authKey: string
288
326
 
289
327
  private _authSecret: string
290
328
 
329
+ private _authToken: string | null
330
+
291
331
  private _endpoint: string
292
332
 
293
333
  private _maxRetries: number
@@ -301,20 +341,26 @@ export class Transloadit {
301
341
  private _validateResponses = false
302
342
 
303
343
  constructor(opts: Options) {
304
- if (opts?.authKey == null) {
305
- throw new Error('Please provide an authKey')
306
- }
307
-
308
- if (opts.authSecret == null) {
309
- throw new Error('Please provide an authSecret')
310
- }
344
+ const rawToken = typeof opts?.authToken === 'string' ? opts.authToken.trim() : ''
345
+ const hasToken = rawToken.length > 0
311
346
 
312
347
  if (opts.endpoint?.endsWith('/')) {
313
348
  throw new Error('Trailing slash in endpoint is not allowed')
314
349
  }
315
350
 
316
- this._authKey = opts.authKey
317
- this._authSecret = opts.authSecret
351
+ if (!hasToken) {
352
+ if (opts?.authKey == null) {
353
+ throw new Error('Please provide an authKey')
354
+ }
355
+
356
+ if (opts.authSecret == null) {
357
+ throw new Error('Please provide an authSecret')
358
+ }
359
+ }
360
+
361
+ this._authKey = opts.authKey ?? ''
362
+ this._authSecret = opts.authSecret ?? ''
363
+ this._authToken = hasToken ? rawToken : null
318
364
  this._endpoint = opts.endpoint || 'https://api2.transloadit.com'
319
365
  this._maxRetries = opts.maxRetries != null ? opts.maxRetries : 5
320
366
  this._defaultTimeout = opts.timeout != null ? opts.timeout : 60000
@@ -351,6 +397,7 @@ export class Transloadit {
351
397
  uploads = {},
352
398
  assemblyId,
353
399
  signal,
400
+ uploadBehavior = 'await',
354
401
  } = opts
355
402
 
356
403
  // Keep track of how long the request took
@@ -406,7 +453,7 @@ export class Transloadit {
406
453
  const streamErrorPromise = createStreamErrorPromise(allStreamsMap)
407
454
 
408
455
  const createAssemblyAndUpload = async () => {
409
- const result: AssemblyStatus = await this._remoteJson({
456
+ const result: AssemblyStatusWithUploadUrls = await this._remoteJson({
410
457
  urlSuffix,
411
458
  method: 'post',
412
459
  timeout: { request: timeout },
@@ -419,17 +466,22 @@ export class Transloadit {
419
466
  checkResult(result)
420
467
 
421
468
  if (Object.keys(allStreamsMap).length > 0) {
422
- await sendTusRequest({
469
+ const { uploadUrls } = await sendTusRequest({
423
470
  streamsMap: allStreamsMap,
424
471
  assembly: result,
425
472
  onProgress: onUploadProgress,
426
473
  requestedChunkSize,
427
474
  uploadConcurrency,
428
475
  signal,
476
+ uploadBehavior,
429
477
  })
478
+ if (uploadBehavior !== 'await' && Object.keys(uploadUrls).length > 0) {
479
+ result.upload_urls = uploadUrls
480
+ }
430
481
  }
431
482
 
432
- if (!waitForCompletion) return result
483
+ const shouldWaitForCompletion = waitForCompletion && uploadBehavior === 'await'
484
+ if (!shouldWaitForCompletion) return result
433
485
 
434
486
  if (result.assembly_id == null) {
435
487
  throw new InconsistentResponseError(
@@ -478,7 +530,9 @@ export class Transloadit {
478
530
  })
479
531
  }
480
532
 
481
- async resumeAssemblyUploads(opts: ResumeAssemblyUploadsOptions): Promise<AssemblyStatus> {
533
+ async resumeAssemblyUploads(
534
+ opts: ResumeAssemblyUploadsOptions,
535
+ ): Promise<AssemblyStatusWithUploadUrls> {
482
536
  const {
483
537
  assemblyUrl,
484
538
  files = {},
@@ -490,12 +544,16 @@ export class Transloadit {
490
544
  onUploadProgress = () => {},
491
545
  onAssemblyProgress = () => {},
492
546
  signal,
547
+ uploadBehavior = 'await',
493
548
  } = opts
494
549
 
495
550
  const startTimeMs = getHrTimeMs()
496
551
 
497
552
  getAssemblyIdFromUrl(assemblyUrl)
498
- const assembly = await this._fetchAssemblyStatus({ url: assemblyUrl, signal })
553
+ const assembly: AssemblyStatusWithUploadUrls = await this._fetchAssemblyStatus({
554
+ url: assemblyUrl,
555
+ signal,
556
+ })
499
557
  const statusUrl = assembly.assembly_ssl_url ?? assembly.assembly_url ?? assemblyUrl
500
558
 
501
559
  const finishedKeys = new Set<string>()
@@ -571,13 +629,25 @@ export class Transloadit {
571
629
  onProgress: onUploadProgress,
572
630
  signal,
573
631
  uploadUrls: uploadUrlsByLabel,
632
+ uploadBehavior,
574
633
  })
575
634
 
576
635
  await Promise.race([uploadPromise, streamErrorPromise])
636
+ const { uploadUrls } = await uploadPromise
637
+ if (uploadBehavior !== 'await' && Object.keys(uploadUrls).length > 0) {
638
+ assembly.upload_urls = uploadUrls
639
+ }
577
640
  }
578
641
 
579
- const latestAssembly = await this._fetchAssemblyStatus({ url: statusUrl, signal })
580
- if (!waitForCompletion) return latestAssembly
642
+ const latestAssembly: AssemblyStatusWithUploadUrls = await this._fetchAssemblyStatus({
643
+ url: statusUrl,
644
+ signal,
645
+ })
646
+ if (uploadBehavior !== 'await' && assembly.upload_urls) {
647
+ latestAssembly.upload_urls = assembly.upload_urls
648
+ }
649
+ const shouldWaitForCompletion = waitForCompletion && uploadBehavior === 'await'
650
+ if (!shouldWaitForCompletion) return latestAssembly
581
651
 
582
652
  if (latestAssembly.assembly_id == null) {
583
653
  throw new InconsistentResponseError(
@@ -701,6 +771,7 @@ export class Transloadit {
701
771
  const { assembly_ssl_url: url } = await this.getAssembly(assemblyId)
702
772
  const rawResult = await this._remoteJson<Record<string, unknown>, OptionalAuthParams>({
703
773
  url,
774
+ isTrustedUrl: true,
704
775
  method: 'delete',
705
776
  })
706
777
 
@@ -829,6 +900,7 @@ export class Transloadit {
829
900
  const rawResult = await this._remoteJson<Record<string, unknown>, OptionalAuthParams>({
830
901
  url,
831
902
  urlSuffix: url ? undefined : `/assemblies/${assemblyId}`,
903
+ isTrustedUrl: Boolean(url),
832
904
  signal,
833
905
  })
834
906
 
@@ -1021,6 +1093,9 @@ export class Transloadit {
1021
1093
  params: OptionalAuthParams,
1022
1094
  algorithm?: string,
1023
1095
  ): { signature: string; params: string } {
1096
+ if (!this._authKey || !this._authSecret) {
1097
+ throw new Error('Cannot sign params without authKey and authSecret.')
1098
+ }
1024
1099
  const jsonParams = this._prepareParams(params)
1025
1100
  const signature = this._calcSignature(jsonParams, algorithm)
1026
1101
 
@@ -1031,6 +1106,9 @@ export class Transloadit {
1031
1106
  * Construct a signed Smart CDN URL. See https://transloadit.com/docs/topics/signature-authentication/#smart-cdn.
1032
1107
  */
1033
1108
  getSignedSmartCDNUrl(opts: SmartCDNUrlOptions): string {
1109
+ if (!this._authKey || !this._authSecret) {
1110
+ throw new Error('authKey and authSecret are required to sign Smart CDN URLs.')
1111
+ }
1034
1112
  return getSignedSmartCdnUrl({
1035
1113
  ...opts,
1036
1114
  authKey: this._authKey,
@@ -1039,15 +1117,24 @@ export class Transloadit {
1039
1117
  }
1040
1118
 
1041
1119
  private _calcSignature(toSign: string, algorithm = 'sha384'): string {
1120
+ if (!this._authSecret) {
1121
+ throw new Error('Cannot sign params without authSecret.')
1122
+ }
1042
1123
  return signParamsSync(toSign, this._authSecret, algorithm)
1043
1124
  }
1044
1125
 
1045
1126
  // Sets the multipart/form-data for POST, PUT and DELETE requests, including
1046
1127
  // the streams, the signed params, and any additional fields.
1047
1128
  private _appendForm(form: FormData, params: OptionalAuthParams, fields?: Fields): void {
1048
- const sigData = this.calcSignature(params)
1049
- const jsonParams = sigData.params
1050
- const { signature } = sigData
1129
+ const shouldSign = Boolean(this._authKey && this._authSecret)
1130
+ let jsonParams = JSON.stringify(params ?? {})
1131
+ let signature: string | undefined
1132
+
1133
+ if (shouldSign) {
1134
+ const sigData = this.calcSignature(params)
1135
+ jsonParams = sigData.params
1136
+ signature = sigData.signature
1137
+ }
1051
1138
 
1052
1139
  form.append('params', jsonParams)
1053
1140
 
@@ -1057,16 +1144,24 @@ export class Transloadit {
1057
1144
  }
1058
1145
  }
1059
1146
 
1060
- form.append('signature', signature)
1147
+ if (signature) {
1148
+ form.append('signature', signature)
1149
+ }
1061
1150
  }
1062
1151
 
1063
1152
  // Implements HTTP GET query params, handling the case where the url already
1064
1153
  // has params.
1065
1154
  private _appendParamsToUrl(url: string, params: OptionalAuthParams): string {
1066
- const { signature, params: jsonParams } = this.calcSignature(params)
1067
-
1068
1155
  const prefix = url.indexOf('?') === -1 ? '?' : '&'
1069
1156
 
1157
+ const shouldSign = Boolean(this._authKey && this._authSecret)
1158
+ if (!shouldSign) {
1159
+ const jsonParams = JSON.stringify(params ?? {})
1160
+ return `${url}${prefix}params=${encodeURIComponent(jsonParams)}`
1161
+ }
1162
+
1163
+ const { signature, params: jsonParams } = this.calcSignature(params)
1164
+
1070
1165
  return `${url}${prefix}signature=${signature}&params=${encodeURIComponent(jsonParams)}`
1071
1166
  }
1072
1167
 
@@ -1102,6 +1197,7 @@ export class Transloadit {
1102
1197
  private async _remoteJson<TRet, TParams extends OptionalAuthParams>(opts: {
1103
1198
  urlSuffix?: string
1104
1199
  url?: string
1200
+ isTrustedUrl?: boolean
1105
1201
  timeout?: Delays
1106
1202
  method?: 'delete' | 'get' | 'post' | 'put'
1107
1203
  params?: TParams
@@ -1112,6 +1208,7 @@ export class Transloadit {
1112
1208
  const {
1113
1209
  urlSuffix,
1114
1210
  url: urlInput,
1211
+ isTrustedUrl = false,
1115
1212
  timeout = { request: this._defaultTimeout },
1116
1213
  method = 'get',
1117
1214
  params = {},
@@ -1123,6 +1220,13 @@ export class Transloadit {
1123
1220
  // Allow providing either a `urlSuffix` or a full `url`
1124
1221
  if (!urlSuffix && !urlInput) throw new Error('No URL provided')
1125
1222
  let url = urlInput || `${this._endpoint}${urlSuffix}`
1223
+ if (urlInput && !isTrustedUrl) {
1224
+ const allowed = new URL(this._endpoint)
1225
+ const candidate = new URL(urlInput)
1226
+ if (allowed.origin !== candidate.origin) {
1227
+ throw new Error(`Untrusted URL: ${candidate.origin}`)
1228
+ }
1229
+ }
1126
1230
 
1127
1231
  if (method === 'get') {
1128
1232
  url = this._appendParamsToUrl(url, params)
@@ -1147,6 +1251,7 @@ export class Transloadit {
1147
1251
  headers: {
1148
1252
  'Transloadit-Client': `node-sdk:${version}`,
1149
1253
  'User-Agent': undefined, // Remove got's user-agent
1254
+ ...(this._authToken ? { Authorization: `Bearer ${this._authToken}` } : {}),
1150
1255
  ...headers,
1151
1256
  },
1152
1257
  responseType: 'json',
@@ -0,0 +1,53 @@
1
+ export type GoldenTemplate = {
2
+ slug: string
3
+ version: string
4
+ description: string
5
+ steps: Record<string, unknown>
6
+ }
7
+
8
+ export const goldenTemplates = {
9
+ '~transloadit/encode-hls-video@0.0.1': {
10
+ slug: '~transloadit/encode-hls-video@0.0.1',
11
+ version: '0.0.1',
12
+ description:
13
+ 'Encode an input video into HLS renditions (270p, 360p, 540p) with an adaptive playlist.',
14
+ steps: {
15
+ ':original': {
16
+ robot: '/upload/handle',
17
+ },
18
+ low: {
19
+ robot: '/video/encode',
20
+ use: ':original',
21
+ ffmpeg_stack: 'v7.0.0',
22
+ preset: 'hls-270p',
23
+ result: true,
24
+ turbo: true,
25
+ },
26
+ mid: {
27
+ robot: '/video/encode',
28
+ use: ':original',
29
+ ffmpeg_stack: 'v7.0.0',
30
+ preset: 'hls-360p',
31
+ result: true,
32
+ turbo: true,
33
+ },
34
+ high: {
35
+ robot: '/video/encode',
36
+ use: ':original',
37
+ ffmpeg_stack: 'v7.0.0',
38
+ preset: 'hls-540p',
39
+ result: true,
40
+ turbo: true,
41
+ },
42
+ adaptive: {
43
+ robot: '/video/adaptive',
44
+ use: {
45
+ steps: ['low', 'mid', 'high'],
46
+ bundle_steps: true,
47
+ },
48
+ technique: 'hls',
49
+ playlist_name: 'my_playlist.m3u8',
50
+ },
51
+ },
52
+ },
53
+ } satisfies Record<string, GoldenTemplate>