transloadit 4.3.0 → 4.6.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.
- package/README.md +58 -1
- package/dist/Transloadit.d.ts +32 -4
- package/dist/Transloadit.d.ts.map +1 -1
- package/dist/Transloadit.js +88 -23
- package/dist/Transloadit.js.map +1 -1
- package/dist/alphalib/mcache.d.ts.map +1 -1
- package/dist/alphalib/mcache.js +4 -2
- package/dist/alphalib/mcache.js.map +1 -1
- package/dist/alphalib/types/assemblyReplay.d.ts +2 -0
- package/dist/alphalib/types/assemblyReplay.d.ts.map +1 -1
- package/dist/alphalib/types/assemblyReplayNotification.d.ts +2 -0
- package/dist/alphalib/types/assemblyReplayNotification.d.ts.map +1 -1
- package/dist/alphalib/types/assemblyStatus.d.ts +20 -20
- package/dist/alphalib/types/assemblyStatus.d.ts.map +1 -1
- package/dist/alphalib/types/assemblyStatus.js +13 -1
- package/dist/alphalib/types/assemblyStatus.js.map +1 -1
- package/dist/alphalib/types/robots/_index.d.ts +20 -0
- package/dist/alphalib/types/robots/_index.d.ts.map +1 -1
- package/dist/alphalib/types/robots/ai-chat.d.ts +20 -0
- package/dist/alphalib/types/robots/ai-chat.d.ts.map +1 -1
- package/dist/alphalib/types/robots/ai-chat.js +5 -3
- package/dist/alphalib/types/robots/ai-chat.js.map +1 -1
- package/dist/alphalib/types/template.d.ts +36 -0
- package/dist/alphalib/types/template.d.ts.map +1 -1
- package/dist/apiTypes.d.ts +7 -4
- package/dist/apiTypes.d.ts.map +1 -1
- package/dist/cli/commands/assemblies.d.ts.map +1 -1
- package/dist/cli/commands/assemblies.js +109 -25
- package/dist/cli/commands/assemblies.js.map +1 -1
- package/dist/cli/commands/docs.d.ts +15 -0
- package/dist/cli/commands/docs.d.ts.map +1 -0
- package/dist/cli/commands/docs.js +58 -0
- package/dist/cli/commands/docs.js.map +1 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +7 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/upload.d.ts +20 -0
- package/dist/cli/commands/upload.d.ts.map +1 -0
- package/dist/cli/commands/upload.js +95 -0
- package/dist/cli/commands/upload.js.map +1 -0
- package/dist/cli/template-last-modified.d.ts.map +1 -1
- package/dist/cli/template-last-modified.js +2 -1
- package/dist/cli/template-last-modified.js.map +1 -1
- package/dist/inputFiles.d.ts +41 -0
- package/dist/inputFiles.d.ts.map +1 -0
- package/dist/inputFiles.js +214 -0
- package/dist/inputFiles.js.map +1 -0
- package/dist/robots.d.ts +39 -0
- package/dist/robots.d.ts.map +1 -0
- package/dist/robots.js +236 -0
- package/dist/robots.js.map +1 -0
- package/dist/tus.d.ts +5 -1
- package/dist/tus.d.ts.map +1 -1
- package/dist/tus.js +80 -6
- package/dist/tus.js.map +1 -1
- package/package.json +3 -5
- package/src/Transloadit.ts +146 -28
- package/src/alphalib/mcache.ts +5 -3
- package/src/alphalib/types/assemblyStatus.ts +13 -1
- package/src/alphalib/types/robots/ai-chat.ts +11 -3
- package/src/apiTypes.ts +8 -4
- package/src/cli/commands/assemblies.ts +131 -25
- package/src/cli/commands/docs.ts +68 -0
- package/src/cli/commands/index.ts +9 -2
- package/src/cli/commands/upload.ts +129 -0
- package/src/cli/template-last-modified.ts +2 -1
- package/src/inputFiles.ts +278 -0
- package/src/robots.ts +325 -0
- package/src/tus.ts +91 -5
package/src/Transloadit.ts
CHANGED
|
@@ -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,31 @@ export {
|
|
|
66
66
|
TimeoutError,
|
|
67
67
|
UploadError,
|
|
68
68
|
} from 'got'
|
|
69
|
-
|
|
70
69
|
export type { AssemblyStatus } from './alphalib/types/assemblyStatus.ts'
|
|
71
70
|
export * from './apiTypes.ts'
|
|
72
71
|
export { InconsistentResponseError, ApiError }
|
|
72
|
+
export { extractFieldNamesFromTemplate } from './alphalib/stepParsing.ts'
|
|
73
|
+
// Builtin templates replace the legacy golden template helpers.
|
|
74
|
+
export { mergeTemplateContent } from './alphalib/templateMerge.ts'
|
|
75
|
+
export type {
|
|
76
|
+
Base64Strategy,
|
|
77
|
+
InputFile,
|
|
78
|
+
PrepareInputFilesOptions,
|
|
79
|
+
PrepareInputFilesResult,
|
|
80
|
+
UploadInput,
|
|
81
|
+
UrlStrategy,
|
|
82
|
+
} from './inputFiles.ts'
|
|
83
|
+
export { prepareInputFiles } from './inputFiles.ts'
|
|
73
84
|
export type { LintAssemblyInstructionsResult, LintFatalLevel } from './lintAssemblyInstructions.ts'
|
|
85
|
+
export type {
|
|
86
|
+
RobotHelp,
|
|
87
|
+
RobotHelpOptions,
|
|
88
|
+
RobotListItem,
|
|
89
|
+
RobotListOptions,
|
|
90
|
+
RobotListResult,
|
|
91
|
+
RobotParamHelp,
|
|
92
|
+
} from './robots.ts'
|
|
93
|
+
export { getRobotHelp, isKnownRobot, listRobots } from './robots.ts'
|
|
74
94
|
|
|
75
95
|
const log = debug('transloadit')
|
|
76
96
|
const logWarn = debug('transloadit:warn')
|
|
@@ -80,6 +100,12 @@ export interface UploadProgress {
|
|
|
80
100
|
totalBytes?: number | undefined
|
|
81
101
|
}
|
|
82
102
|
|
|
103
|
+
export type { UploadBehavior }
|
|
104
|
+
|
|
105
|
+
export type AssemblyStatusWithUploadUrls = AssemblyStatus & {
|
|
106
|
+
upload_urls?: Record<string, string>
|
|
107
|
+
}
|
|
108
|
+
|
|
83
109
|
const { version } = packageJson
|
|
84
110
|
|
|
85
111
|
export type AssemblyProgress = (assembly: AssemblyStatus) => void
|
|
@@ -157,6 +183,7 @@ interface AssemblyUploadOptions {
|
|
|
157
183
|
uploads?: {
|
|
158
184
|
[name: string]: Readable | IntoStreamInput
|
|
159
185
|
}
|
|
186
|
+
uploadBehavior?: UploadBehavior
|
|
160
187
|
waitForCompletion?: boolean
|
|
161
188
|
chunkSize?: number
|
|
162
189
|
uploadConcurrency?: number
|
|
@@ -173,6 +200,10 @@ interface AssemblyUploadOptions {
|
|
|
173
200
|
export interface CreateAssemblyOptions extends AssemblyUploadOptions {
|
|
174
201
|
params?: CreateAssemblyParams
|
|
175
202
|
assemblyId?: string
|
|
203
|
+
/**
|
|
204
|
+
* Expected number of tus uploads when files will be uploaded separately.
|
|
205
|
+
*/
|
|
206
|
+
expectedUploads?: number
|
|
176
207
|
}
|
|
177
208
|
|
|
178
209
|
export interface ResumeAssemblyUploadsOptions extends AssemblyUploadOptions {
|
|
@@ -237,7 +268,7 @@ export interface SmartCDNUrlOptions {
|
|
|
237
268
|
export type Fields = Record<string, string | number>
|
|
238
269
|
|
|
239
270
|
// A special promise that lets the user immediately get the assembly ID (synchronously before the request is sent)
|
|
240
|
-
interface CreateAssemblyPromise extends Promise<
|
|
271
|
+
interface CreateAssemblyPromise extends Promise<AssemblyStatusWithUploadUrls> {
|
|
241
272
|
assemblyId: string
|
|
242
273
|
}
|
|
243
274
|
|
|
@@ -273,21 +304,36 @@ function checkResult<T>(result: T | { error: string }): asserts result is T {
|
|
|
273
304
|
}
|
|
274
305
|
}
|
|
275
306
|
|
|
276
|
-
|
|
307
|
+
type AuthKeySecret = {
|
|
277
308
|
authKey: string
|
|
278
309
|
authSecret: string
|
|
310
|
+
authToken?: undefined
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
type AuthToken = {
|
|
314
|
+
authToken: string
|
|
315
|
+
authKey?: string
|
|
316
|
+
authSecret?: string
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
type BaseOptions = {
|
|
279
320
|
endpoint?: string
|
|
280
321
|
maxRetries?: number
|
|
281
322
|
timeout?: number
|
|
282
323
|
gotRetry?: Partial<RetryOptions>
|
|
283
324
|
validateResponses?: boolean
|
|
325
|
+
clientName?: string
|
|
284
326
|
}
|
|
285
327
|
|
|
328
|
+
export type Options = BaseOptions & (AuthKeySecret | AuthToken)
|
|
329
|
+
|
|
286
330
|
export class Transloadit {
|
|
287
331
|
private _authKey: string
|
|
288
332
|
|
|
289
333
|
private _authSecret: string
|
|
290
334
|
|
|
335
|
+
private _authToken: string | null
|
|
336
|
+
|
|
291
337
|
private _endpoint: string
|
|
292
338
|
|
|
293
339
|
private _maxRetries: number
|
|
@@ -296,28 +342,37 @@ export class Transloadit {
|
|
|
296
342
|
|
|
297
343
|
private _gotRetry: Partial<RetryOptions>
|
|
298
344
|
|
|
345
|
+
private _clientName: string
|
|
346
|
+
|
|
299
347
|
private _lastUsedAssemblyUrl = ''
|
|
300
348
|
|
|
301
349
|
private _validateResponses = false
|
|
302
350
|
|
|
303
351
|
constructor(opts: Options) {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (opts.authSecret == null) {
|
|
309
|
-
throw new Error('Please provide an authSecret')
|
|
310
|
-
}
|
|
352
|
+
const rawToken = typeof opts?.authToken === 'string' ? opts.authToken.trim() : ''
|
|
353
|
+
const hasToken = rawToken.length > 0
|
|
311
354
|
|
|
312
355
|
if (opts.endpoint?.endsWith('/')) {
|
|
313
356
|
throw new Error('Trailing slash in endpoint is not allowed')
|
|
314
357
|
}
|
|
315
358
|
|
|
316
|
-
|
|
317
|
-
|
|
359
|
+
if (!hasToken) {
|
|
360
|
+
if (opts?.authKey == null) {
|
|
361
|
+
throw new Error('Please provide an authKey')
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (opts.authSecret == null) {
|
|
365
|
+
throw new Error('Please provide an authSecret')
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
this._authKey = opts.authKey ?? ''
|
|
370
|
+
this._authSecret = opts.authSecret ?? ''
|
|
371
|
+
this._authToken = hasToken ? rawToken : null
|
|
318
372
|
this._endpoint = opts.endpoint || 'https://api2.transloadit.com'
|
|
319
373
|
this._maxRetries = opts.maxRetries != null ? opts.maxRetries : 5
|
|
320
374
|
this._defaultTimeout = opts.timeout != null ? opts.timeout : 60000
|
|
375
|
+
this._clientName = opts.clientName?.trim() || `node-sdk:${version}`
|
|
321
376
|
|
|
322
377
|
// Passed on to got https://github.com/sindresorhus/got/blob/main/documentation/7-retry.md
|
|
323
378
|
this._gotRetry = opts.gotRetry != null ? opts.gotRetry : { limit: 0 }
|
|
@@ -350,7 +405,9 @@ export class Transloadit {
|
|
|
350
405
|
files = {},
|
|
351
406
|
uploads = {},
|
|
352
407
|
assemblyId,
|
|
408
|
+
expectedUploads,
|
|
353
409
|
signal,
|
|
410
|
+
uploadBehavior = 'await',
|
|
354
411
|
} = opts
|
|
355
412
|
|
|
356
413
|
// Keep track of how long the request took
|
|
@@ -406,30 +463,38 @@ export class Transloadit {
|
|
|
406
463
|
const streamErrorPromise = createStreamErrorPromise(allStreamsMap)
|
|
407
464
|
|
|
408
465
|
const createAssemblyAndUpload = async () => {
|
|
409
|
-
const
|
|
466
|
+
const totalExpectedUploads =
|
|
467
|
+
expectedUploads == null ? allStreams.length : Math.max(expectedUploads, allStreams.length)
|
|
468
|
+
|
|
469
|
+
const result: AssemblyStatusWithUploadUrls = await this._remoteJson({
|
|
410
470
|
urlSuffix,
|
|
411
471
|
method: 'post',
|
|
412
472
|
timeout: { request: timeout },
|
|
413
473
|
params,
|
|
414
474
|
fields: {
|
|
415
|
-
tus_num_expected_upload_files:
|
|
475
|
+
tus_num_expected_upload_files: totalExpectedUploads,
|
|
416
476
|
},
|
|
417
477
|
signal,
|
|
418
478
|
})
|
|
419
479
|
checkResult(result)
|
|
420
480
|
|
|
421
481
|
if (Object.keys(allStreamsMap).length > 0) {
|
|
422
|
-
await sendTusRequest({
|
|
482
|
+
const { uploadUrls } = await sendTusRequest({
|
|
423
483
|
streamsMap: allStreamsMap,
|
|
424
484
|
assembly: result,
|
|
425
485
|
onProgress: onUploadProgress,
|
|
426
486
|
requestedChunkSize,
|
|
427
487
|
uploadConcurrency,
|
|
428
488
|
signal,
|
|
489
|
+
uploadBehavior,
|
|
429
490
|
})
|
|
491
|
+
if (uploadBehavior !== 'await' && Object.keys(uploadUrls).length > 0) {
|
|
492
|
+
result.upload_urls = uploadUrls
|
|
493
|
+
}
|
|
430
494
|
}
|
|
431
495
|
|
|
432
|
-
|
|
496
|
+
const shouldWaitForCompletion = waitForCompletion && uploadBehavior === 'await'
|
|
497
|
+
if (!shouldWaitForCompletion) return result
|
|
433
498
|
|
|
434
499
|
if (result.assembly_id == null) {
|
|
435
500
|
throw new InconsistentResponseError(
|
|
@@ -478,7 +543,9 @@ export class Transloadit {
|
|
|
478
543
|
})
|
|
479
544
|
}
|
|
480
545
|
|
|
481
|
-
async resumeAssemblyUploads(
|
|
546
|
+
async resumeAssemblyUploads(
|
|
547
|
+
opts: ResumeAssemblyUploadsOptions,
|
|
548
|
+
): Promise<AssemblyStatusWithUploadUrls> {
|
|
482
549
|
const {
|
|
483
550
|
assemblyUrl,
|
|
484
551
|
files = {},
|
|
@@ -490,12 +557,16 @@ export class Transloadit {
|
|
|
490
557
|
onUploadProgress = () => {},
|
|
491
558
|
onAssemblyProgress = () => {},
|
|
492
559
|
signal,
|
|
560
|
+
uploadBehavior = 'await',
|
|
493
561
|
} = opts
|
|
494
562
|
|
|
495
563
|
const startTimeMs = getHrTimeMs()
|
|
496
564
|
|
|
497
565
|
getAssemblyIdFromUrl(assemblyUrl)
|
|
498
|
-
const assembly = await this._fetchAssemblyStatus({
|
|
566
|
+
const assembly: AssemblyStatusWithUploadUrls = await this._fetchAssemblyStatus({
|
|
567
|
+
url: assemblyUrl,
|
|
568
|
+
signal,
|
|
569
|
+
})
|
|
499
570
|
const statusUrl = assembly.assembly_ssl_url ?? assembly.assembly_url ?? assemblyUrl
|
|
500
571
|
|
|
501
572
|
const finishedKeys = new Set<string>()
|
|
@@ -571,13 +642,25 @@ export class Transloadit {
|
|
|
571
642
|
onProgress: onUploadProgress,
|
|
572
643
|
signal,
|
|
573
644
|
uploadUrls: uploadUrlsByLabel,
|
|
645
|
+
uploadBehavior,
|
|
574
646
|
})
|
|
575
647
|
|
|
576
648
|
await Promise.race([uploadPromise, streamErrorPromise])
|
|
649
|
+
const { uploadUrls } = await uploadPromise
|
|
650
|
+
if (uploadBehavior !== 'await' && Object.keys(uploadUrls).length > 0) {
|
|
651
|
+
assembly.upload_urls = uploadUrls
|
|
652
|
+
}
|
|
577
653
|
}
|
|
578
654
|
|
|
579
|
-
const latestAssembly = await this._fetchAssemblyStatus({
|
|
580
|
-
|
|
655
|
+
const latestAssembly: AssemblyStatusWithUploadUrls = await this._fetchAssemblyStatus({
|
|
656
|
+
url: statusUrl,
|
|
657
|
+
signal,
|
|
658
|
+
})
|
|
659
|
+
if (uploadBehavior !== 'await' && assembly.upload_urls) {
|
|
660
|
+
latestAssembly.upload_urls = assembly.upload_urls
|
|
661
|
+
}
|
|
662
|
+
const shouldWaitForCompletion = waitForCompletion && uploadBehavior === 'await'
|
|
663
|
+
if (!shouldWaitForCompletion) return latestAssembly
|
|
581
664
|
|
|
582
665
|
if (latestAssembly.assembly_id == null) {
|
|
583
666
|
throw new InconsistentResponseError(
|
|
@@ -701,6 +784,7 @@ export class Transloadit {
|
|
|
701
784
|
const { assembly_ssl_url: url } = await this.getAssembly(assemblyId)
|
|
702
785
|
const rawResult = await this._remoteJson<Record<string, unknown>, OptionalAuthParams>({
|
|
703
786
|
url,
|
|
787
|
+
isTrustedUrl: true,
|
|
704
788
|
method: 'delete',
|
|
705
789
|
})
|
|
706
790
|
|
|
@@ -829,6 +913,7 @@ export class Transloadit {
|
|
|
829
913
|
const rawResult = await this._remoteJson<Record<string, unknown>, OptionalAuthParams>({
|
|
830
914
|
url,
|
|
831
915
|
urlSuffix: url ? undefined : `/assemblies/${assemblyId}`,
|
|
916
|
+
isTrustedUrl: Boolean(url),
|
|
832
917
|
signal,
|
|
833
918
|
})
|
|
834
919
|
|
|
@@ -1021,6 +1106,9 @@ export class Transloadit {
|
|
|
1021
1106
|
params: OptionalAuthParams,
|
|
1022
1107
|
algorithm?: string,
|
|
1023
1108
|
): { signature: string; params: string } {
|
|
1109
|
+
if (!this._authKey || !this._authSecret) {
|
|
1110
|
+
throw new Error('Cannot sign params without authKey and authSecret.')
|
|
1111
|
+
}
|
|
1024
1112
|
const jsonParams = this._prepareParams(params)
|
|
1025
1113
|
const signature = this._calcSignature(jsonParams, algorithm)
|
|
1026
1114
|
|
|
@@ -1031,6 +1119,9 @@ export class Transloadit {
|
|
|
1031
1119
|
* Construct a signed Smart CDN URL. See https://transloadit.com/docs/topics/signature-authentication/#smart-cdn.
|
|
1032
1120
|
*/
|
|
1033
1121
|
getSignedSmartCDNUrl(opts: SmartCDNUrlOptions): string {
|
|
1122
|
+
if (!this._authKey || !this._authSecret) {
|
|
1123
|
+
throw new Error('authKey and authSecret are required to sign Smart CDN URLs.')
|
|
1124
|
+
}
|
|
1034
1125
|
return getSignedSmartCdnUrl({
|
|
1035
1126
|
...opts,
|
|
1036
1127
|
authKey: this._authKey,
|
|
@@ -1039,15 +1130,24 @@ export class Transloadit {
|
|
|
1039
1130
|
}
|
|
1040
1131
|
|
|
1041
1132
|
private _calcSignature(toSign: string, algorithm = 'sha384'): string {
|
|
1133
|
+
if (!this._authSecret) {
|
|
1134
|
+
throw new Error('Cannot sign params without authSecret.')
|
|
1135
|
+
}
|
|
1042
1136
|
return signParamsSync(toSign, this._authSecret, algorithm)
|
|
1043
1137
|
}
|
|
1044
1138
|
|
|
1045
1139
|
// Sets the multipart/form-data for POST, PUT and DELETE requests, including
|
|
1046
1140
|
// the streams, the signed params, and any additional fields.
|
|
1047
1141
|
private _appendForm(form: FormData, params: OptionalAuthParams, fields?: Fields): void {
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1050
|
-
|
|
1142
|
+
const shouldSign = Boolean(this._authKey && this._authSecret)
|
|
1143
|
+
let jsonParams = JSON.stringify(params ?? {})
|
|
1144
|
+
let signature: string | undefined
|
|
1145
|
+
|
|
1146
|
+
if (shouldSign) {
|
|
1147
|
+
const sigData = this.calcSignature(params)
|
|
1148
|
+
jsonParams = sigData.params
|
|
1149
|
+
signature = sigData.signature
|
|
1150
|
+
}
|
|
1051
1151
|
|
|
1052
1152
|
form.append('params', jsonParams)
|
|
1053
1153
|
|
|
@@ -1057,16 +1157,24 @@ export class Transloadit {
|
|
|
1057
1157
|
}
|
|
1058
1158
|
}
|
|
1059
1159
|
|
|
1060
|
-
|
|
1160
|
+
if (signature) {
|
|
1161
|
+
form.append('signature', signature)
|
|
1162
|
+
}
|
|
1061
1163
|
}
|
|
1062
1164
|
|
|
1063
1165
|
// Implements HTTP GET query params, handling the case where the url already
|
|
1064
1166
|
// has params.
|
|
1065
1167
|
private _appendParamsToUrl(url: string, params: OptionalAuthParams): string {
|
|
1066
|
-
const { signature, params: jsonParams } = this.calcSignature(params)
|
|
1067
|
-
|
|
1068
1168
|
const prefix = url.indexOf('?') === -1 ? '?' : '&'
|
|
1069
1169
|
|
|
1170
|
+
const shouldSign = Boolean(this._authKey && this._authSecret)
|
|
1171
|
+
if (!shouldSign) {
|
|
1172
|
+
const jsonParams = JSON.stringify(params ?? {})
|
|
1173
|
+
return `${url}${prefix}params=${encodeURIComponent(jsonParams)}`
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
const { signature, params: jsonParams } = this.calcSignature(params)
|
|
1177
|
+
|
|
1070
1178
|
return `${url}${prefix}signature=${signature}¶ms=${encodeURIComponent(jsonParams)}`
|
|
1071
1179
|
}
|
|
1072
1180
|
|
|
@@ -1102,6 +1210,7 @@ export class Transloadit {
|
|
|
1102
1210
|
private async _remoteJson<TRet, TParams extends OptionalAuthParams>(opts: {
|
|
1103
1211
|
urlSuffix?: string
|
|
1104
1212
|
url?: string
|
|
1213
|
+
isTrustedUrl?: boolean
|
|
1105
1214
|
timeout?: Delays
|
|
1106
1215
|
method?: 'delete' | 'get' | 'post' | 'put'
|
|
1107
1216
|
params?: TParams
|
|
@@ -1112,6 +1221,7 @@ export class Transloadit {
|
|
|
1112
1221
|
const {
|
|
1113
1222
|
urlSuffix,
|
|
1114
1223
|
url: urlInput,
|
|
1224
|
+
isTrustedUrl = false,
|
|
1115
1225
|
timeout = { request: this._defaultTimeout },
|
|
1116
1226
|
method = 'get',
|
|
1117
1227
|
params = {},
|
|
@@ -1123,6 +1233,13 @@ export class Transloadit {
|
|
|
1123
1233
|
// Allow providing either a `urlSuffix` or a full `url`
|
|
1124
1234
|
if (!urlSuffix && !urlInput) throw new Error('No URL provided')
|
|
1125
1235
|
let url = urlInput || `${this._endpoint}${urlSuffix}`
|
|
1236
|
+
if (urlInput && !isTrustedUrl) {
|
|
1237
|
+
const allowed = new URL(this._endpoint)
|
|
1238
|
+
const candidate = new URL(urlInput)
|
|
1239
|
+
if (allowed.origin !== candidate.origin) {
|
|
1240
|
+
throw new Error(`Untrusted URL: ${candidate.origin}`)
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1126
1243
|
|
|
1127
1244
|
if (method === 'get') {
|
|
1128
1245
|
url = this._appendParamsToUrl(url, params)
|
|
@@ -1145,8 +1262,9 @@ export class Transloadit {
|
|
|
1145
1262
|
body: form,
|
|
1146
1263
|
timeout,
|
|
1147
1264
|
headers: {
|
|
1148
|
-
'Transloadit-Client':
|
|
1265
|
+
'Transloadit-Client': this._clientName,
|
|
1149
1266
|
'User-Agent': undefined, // Remove got's user-agent
|
|
1267
|
+
...(this._authToken ? { Authorization: `Bearer ${this._authToken}` } : {}),
|
|
1150
1268
|
...headers,
|
|
1151
1269
|
},
|
|
1152
1270
|
responseType: 'json',
|
package/src/alphalib/mcache.ts
CHANGED
|
@@ -98,9 +98,11 @@ export class Mcache<T> {
|
|
|
98
98
|
})
|
|
99
99
|
|
|
100
100
|
this.#pending.set(key, promise)
|
|
101
|
-
void promise
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
void promise
|
|
102
|
+
.finally(() => {
|
|
103
|
+
this.#pending.delete(key)
|
|
104
|
+
})
|
|
105
|
+
.catch(() => undefined)
|
|
104
106
|
return promise
|
|
105
107
|
}
|
|
106
108
|
|
|
@@ -10,7 +10,6 @@ export const assemblyStatusOkCodeSchema = z.enum([
|
|
|
10
10
|
'ASSEMBLY_CANCELED',
|
|
11
11
|
'ASSEMBLY_COMPLETED',
|
|
12
12
|
'ASSEMBLY_EXECUTING',
|
|
13
|
-
'ASSEMBLY_EXPIRED',
|
|
14
13
|
'ASSEMBLY_REPLAYING',
|
|
15
14
|
'ASSEMBLY_UPLOADING',
|
|
16
15
|
'REQUEST_ABORTED',
|
|
@@ -27,6 +26,7 @@ export const assemblyStatusErrCodeSchema = z.enum([
|
|
|
27
26
|
'ASSEMBLY_CRASHED',
|
|
28
27
|
'ASSEMBLY_DISALLOWED_ROBOTS_USED',
|
|
29
28
|
'ASSEMBLY_EMPTY_STEPS',
|
|
29
|
+
'ASSEMBLY_EXECUTION_PROGRESS_NOT_ENABLED',
|
|
30
30
|
'ASSEMBLY_EXPIRED',
|
|
31
31
|
'ASSEMBLY_FILE_NOT_RESERVED',
|
|
32
32
|
'ASSEMBLY_INFINITE',
|
|
@@ -43,9 +43,17 @@ export const assemblyStatusErrCodeSchema = z.enum([
|
|
|
43
43
|
'ASSEMBLY_NOT_FINISHED',
|
|
44
44
|
'ASSEMBLY_NOT_FOUND',
|
|
45
45
|
'ASSEMBLY_NOT_REPLAYED',
|
|
46
|
+
'ASSEMBLY_NOTIFICATION_LIST_ERROR',
|
|
46
47
|
'ASSEMBLY_NOTIFICATION_NOT_PERSISTED',
|
|
48
|
+
'ASSEMBLY_NOTIFICATION_NOT_REPLAYED',
|
|
49
|
+
'ASSEMBLY_NOTIFICATIONS_LIST_ERROR',
|
|
50
|
+
'ASSEMBLY_NO_NOTIFY_URL',
|
|
47
51
|
'ASSEMBLY_ROBOT_MISSING',
|
|
48
52
|
'ASSEMBLY_SATURATED',
|
|
53
|
+
'ASSEMBLY_STATS_ERROR',
|
|
54
|
+
'ASSEMBLY_STATS_INVALID_TIME',
|
|
55
|
+
'ASSEMBLY_STATS_MISSING_REGION',
|
|
56
|
+
'ASSEMBLY_STATUS_FETCHING_RATE_LIMIT_REACHED',
|
|
49
57
|
'ASSEMBLY_STATUS_NOT_FOUND',
|
|
50
58
|
'ASSEMBLY_STATUS_PARSE_ERROR',
|
|
51
59
|
'ASSEMBLY_STEP_INVALID_ROBOT',
|
|
@@ -61,6 +69,9 @@ export const assemblyStatusErrCodeSchema = z.enum([
|
|
|
61
69
|
'AUTH_KEYS_NOT_FOUND',
|
|
62
70
|
'AUTH_SECRET_NOT_RETRIEVED',
|
|
63
71
|
'AZURE_STORE_ACCESS_DENIED',
|
|
72
|
+
'BEARER_TOKEN_AUTH_KEY_MISMATCH',
|
|
73
|
+
'BEARER_TOKEN_EXPIRED',
|
|
74
|
+
'BEARER_TOKEN_INVALID',
|
|
64
75
|
'BACKBLAZE_IMPORT_ACCESS_DENIED',
|
|
65
76
|
'BACKBLAZE_IMPORT_NOT_FOUND',
|
|
66
77
|
'BACKBLAZE_STORE_ACCESS_DENIED',
|
|
@@ -88,6 +99,7 @@ export const assemblyStatusErrCodeSchema = z.enum([
|
|
|
88
99
|
'FILE_META_DATA_ERROR',
|
|
89
100
|
'FILE_PREVIEW_VALIDATION',
|
|
90
101
|
'FILE_READ_VALIDATION_ERROR',
|
|
102
|
+
'FILE_SERVE_NO_RESULT',
|
|
91
103
|
'FILE_VERIFY_INVALID_FILE',
|
|
92
104
|
'FILE_VIRUSSCAN_DECLINED_FILE',
|
|
93
105
|
'GET_ACCOUNT_DB_ERROR',
|
|
@@ -150,6 +150,7 @@ export const MODEL_CAPABILITIES: Record<string, { pdf: boolean; image: boolean }
|
|
|
150
150
|
'anthropic/claude-4-opus-20250514': { pdf: true, image: true },
|
|
151
151
|
'anthropic/claude-sonnet-4-5': { pdf: true, image: true },
|
|
152
152
|
'anthropic/claude-opus-4-5': { pdf: true, image: true },
|
|
153
|
+
'anthropic/claude-opus-4-6': { pdf: true, image: true },
|
|
153
154
|
'openai/gpt-4.1-2025-04-14': { pdf: false, image: true },
|
|
154
155
|
'openai/chatgpt-4o-latest': { pdf: false, image: true },
|
|
155
156
|
'openai/o3-2025-04-16': { pdf: false, image: true },
|
|
@@ -197,21 +198,28 @@ export const robotAiChatInstructionsSchema = robotBase
|
|
|
197
198
|
credentials: z
|
|
198
199
|
.union([z.string(), z.array(z.string())])
|
|
199
200
|
.optional()
|
|
200
|
-
.describe(
|
|
201
|
+
.describe(
|
|
202
|
+
'Names of template credentials to make available to the robot. When using your own AI provider keys, Transloadit charges a 10% markup (minimum $0.0005 per request).',
|
|
203
|
+
),
|
|
201
204
|
test_credentials: z
|
|
202
205
|
.boolean()
|
|
203
206
|
.optional()
|
|
204
|
-
.describe(
|
|
207
|
+
.describe(
|
|
208
|
+
'Use Transloadit-provided credentials for testing. Usage is billed at provider cost plus a 10% markup (minimum $0.0005 per request).',
|
|
209
|
+
),
|
|
205
210
|
mcp_servers: z
|
|
206
211
|
.array(
|
|
207
212
|
z.object({
|
|
208
213
|
type: z.enum(['sse', 'http']),
|
|
209
214
|
url: z.string(),
|
|
210
215
|
headers: z.record(z.string()).optional(),
|
|
216
|
+
auth: z.enum(['transloadit']).optional(),
|
|
211
217
|
}),
|
|
212
218
|
)
|
|
213
219
|
.optional()
|
|
214
|
-
.describe(
|
|
220
|
+
.describe(
|
|
221
|
+
'The MCP servers to use. This is used to call tools from the LLM. Use `headers` to pass `Authorization: Bearer <token>` when needed. You can use any MCP server reachable from your environment. For Transloadit\'s own MCP server, you can set `auth: "transloadit"` to let API2 auto-auth and inject an Authorization header for you (only for Transloadit-hosted MCP servers).',
|
|
222
|
+
),
|
|
215
223
|
})
|
|
216
224
|
.strict()
|
|
217
225
|
|
package/src/apiTypes.ts
CHANGED
|
@@ -98,6 +98,7 @@ export type ListTemplatesParams = OptionalAuthParams & {
|
|
|
98
98
|
fromdate?: string
|
|
99
99
|
todate?: string
|
|
100
100
|
keywords?: string[]
|
|
101
|
+
include_builtin?: 'all' | 'latest' | 'exclusively-all' | 'exclusively-latest'
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
interface TemplateResponseBase {
|
|
@@ -108,10 +109,13 @@ interface TemplateResponseBase {
|
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
export interface ListedTemplate extends TemplateResponseBase {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
// API responses may omit or null these fields for builtin or legacy templates.
|
|
113
|
+
encryption_version?: number | null
|
|
114
|
+
last_used?: string | null
|
|
115
|
+
created?: string | null
|
|
116
|
+
modified?: string | null
|
|
117
|
+
description?: string
|
|
118
|
+
builtin_version?: string
|
|
115
119
|
}
|
|
116
120
|
|
|
117
121
|
export interface TemplateResponse extends TemplateResponseBase, BaseResponse {}
|