@transloadit/node 4.2.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/README.md +116 -4
- package/dist/Transloadit.d.ts +45 -4
- package/dist/Transloadit.d.ts.map +1 -1
- package/dist/Transloadit.js +104 -21
- package/dist/Transloadit.js.map +1 -1
- package/dist/alphalib/assembly-linter.d.ts +123 -0
- package/dist/alphalib/assembly-linter.d.ts.map +1 -0
- package/dist/alphalib/assembly-linter.js +1142 -0
- package/dist/alphalib/assembly-linter.js.map +1 -0
- package/dist/alphalib/assembly-linter.lang.en.d.ts +87 -0
- package/dist/alphalib/assembly-linter.lang.en.d.ts.map +1 -0
- package/dist/alphalib/assembly-linter.lang.en.js +326 -0
- package/dist/alphalib/assembly-linter.lang.en.js.map +1 -0
- package/dist/alphalib/goldenTemplates.d.ts +52 -0
- package/dist/alphalib/goldenTemplates.d.ts.map +1 -0
- package/dist/alphalib/goldenTemplates.js +46 -0
- package/dist/alphalib/goldenTemplates.js.map +1 -0
- package/dist/alphalib/object.d.ts +20 -0
- package/dist/alphalib/object.d.ts.map +1 -0
- package/dist/alphalib/object.js +23 -0
- package/dist/alphalib/object.js.map +1 -0
- package/dist/alphalib/stepParsing.d.ts +93 -0
- package/dist/alphalib/stepParsing.d.ts.map +1 -0
- package/dist/alphalib/stepParsing.js +1154 -0
- package/dist/alphalib/stepParsing.js.map +1 -0
- package/dist/alphalib/templateMerge.d.ts +4 -0
- package/dist/alphalib/templateMerge.d.ts.map +1 -0
- package/dist/alphalib/templateMerge.js +22 -0
- package/dist/alphalib/templateMerge.js.map +1 -0
- package/dist/cli/commands/assemblies.d.ts +20 -1
- package/dist/cli/commands/assemblies.d.ts.map +1 -1
- package/dist/cli/commands/assemblies.js +137 -2
- package/dist/cli/commands/assemblies.js.map +1 -1
- package/dist/cli/commands/auth.d.ts.map +1 -1
- package/dist/cli/commands/auth.js +19 -19
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +2 -1
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/docs/assemblyLintingExamples.d.ts +2 -0
- package/dist/cli/docs/assemblyLintingExamples.d.ts.map +1 -0
- package/dist/cli/docs/assemblyLintingExamples.js +10 -0
- package/dist/cli/docs/assemblyLintingExamples.js.map +1 -0
- package/dist/cli/helpers.d.ts +11 -0
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/helpers.js +29 -0
- package/dist/cli/helpers.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/lintAssemblyInput.d.ts +10 -0
- package/dist/lintAssemblyInput.d.ts.map +1 -0
- package/dist/lintAssemblyInput.js +73 -0
- package/dist/lintAssemblyInput.js.map +1 -0
- package/dist/lintAssemblyInstructions.d.ts +29 -0
- package/dist/lintAssemblyInstructions.d.ts.map +1 -0
- package/dist/lintAssemblyInstructions.js +33 -0
- package/dist/lintAssemblyInstructions.js.map +1 -0
- package/dist/robots.d.ts +38 -0
- package/dist/robots.d.ts.map +1 -0
- package/dist/robots.js +230 -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 +5 -2
- package/src/Transloadit.ts +170 -26
- package/src/alphalib/assembly-linter.lang.en.ts +393 -0
- package/src/alphalib/assembly-linter.ts +1475 -0
- package/src/alphalib/goldenTemplates.ts +53 -0
- package/src/alphalib/object.ts +27 -0
- package/src/alphalib/stepParsing.ts +1465 -0
- package/src/alphalib/templateMerge.ts +32 -0
- package/src/alphalib/typings/json-to-ast.d.ts +34 -0
- package/src/cli/commands/assemblies.ts +161 -2
- package/src/cli/commands/auth.ts +19 -22
- package/src/cli/commands/index.ts +2 -0
- package/src/cli/docs/assemblyLintingExamples.ts +9 -0
- package/src/cli/helpers.ts +50 -0
- package/src/inputFiles.ts +278 -0
- package/src/lintAssemblyInput.ts +89 -0
- package/src/lintAssemblyInstructions.ts +72 -0
- package/src/robots.ts +317 -0
- package/src/tus.ts +91 -5
package/src/Transloadit.ts
CHANGED
|
@@ -45,9 +45,14 @@ import type {
|
|
|
45
45
|
TemplateResponse,
|
|
46
46
|
} from './apiTypes.ts'
|
|
47
47
|
import InconsistentResponseError from './InconsistentResponseError.ts'
|
|
48
|
+
import type {
|
|
49
|
+
LintAssemblyInstructionsInput,
|
|
50
|
+
LintAssemblyInstructionsResult,
|
|
51
|
+
} from './lintAssemblyInstructions.ts'
|
|
52
|
+
import { lintAssemblyInstructions as lintAssemblyInstructionsInternal } from './lintAssemblyInstructions.ts'
|
|
48
53
|
import PaginationStream from './PaginationStream.ts'
|
|
49
54
|
import PollingTimeoutError from './PollingTimeoutError.ts'
|
|
50
|
-
import type { Stream } from './tus.ts'
|
|
55
|
+
import type { Stream, UploadBehavior } from './tus.ts'
|
|
51
56
|
import { sendTusRequest } from './tus.ts'
|
|
52
57
|
|
|
53
58
|
// See https://github.com/sindresorhus/got/tree/v11.8.6?tab=readme-ov-file#errors
|
|
@@ -61,10 +66,30 @@ export {
|
|
|
61
66
|
TimeoutError,
|
|
62
67
|
UploadError,
|
|
63
68
|
} from 'got'
|
|
64
|
-
|
|
69
|
+
export { goldenTemplates } from './alphalib/goldenTemplates.ts'
|
|
65
70
|
export type { AssemblyStatus } from './alphalib/types/assemblyStatus.ts'
|
|
66
71
|
export * from './apiTypes.ts'
|
|
67
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'
|
|
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'
|
|
68
93
|
|
|
69
94
|
const log = debug('transloadit')
|
|
70
95
|
const logWarn = debug('transloadit:warn')
|
|
@@ -74,6 +99,12 @@ export interface UploadProgress {
|
|
|
74
99
|
totalBytes?: number | undefined
|
|
75
100
|
}
|
|
76
101
|
|
|
102
|
+
export type { UploadBehavior }
|
|
103
|
+
|
|
104
|
+
export type AssemblyStatusWithUploadUrls = AssemblyStatus & {
|
|
105
|
+
upload_urls?: Record<string, string>
|
|
106
|
+
}
|
|
107
|
+
|
|
77
108
|
const { version } = packageJson
|
|
78
109
|
|
|
79
110
|
export type AssemblyProgress = (assembly: AssemblyStatus) => void
|
|
@@ -151,6 +182,7 @@ interface AssemblyUploadOptions {
|
|
|
151
182
|
uploads?: {
|
|
152
183
|
[name: string]: Readable | IntoStreamInput
|
|
153
184
|
}
|
|
185
|
+
uploadBehavior?: UploadBehavior
|
|
154
186
|
waitForCompletion?: boolean
|
|
155
187
|
chunkSize?: number
|
|
156
188
|
uploadConcurrency?: number
|
|
@@ -196,6 +228,14 @@ export interface AwaitAssemblyCompletionOptions {
|
|
|
196
228
|
onPoll?: () => boolean | undefined
|
|
197
229
|
}
|
|
198
230
|
|
|
231
|
+
export interface LintAssemblyInstructionsOptions
|
|
232
|
+
extends Omit<LintAssemblyInstructionsInput, 'template'> {
|
|
233
|
+
/**
|
|
234
|
+
* Template ID to merge with the provided instructions before linting.
|
|
235
|
+
*/
|
|
236
|
+
templateId?: string
|
|
237
|
+
}
|
|
238
|
+
|
|
199
239
|
export interface SmartCDNUrlOptions {
|
|
200
240
|
/**
|
|
201
241
|
* Workspace slug
|
|
@@ -223,7 +263,7 @@ export interface SmartCDNUrlOptions {
|
|
|
223
263
|
export type Fields = Record<string, string | number>
|
|
224
264
|
|
|
225
265
|
// A special promise that lets the user immediately get the assembly ID (synchronously before the request is sent)
|
|
226
|
-
interface CreateAssemblyPromise extends Promise<
|
|
266
|
+
interface CreateAssemblyPromise extends Promise<AssemblyStatusWithUploadUrls> {
|
|
227
267
|
assemblyId: string
|
|
228
268
|
}
|
|
229
269
|
|
|
@@ -259,9 +299,19 @@ function checkResult<T>(result: T | { error: string }): asserts result is T {
|
|
|
259
299
|
}
|
|
260
300
|
}
|
|
261
301
|
|
|
262
|
-
|
|
302
|
+
type AuthKeySecret = {
|
|
263
303
|
authKey: string
|
|
264
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 = {
|
|
265
315
|
endpoint?: string
|
|
266
316
|
maxRetries?: number
|
|
267
317
|
timeout?: number
|
|
@@ -269,11 +319,15 @@ export interface Options {
|
|
|
269
319
|
validateResponses?: boolean
|
|
270
320
|
}
|
|
271
321
|
|
|
322
|
+
export type Options = BaseOptions & (AuthKeySecret | AuthToken)
|
|
323
|
+
|
|
272
324
|
export class Transloadit {
|
|
273
325
|
private _authKey: string
|
|
274
326
|
|
|
275
327
|
private _authSecret: string
|
|
276
328
|
|
|
329
|
+
private _authToken: string | null
|
|
330
|
+
|
|
277
331
|
private _endpoint: string
|
|
278
332
|
|
|
279
333
|
private _maxRetries: number
|
|
@@ -287,20 +341,26 @@ export class Transloadit {
|
|
|
287
341
|
private _validateResponses = false
|
|
288
342
|
|
|
289
343
|
constructor(opts: Options) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (opts.authSecret == null) {
|
|
295
|
-
throw new Error('Please provide an authSecret')
|
|
296
|
-
}
|
|
344
|
+
const rawToken = typeof opts?.authToken === 'string' ? opts.authToken.trim() : ''
|
|
345
|
+
const hasToken = rawToken.length > 0
|
|
297
346
|
|
|
298
347
|
if (opts.endpoint?.endsWith('/')) {
|
|
299
348
|
throw new Error('Trailing slash in endpoint is not allowed')
|
|
300
349
|
}
|
|
301
350
|
|
|
302
|
-
|
|
303
|
-
|
|
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
|
|
304
364
|
this._endpoint = opts.endpoint || 'https://api2.transloadit.com'
|
|
305
365
|
this._maxRetries = opts.maxRetries != null ? opts.maxRetries : 5
|
|
306
366
|
this._defaultTimeout = opts.timeout != null ? opts.timeout : 60000
|
|
@@ -337,6 +397,7 @@ export class Transloadit {
|
|
|
337
397
|
uploads = {},
|
|
338
398
|
assemblyId,
|
|
339
399
|
signal,
|
|
400
|
+
uploadBehavior = 'await',
|
|
340
401
|
} = opts
|
|
341
402
|
|
|
342
403
|
// Keep track of how long the request took
|
|
@@ -392,7 +453,7 @@ export class Transloadit {
|
|
|
392
453
|
const streamErrorPromise = createStreamErrorPromise(allStreamsMap)
|
|
393
454
|
|
|
394
455
|
const createAssemblyAndUpload = async () => {
|
|
395
|
-
const result:
|
|
456
|
+
const result: AssemblyStatusWithUploadUrls = await this._remoteJson({
|
|
396
457
|
urlSuffix,
|
|
397
458
|
method: 'post',
|
|
398
459
|
timeout: { request: timeout },
|
|
@@ -405,17 +466,22 @@ export class Transloadit {
|
|
|
405
466
|
checkResult(result)
|
|
406
467
|
|
|
407
468
|
if (Object.keys(allStreamsMap).length > 0) {
|
|
408
|
-
await sendTusRequest({
|
|
469
|
+
const { uploadUrls } = await sendTusRequest({
|
|
409
470
|
streamsMap: allStreamsMap,
|
|
410
471
|
assembly: result,
|
|
411
472
|
onProgress: onUploadProgress,
|
|
412
473
|
requestedChunkSize,
|
|
413
474
|
uploadConcurrency,
|
|
414
475
|
signal,
|
|
476
|
+
uploadBehavior,
|
|
415
477
|
})
|
|
478
|
+
if (uploadBehavior !== 'await' && Object.keys(uploadUrls).length > 0) {
|
|
479
|
+
result.upload_urls = uploadUrls
|
|
480
|
+
}
|
|
416
481
|
}
|
|
417
482
|
|
|
418
|
-
|
|
483
|
+
const shouldWaitForCompletion = waitForCompletion && uploadBehavior === 'await'
|
|
484
|
+
if (!shouldWaitForCompletion) return result
|
|
419
485
|
|
|
420
486
|
if (result.assembly_id == null) {
|
|
421
487
|
throw new InconsistentResponseError(
|
|
@@ -439,7 +505,34 @@ export class Transloadit {
|
|
|
439
505
|
return Object.assign(promise, { assemblyId: effectiveAssemblyId })
|
|
440
506
|
}
|
|
441
507
|
|
|
442
|
-
|
|
508
|
+
/**
|
|
509
|
+
* Lint Assembly Instructions locally.
|
|
510
|
+
*
|
|
511
|
+
* If a templateId is provided, the template content is merged with the instructions,
|
|
512
|
+
* just like the API. When a template sets `allow_steps_override=false`, providing
|
|
513
|
+
* `steps` will throw a TEMPLATE_DENIES_STEPS_OVERRIDE error.
|
|
514
|
+
*
|
|
515
|
+
* The `assemblyInstructions` input may be a JSON string, a full instructions object,
|
|
516
|
+
* or a steps-only object (missing the `steps` property).
|
|
517
|
+
*/
|
|
518
|
+
async lintAssemblyInstructions(
|
|
519
|
+
options: LintAssemblyInstructionsOptions,
|
|
520
|
+
): Promise<LintAssemblyInstructionsResult> {
|
|
521
|
+
const { templateId, ...rest } = options
|
|
522
|
+
if (!templateId) {
|
|
523
|
+
return await lintAssemblyInstructionsInternal(rest)
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
const template = await this.getTemplate(templateId)
|
|
527
|
+
return await lintAssemblyInstructionsInternal({
|
|
528
|
+
...rest,
|
|
529
|
+
template: template.content,
|
|
530
|
+
})
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
async resumeAssemblyUploads(
|
|
534
|
+
opts: ResumeAssemblyUploadsOptions,
|
|
535
|
+
): Promise<AssemblyStatusWithUploadUrls> {
|
|
443
536
|
const {
|
|
444
537
|
assemblyUrl,
|
|
445
538
|
files = {},
|
|
@@ -451,12 +544,16 @@ export class Transloadit {
|
|
|
451
544
|
onUploadProgress = () => {},
|
|
452
545
|
onAssemblyProgress = () => {},
|
|
453
546
|
signal,
|
|
547
|
+
uploadBehavior = 'await',
|
|
454
548
|
} = opts
|
|
455
549
|
|
|
456
550
|
const startTimeMs = getHrTimeMs()
|
|
457
551
|
|
|
458
552
|
getAssemblyIdFromUrl(assemblyUrl)
|
|
459
|
-
const assembly = await this._fetchAssemblyStatus({
|
|
553
|
+
const assembly: AssemblyStatusWithUploadUrls = await this._fetchAssemblyStatus({
|
|
554
|
+
url: assemblyUrl,
|
|
555
|
+
signal,
|
|
556
|
+
})
|
|
460
557
|
const statusUrl = assembly.assembly_ssl_url ?? assembly.assembly_url ?? assemblyUrl
|
|
461
558
|
|
|
462
559
|
const finishedKeys = new Set<string>()
|
|
@@ -532,13 +629,25 @@ export class Transloadit {
|
|
|
532
629
|
onProgress: onUploadProgress,
|
|
533
630
|
signal,
|
|
534
631
|
uploadUrls: uploadUrlsByLabel,
|
|
632
|
+
uploadBehavior,
|
|
535
633
|
})
|
|
536
634
|
|
|
537
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
|
+
}
|
|
538
640
|
}
|
|
539
641
|
|
|
540
|
-
const latestAssembly = await this._fetchAssemblyStatus({
|
|
541
|
-
|
|
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
|
|
542
651
|
|
|
543
652
|
if (latestAssembly.assembly_id == null) {
|
|
544
653
|
throw new InconsistentResponseError(
|
|
@@ -662,6 +771,7 @@ export class Transloadit {
|
|
|
662
771
|
const { assembly_ssl_url: url } = await this.getAssembly(assemblyId)
|
|
663
772
|
const rawResult = await this._remoteJson<Record<string, unknown>, OptionalAuthParams>({
|
|
664
773
|
url,
|
|
774
|
+
isTrustedUrl: true,
|
|
665
775
|
method: 'delete',
|
|
666
776
|
})
|
|
667
777
|
|
|
@@ -790,6 +900,7 @@ export class Transloadit {
|
|
|
790
900
|
const rawResult = await this._remoteJson<Record<string, unknown>, OptionalAuthParams>({
|
|
791
901
|
url,
|
|
792
902
|
urlSuffix: url ? undefined : `/assemblies/${assemblyId}`,
|
|
903
|
+
isTrustedUrl: Boolean(url),
|
|
793
904
|
signal,
|
|
794
905
|
})
|
|
795
906
|
|
|
@@ -982,6 +1093,9 @@ export class Transloadit {
|
|
|
982
1093
|
params: OptionalAuthParams,
|
|
983
1094
|
algorithm?: string,
|
|
984
1095
|
): { signature: string; params: string } {
|
|
1096
|
+
if (!this._authKey || !this._authSecret) {
|
|
1097
|
+
throw new Error('Cannot sign params without authKey and authSecret.')
|
|
1098
|
+
}
|
|
985
1099
|
const jsonParams = this._prepareParams(params)
|
|
986
1100
|
const signature = this._calcSignature(jsonParams, algorithm)
|
|
987
1101
|
|
|
@@ -992,6 +1106,9 @@ export class Transloadit {
|
|
|
992
1106
|
* Construct a signed Smart CDN URL. See https://transloadit.com/docs/topics/signature-authentication/#smart-cdn.
|
|
993
1107
|
*/
|
|
994
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
|
+
}
|
|
995
1112
|
return getSignedSmartCdnUrl({
|
|
996
1113
|
...opts,
|
|
997
1114
|
authKey: this._authKey,
|
|
@@ -1000,15 +1117,24 @@ export class Transloadit {
|
|
|
1000
1117
|
}
|
|
1001
1118
|
|
|
1002
1119
|
private _calcSignature(toSign: string, algorithm = 'sha384'): string {
|
|
1120
|
+
if (!this._authSecret) {
|
|
1121
|
+
throw new Error('Cannot sign params without authSecret.')
|
|
1122
|
+
}
|
|
1003
1123
|
return signParamsSync(toSign, this._authSecret, algorithm)
|
|
1004
1124
|
}
|
|
1005
1125
|
|
|
1006
1126
|
// Sets the multipart/form-data for POST, PUT and DELETE requests, including
|
|
1007
1127
|
// the streams, the signed params, and any additional fields.
|
|
1008
1128
|
private _appendForm(form: FormData, params: OptionalAuthParams, fields?: Fields): void {
|
|
1009
|
-
const
|
|
1010
|
-
|
|
1011
|
-
|
|
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
|
+
}
|
|
1012
1138
|
|
|
1013
1139
|
form.append('params', jsonParams)
|
|
1014
1140
|
|
|
@@ -1018,16 +1144,24 @@ export class Transloadit {
|
|
|
1018
1144
|
}
|
|
1019
1145
|
}
|
|
1020
1146
|
|
|
1021
|
-
|
|
1147
|
+
if (signature) {
|
|
1148
|
+
form.append('signature', signature)
|
|
1149
|
+
}
|
|
1022
1150
|
}
|
|
1023
1151
|
|
|
1024
1152
|
// Implements HTTP GET query params, handling the case where the url already
|
|
1025
1153
|
// has params.
|
|
1026
1154
|
private _appendParamsToUrl(url: string, params: OptionalAuthParams): string {
|
|
1027
|
-
const { signature, params: jsonParams } = this.calcSignature(params)
|
|
1028
|
-
|
|
1029
1155
|
const prefix = url.indexOf('?') === -1 ? '?' : '&'
|
|
1030
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
|
+
|
|
1031
1165
|
return `${url}${prefix}signature=${signature}¶ms=${encodeURIComponent(jsonParams)}`
|
|
1032
1166
|
}
|
|
1033
1167
|
|
|
@@ -1063,6 +1197,7 @@ export class Transloadit {
|
|
|
1063
1197
|
private async _remoteJson<TRet, TParams extends OptionalAuthParams>(opts: {
|
|
1064
1198
|
urlSuffix?: string
|
|
1065
1199
|
url?: string
|
|
1200
|
+
isTrustedUrl?: boolean
|
|
1066
1201
|
timeout?: Delays
|
|
1067
1202
|
method?: 'delete' | 'get' | 'post' | 'put'
|
|
1068
1203
|
params?: TParams
|
|
@@ -1073,6 +1208,7 @@ export class Transloadit {
|
|
|
1073
1208
|
const {
|
|
1074
1209
|
urlSuffix,
|
|
1075
1210
|
url: urlInput,
|
|
1211
|
+
isTrustedUrl = false,
|
|
1076
1212
|
timeout = { request: this._defaultTimeout },
|
|
1077
1213
|
method = 'get',
|
|
1078
1214
|
params = {},
|
|
@@ -1084,6 +1220,13 @@ export class Transloadit {
|
|
|
1084
1220
|
// Allow providing either a `urlSuffix` or a full `url`
|
|
1085
1221
|
if (!urlSuffix && !urlInput) throw new Error('No URL provided')
|
|
1086
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
|
+
}
|
|
1087
1230
|
|
|
1088
1231
|
if (method === 'get') {
|
|
1089
1232
|
url = this._appendParamsToUrl(url, params)
|
|
@@ -1108,6 +1251,7 @@ export class Transloadit {
|
|
|
1108
1251
|
headers: {
|
|
1109
1252
|
'Transloadit-Client': `node-sdk:${version}`,
|
|
1110
1253
|
'User-Agent': undefined, // Remove got's user-agent
|
|
1254
|
+
...(this._authToken ? { Authorization: `Bearer ${this._authToken}` } : {}),
|
|
1111
1255
|
...headers,
|
|
1112
1256
|
},
|
|
1113
1257
|
responseType: 'json',
|