transloadit 6.4.0 → 6.5.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 +30 -5
- package/dist/Transloadit.d.ts.map +1 -1
- package/dist/Transloadit.js +61 -5
- package/dist/Transloadit.js.map +1 -1
- package/dist/alphalib/types/builtinTemplates.d.ts +15 -3
- package/dist/alphalib/types/builtinTemplates.d.ts.map +1 -1
- package/dist/alphalib/types/builtinTemplates.js +23 -3
- package/dist/alphalib/types/builtinTemplates.js.map +1 -1
- package/dist/cli/OutputCtl.d.ts +1 -0
- package/dist/cli/OutputCtl.d.ts.map +1 -1
- package/dist/cli/OutputCtl.js +1 -1
- package/dist/cli/OutputCtl.js.map +1 -1
- package/dist/cli/commands/BaseCommand.d.ts +3 -2
- package/dist/cli/commands/BaseCommand.d.ts.map +1 -1
- package/dist/cli/commands/BaseCommand.js +27 -3
- package/dist/cli/commands/BaseCommand.js.map +1 -1
- package/dist/cli/commands/assemblies.d.ts +21 -1
- package/dist/cli/commands/assemblies.d.ts.map +1 -1
- package/dist/cli/commands/assemblies.js +584 -91
- package/dist/cli/commands/assemblies.js.map +1 -1
- package/dist/cli/commands/templates.d.ts +1 -1
- package/dist/cli/commands/templates.d.ts.map +1 -1
- package/dist/cli/commands/templates.js +57 -67
- package/dist/cli/commands/templates.js.map +1 -1
- package/dist/cli/errors.d.ts +8 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +28 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/helpers.js +22 -0
- package/dist/cli/helpers.js.map +1 -1
- package/dist/cli/intentRuntime.d.ts +1 -0
- package/dist/cli/intentRuntime.d.ts.map +1 -1
- package/dist/cli/intentRuntime.js +9 -3
- package/dist/cli/intentRuntime.js.map +1 -1
- package/dist/cli/resultFiles.d.ts +1 -0
- package/dist/cli/resultFiles.d.ts.map +1 -1
- package/dist/cli/resultFiles.js.map +1 -1
- package/dist/cli/resultUrls.d.ts +2 -1
- package/dist/cli/resultUrls.d.ts.map +1 -1
- package/dist/cli/resultUrls.js +6 -3
- package/dist/cli/resultUrls.js.map +1 -1
- package/dist/cli/stepsInput.d.ts.map +1 -1
- package/dist/cli/stepsInput.js +17 -4
- package/dist/cli/stepsInput.js.map +1 -1
- package/dist/cli/types.d.ts +66 -0
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli/types.js +29 -0
- package/dist/cli/types.js.map +1 -1
- package/dist/tus.d.ts +7 -2
- package/dist/tus.d.ts.map +1 -1
- package/dist/tus.js +58 -4
- package/dist/tus.js.map +1 -1
- package/package.json +1 -1
- package/src/Transloadit.ts +65 -4
- package/src/alphalib/types/builtinTemplates.ts +33 -3
- package/src/cli/OutputCtl.ts +2 -1
- package/src/cli/commands/BaseCommand.ts +29 -7
- package/src/cli/commands/assemblies.ts +775 -118
- package/src/cli/commands/templates.ts +93 -98
- package/src/cli/errors.ts +34 -0
- package/src/cli/helpers.ts +21 -0
- package/src/cli/intentRuntime.ts +10 -3
- package/src/cli/resultFiles.ts +1 -0
- package/src/cli/resultUrls.ts +11 -3
- package/src/cli/stepsInput.ts +19 -4
- package/src/cli/types.ts +35 -0
- package/src/tus.ts +72 -5
package/dist/cli/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,qCAAqC;AACrC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;CACpB,CAAC,CAAA;AAGF,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3C,QAAQ,EAAE,CAAC;SACR,MAAM,CAAC;QACN,IAAI,EAAE,CAAC;aACJ,MAAM,CAAC;YACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SAC7B,CAAC;aACD,QAAQ,EAAE;QACb,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAClC,CAAC;SACD,QAAQ,EAAE;CACd,CAAC,CAAA;AAeF,uCAAuC;AACvC,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,yBAAyB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;AAC5D,CAAC;AAED,0BAA0B;AAC1B,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAA;AAChD,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,OAAO,yBAAyB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAA;AAC3D,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,CAAA;AAClD,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":"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"}
|
package/dist/tus.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Readable } from 'node:stream';
|
|
2
2
|
import type { AssemblyStatus } from './alphalib/types/assemblyStatus.ts';
|
|
3
3
|
import type { UploadProgress } from './Transloadit.ts';
|
|
4
|
+
import { ReadStream } from 'node:fs';
|
|
4
5
|
export type UploadBehavior = 'await' | 'background' | 'none';
|
|
5
6
|
export interface Stream {
|
|
6
7
|
path?: string;
|
|
@@ -15,9 +16,13 @@ interface SendTusRequestOptions {
|
|
|
15
16
|
signal?: AbortSignal;
|
|
16
17
|
uploadUrls?: Record<string, string>;
|
|
17
18
|
uploadBehavior?: UploadBehavior;
|
|
19
|
+
onFileStreamOpened?: (stream: ReadStream) => void;
|
|
20
|
+
onFileSliceStarted?: (slice: Promise<unknown>) => void;
|
|
18
21
|
}
|
|
19
|
-
|
|
22
|
+
interface SendTusRequestResult {
|
|
20
23
|
uploadUrls: Record<string, string>;
|
|
21
|
-
|
|
24
|
+
uploadsComplete?: Promise<unknown>;
|
|
25
|
+
}
|
|
26
|
+
export declare function sendTusRequest({ streamsMap, assembly, requestedChunkSize, uploadConcurrency, onProgress, signal, uploadUrls, uploadBehavior, onFileStreamOpened, onFileSliceStarted, }: SendTusRequestOptions): Promise<SendTusRequestResult>;
|
|
22
27
|
export {};
|
|
23
28
|
//# sourceMappingURL=tus.d.ts.map
|
package/dist/tus.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tus.d.ts","sourceRoot":"","sources":["../src/tus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"tus.d.ts","sourceRoot":"","sources":["../src/tus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAW3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAWpC,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,YAAY,GAAG,MAAM,CAAA;AAE5D,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,QAAQ,CAAA;CACjB;AAED,UAAU,qBAAqB;IAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,QAAQ,EAAE,cAAc,CAAA;IACxB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,iBAAiB,EAAE,MAAM,CAAA;IACzB,UAAU,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;IAC7C,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAA;IACjD,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;CACvD;AAED,UAAU,oBAAoB;IAC5B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;CACnC;AAED,wBAAsB,cAAc,CAAC,EACnC,UAAU,EACV,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,UAAU,EACV,cAAwB,EACxB,kBAAkB,EAClB,kBAAkB,GACnB,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAgRvD"}
|
package/dist/tus.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { ReadStream } from 'node:fs';
|
|
1
2
|
import { stat } from 'node:fs/promises';
|
|
2
3
|
import { basename } from 'node:path';
|
|
3
4
|
import debug from 'debug';
|
|
4
5
|
import pMap from 'p-map';
|
|
5
|
-
import { Upload } from 'tus-js-client';
|
|
6
|
+
import { defaultOptions, Upload } from 'tus-js-client';
|
|
6
7
|
const log = debug('transloadit');
|
|
7
8
|
const logWarn = debug('transloadit:warn');
|
|
8
|
-
export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize, uploadConcurrency, onProgress, signal, uploadUrls, uploadBehavior = 'await', }) {
|
|
9
|
+
export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize, uploadConcurrency, onProgress, signal, uploadUrls, uploadBehavior = 'await', onFileStreamOpened, onFileSliceStarted, }) {
|
|
9
10
|
const streamLabels = Object.keys(streamsMap);
|
|
10
11
|
let totalBytes = 0;
|
|
11
12
|
let lastEmittedProgress = 0;
|
|
@@ -143,6 +144,25 @@ export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize,
|
|
|
143
144
|
fieldname: label,
|
|
144
145
|
filename,
|
|
145
146
|
},
|
|
147
|
+
httpStack: {
|
|
148
|
+
createRequest(method, url) {
|
|
149
|
+
const request = defaultOptions.httpStack.createRequest(method, url);
|
|
150
|
+
const send = request.send.bind(request);
|
|
151
|
+
request.send = (body) => {
|
|
152
|
+
// tus awaits pre-request hooks, so queued aborts must be checked at send itself.
|
|
153
|
+
if (signal?.aborted) {
|
|
154
|
+
// File setup can finish after abort() and reset tus's aborted state.
|
|
155
|
+
tusUpload.abort();
|
|
156
|
+
return Promise.reject(new Error('Upload aborted'));
|
|
157
|
+
}
|
|
158
|
+
return send(body);
|
|
159
|
+
};
|
|
160
|
+
return request;
|
|
161
|
+
},
|
|
162
|
+
getName() {
|
|
163
|
+
return defaultOptions.httpStack.getName();
|
|
164
|
+
},
|
|
165
|
+
},
|
|
146
166
|
onError: reject,
|
|
147
167
|
onProgress: onTusProgress,
|
|
148
168
|
onSuccess: resolve,
|
|
@@ -158,6 +178,39 @@ export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize,
|
|
|
158
178
|
}
|
|
159
179
|
},
|
|
160
180
|
};
|
|
181
|
+
if (onFileStreamOpened) {
|
|
182
|
+
// tus opens a separate ReadStream for each chunk; abort() leaves those streams open.
|
|
183
|
+
// Track those chunks even when the original file stream belongs to the caller.
|
|
184
|
+
tusOptions.fileReader = {
|
|
185
|
+
async openFile(input, chunkSize) {
|
|
186
|
+
const source = await defaultOptions.fileReader.openFile(input, chunkSize);
|
|
187
|
+
return {
|
|
188
|
+
size: source.size,
|
|
189
|
+
async slice(start, end) {
|
|
190
|
+
if (signal?.aborted)
|
|
191
|
+
throw new Error('Upload aborted');
|
|
192
|
+
const reading = source.slice(start, end).then((chunk) => {
|
|
193
|
+
// tus-js-client declares platform-specific chunk values as any.
|
|
194
|
+
const value = chunk.value;
|
|
195
|
+
if (value instanceof ReadStream)
|
|
196
|
+
onFileStreamOpened(value);
|
|
197
|
+
if (signal?.aborted)
|
|
198
|
+
throw new Error('Upload aborted');
|
|
199
|
+
return chunk;
|
|
200
|
+
});
|
|
201
|
+
// A file slice can open its stream before the promise resolves.
|
|
202
|
+
if (input instanceof ReadStream && input.path != null) {
|
|
203
|
+
onFileSliceStarted?.(reading);
|
|
204
|
+
}
|
|
205
|
+
return await reading;
|
|
206
|
+
},
|
|
207
|
+
close() {
|
|
208
|
+
source.close();
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
}
|
|
161
214
|
// tus-js-client doesn't like undefined/null
|
|
162
215
|
if (size != null)
|
|
163
216
|
tusOptions.uploadSize = size;
|
|
@@ -189,14 +242,15 @@ export async function sendTusRequest({ streamsMap, assembly, requestedChunkSize,
|
|
|
189
242
|
}
|
|
190
243
|
await pMap(streamLabels, uploadSingleStream, { concurrency: uploadConcurrency, signal });
|
|
191
244
|
await Promise.all(uploadUrlPromises);
|
|
245
|
+
const uploadsComplete = Promise.allSettled(completionPromises);
|
|
192
246
|
if (uploadBehavior === 'await') {
|
|
193
247
|
await Promise.all(completionPromises);
|
|
194
248
|
}
|
|
195
249
|
else {
|
|
196
|
-
|
|
250
|
+
uploadsComplete.catch((err) => {
|
|
197
251
|
logWarn('Background upload failed', err);
|
|
198
252
|
});
|
|
199
253
|
}
|
|
200
|
-
return { uploadUrls: uploadUrlsResult };
|
|
254
|
+
return { uploadUrls: uploadUrlsResult, uploadsComplete };
|
|
201
255
|
}
|
|
202
256
|
//# 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":"
|
|
1
|
+
{"version":3,"file":"tus.js","sourceRoot":"","sources":["../src/tus.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/Transloadit.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ReadStream } from 'node:fs'
|
|
1
2
|
import type { Readable } from 'node:stream'
|
|
2
3
|
|
|
3
4
|
import type {
|
|
@@ -72,9 +73,11 @@ import type { Stream, UploadBehavior } from './tus.ts'
|
|
|
72
73
|
|
|
73
74
|
import * as assert from 'node:assert'
|
|
74
75
|
import { randomUUID } from 'node:crypto'
|
|
76
|
+
import { addAbortListener, setMaxListeners } from 'node:events'
|
|
75
77
|
import { constants, createReadStream } from 'node:fs'
|
|
76
78
|
import { access, stat } from 'node:fs/promises'
|
|
77
79
|
import { basename } from 'node:path'
|
|
80
|
+
import { finished } from 'node:stream/promises'
|
|
78
81
|
import { setTimeout as delay } from 'node:timers/promises'
|
|
79
82
|
|
|
80
83
|
import { compileAssemblyInstructionsFromPrompt } from '@transloadit/utils'
|
|
@@ -241,11 +244,15 @@ const toReadableUpload = (label: string, value: Readable | IntoStreamInput): Rea
|
|
|
241
244
|
return readable ? value : intoStream(value)
|
|
242
245
|
}
|
|
243
246
|
|
|
244
|
-
const buildStreamsMap = (
|
|
247
|
+
const buildStreamsMap = (
|
|
248
|
+
descriptors: UploadDescriptor[],
|
|
249
|
+
onFileStreamOpened?: (stream: ReadStream) => void,
|
|
250
|
+
): Record<string, Stream> =>
|
|
245
251
|
Object.fromEntries(
|
|
246
252
|
descriptors.map((descriptor) => {
|
|
247
253
|
if (descriptor.path) {
|
|
248
254
|
const stream = createReadStream(descriptor.path)
|
|
255
|
+
onFileStreamOpened?.(stream)
|
|
249
256
|
return [descriptor.label, { stream, path: descriptor.path }]
|
|
250
257
|
}
|
|
251
258
|
|
|
@@ -705,7 +712,7 @@ export class Transloadit {
|
|
|
705
712
|
assemblyId,
|
|
706
713
|
expectedUploads,
|
|
707
714
|
onAssemblyCreated,
|
|
708
|
-
signal,
|
|
715
|
+
signal: callerSignal,
|
|
709
716
|
uploadBehavior = 'await',
|
|
710
717
|
} = opts
|
|
711
718
|
|
|
@@ -722,6 +729,34 @@ export class Transloadit {
|
|
|
722
729
|
effectiveAssemblyId = randomUUID().replace(/-/g, '')
|
|
723
730
|
}
|
|
724
731
|
const urlSuffix = `/assemblies/${effectiveAssemblyId}`
|
|
732
|
+
const uploadAbort = new AbortController()
|
|
733
|
+
const signal = uploadAbort.signal
|
|
734
|
+
// This private signal coordinates every concurrent upload and its queue.
|
|
735
|
+
setMaxListeners(0, signal)
|
|
736
|
+
if (callerSignal?.aborted) uploadAbort.abort(callerSignal.reason)
|
|
737
|
+
// Older supported Node releases retain AbortSignal.any() dependencies indefinitely.
|
|
738
|
+
const callerAbort =
|
|
739
|
+
callerSignal && !callerSignal.aborted
|
|
740
|
+
? addAbortListener(callerSignal, () => uploadAbort.abort(callerSignal.reason))
|
|
741
|
+
: undefined
|
|
742
|
+
const detachCallerAbort = (): void => {
|
|
743
|
+
callerAbort?.[Symbol.dispose]()
|
|
744
|
+
}
|
|
745
|
+
let backgroundUploadsComplete: Promise<unknown> | undefined
|
|
746
|
+
const openedFileStreams = new Set<ReadStream>()
|
|
747
|
+
const pendingFileSlices = new Set<Promise<unknown>>()
|
|
748
|
+
const onFileStreamOpened = (stream: ReadStream): void => {
|
|
749
|
+
// Register before I/O can emit close, so cleanup cannot miss that event.
|
|
750
|
+
openedFileStreams.add(stream)
|
|
751
|
+
stream.once('close', () => openedFileStreams.delete(stream))
|
|
752
|
+
}
|
|
753
|
+
const onFileSliceStarted = (slice: Promise<unknown>): void => {
|
|
754
|
+
pendingFileSlices.add(slice)
|
|
755
|
+
const remove = (): void => {
|
|
756
|
+
pendingFileSlices.delete(slice)
|
|
757
|
+
}
|
|
758
|
+
slice.then(remove, remove)
|
|
759
|
+
}
|
|
725
760
|
|
|
726
761
|
// We want to be able to return the promise immediately with custom data
|
|
727
762
|
const promise = (async () => {
|
|
@@ -746,7 +781,7 @@ export class Transloadit {
|
|
|
746
781
|
})),
|
|
747
782
|
]
|
|
748
783
|
|
|
749
|
-
const allStreamsMap = buildStreamsMap(descriptors)
|
|
784
|
+
const allStreamsMap = buildStreamsMap(descriptors, onFileStreamOpened)
|
|
750
785
|
|
|
751
786
|
const allStreams = Object.values(allStreamsMap)
|
|
752
787
|
|
|
@@ -779,7 +814,7 @@ export class Transloadit {
|
|
|
779
814
|
onAssemblyCreated?.(result)
|
|
780
815
|
|
|
781
816
|
if (Object.keys(allStreamsMap).length > 0) {
|
|
782
|
-
const { uploadUrls } = await sendTusRequest({
|
|
817
|
+
const { uploadUrls, uploadsComplete } = await sendTusRequest({
|
|
783
818
|
streamsMap: allStreamsMap,
|
|
784
819
|
assembly: result,
|
|
785
820
|
onProgress: onUploadProgress,
|
|
@@ -787,7 +822,10 @@ export class Transloadit {
|
|
|
787
822
|
uploadConcurrency,
|
|
788
823
|
signal,
|
|
789
824
|
uploadBehavior,
|
|
825
|
+
onFileStreamOpened,
|
|
826
|
+
onFileSliceStarted,
|
|
790
827
|
})
|
|
828
|
+
if (uploadBehavior === 'background') backgroundUploadsComplete = uploadsComplete
|
|
791
829
|
if (uploadBehavior !== 'await' && Object.keys(uploadUrls).length > 0) {
|
|
792
830
|
result.upload_urls = uploadUrls
|
|
793
831
|
}
|
|
@@ -813,6 +851,29 @@ export class Transloadit {
|
|
|
813
851
|
|
|
814
852
|
return Promise.race([createAssemblyAndUpload(), streamErrorPromise])
|
|
815
853
|
})()
|
|
854
|
+
.catch(async (error: unknown) => {
|
|
855
|
+
uploadAbort.abort()
|
|
856
|
+
// File descriptors must be closed before callers can remove their temporary files.
|
|
857
|
+
// Destroyed, unread streams reject finished(); cleanup must preserve the creation error.
|
|
858
|
+
while (openedFileStreams.size > 0 || pendingFileSlices.size > 0) {
|
|
859
|
+
await Promise.allSettled(pendingFileSlices)
|
|
860
|
+
await Promise.allSettled(
|
|
861
|
+
[...openedFileStreams].map((stream) => {
|
|
862
|
+
const closed = finished(stream, { cleanup: true })
|
|
863
|
+
stream.destroy()
|
|
864
|
+
return closed
|
|
865
|
+
}),
|
|
866
|
+
)
|
|
867
|
+
}
|
|
868
|
+
throw error
|
|
869
|
+
})
|
|
870
|
+
.finally(() => {
|
|
871
|
+
if (backgroundUploadsComplete && !signal.aborted) {
|
|
872
|
+
backgroundUploadsComplete.then(detachCallerAbort, detachCallerAbort)
|
|
873
|
+
return
|
|
874
|
+
}
|
|
875
|
+
detachCallerAbort()
|
|
876
|
+
})
|
|
816
877
|
|
|
817
878
|
// This allows the user to use or log the assemblyId even before it has been created for easier debugging
|
|
818
879
|
return Object.assign(promise, { assemblyId: effectiveAssemblyId })
|
|
@@ -27,12 +27,14 @@ export type BuiltinTemplateDoc = z.infer<typeof builtinTemplateDocSchema>
|
|
|
27
27
|
export const builtinTemplateFieldsSchema = z.record(z.string(), z.unknown()).nullable()
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
* Runtime catalog projection used by Builtin clients. API2 supplies descriptions,
|
|
31
|
-
* and defaults; absent and null schemas remain distinct, and neither
|
|
30
|
+
* Runtime catalog projection used by Builtin clients. API2 supplies descriptions, tool-ready
|
|
31
|
+
* summaries, field schemas and defaults; absent and null schemas remain distinct, and neither
|
|
32
|
+
* declares a usable contract.
|
|
32
33
|
*/
|
|
33
34
|
export const builtinTemplateCatalogItemSchema = z.object({
|
|
34
35
|
id: z.string(),
|
|
35
36
|
description: z.string().optional(),
|
|
37
|
+
summary: z.string().optional(),
|
|
36
38
|
fields_schema: builtinTemplateFieldsSchema.optional(),
|
|
37
39
|
content: z.object({ fields: z.record(z.string(), z.unknown()).default({}) }),
|
|
38
40
|
})
|
|
@@ -43,7 +45,8 @@ export type BuiltinTemplateCatalogItem = z.infer<typeof builtinTemplateCatalogIt
|
|
|
43
45
|
/**
|
|
44
46
|
* MCP channel approvals: exact reviewed versions and temporarily excluded field values.
|
|
45
47
|
* Membership is explicit; a catalog schema, a new Builtin version, or Storage eligibility does
|
|
46
|
-
* not grant MCP approval. Keep runtime descriptions, schemas and defaults in API2's
|
|
48
|
+
* not grant MCP approval. Keep runtime descriptions, summaries, schemas and defaults in API2's
|
|
49
|
+
* catalog.
|
|
47
50
|
*/
|
|
48
51
|
export const mcpBuiltinTemplateManifest: Readonly<
|
|
49
52
|
Record<string, Readonly<Record<string, readonly string[]>>>
|
|
@@ -76,3 +79,30 @@ export const mcpBuiltinInputUrlMaxCounts: Readonly<Record<string, number>> = {
|
|
|
76
79
|
'builtin/transcribe@0.0.1': 10,
|
|
77
80
|
'builtin/video-covers@0.0.1': 10,
|
|
78
81
|
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Static summaries of the MCP-approved Builtins, for clients that describe them before reading
|
|
85
|
+
* API2's catalog, such as server cards and directory listings. API2 authors each `summary` beside
|
|
86
|
+
* its Builtin definition and serves the same text in the Template list; its tests keep this copy
|
|
87
|
+
* equal to those definitions, so edit the definition first.
|
|
88
|
+
*/
|
|
89
|
+
export const mcpBuiltinTemplateSummaries: Readonly<Record<string, string>> = {
|
|
90
|
+
'builtin/caption-video@0.0.1':
|
|
91
|
+
'Transcribe the speech in videos and burn plain captions into each original video. Returns the captioned video and its SRT captions. Fields set the caption font_size (default 16), position, font_color and border_color. The automatic provider detects the spoken language; target_language (such as french) hints it, and source_language (default en-US) sets it for provider aws or gcp. Captions are never translated.',
|
|
92
|
+
'builtin/capture-webpage@0.0.1':
|
|
93
|
+
'Capture a public HTTP(S) webpage (url) or an uploaded HTML file as a PNG, JPEG or PDF. Returns one image or PDF per captured page. Defaults to a full-page PNG 1024 pixels wide; set fullpage to false for a fixed width × height viewport, and use delay or wait_until for late-loading pages. A url takes precedence over uploaded HTML. No custom headers, credentials or browser actions are sent.',
|
|
94
|
+
'builtin/convert-to-pdf@0.0.1':
|
|
95
|
+
'Convert Office documents, HTML, Markdown and plain text files to PDF. Returns one PDF per input. Fields set the paper size (pdf_format, default Letter), pdf_margin, background printing, and the Markdown flavor and theme. Paper and margin fields apply to HTML and Markdown; Office and text files keep the converter’s native layout.',
|
|
96
|
+
'builtin/encode-video@0.0.1':
|
|
97
|
+
'Encode videos for web playback with an MP4 or WebM preset. Returns one encoded video per input. Defaults to the 720p MP4 preset with turbo encoding; width or height override that preset dimension. Output size depends on the source and preset.',
|
|
98
|
+
'builtin/extract-text@0.0.1':
|
|
99
|
+
'Extract text from images, PDFs and Office documents as plain text (default) or JSON. Returns one text result per input by default. Images use OCR; documents try embedded text before OCR, and Office files are converted to PDF first. Fields set text_method, the OCR provider (AWS or GCP), page_range, password and text_granularity, where page returns one result per page; those last three need native extraction. Unsupported formats are skipped.',
|
|
100
|
+
'builtin/prepare-image@0.0.1':
|
|
101
|
+
'Prepare images for a website: auto-orient, fit within 1600×1600 pixels without enlarging, encode as WebP at quality 75, strip metadata and keep transparency. Returns one image per input. Fields set width and height (w, h), format (f), quality (q), resize strategy (r), background color (bg) and metadata stripping (strip). JPEG output needs an opaque background.',
|
|
102
|
+
'builtin/remove-background@0.0.1':
|
|
103
|
+
'Remove the background from photos. Returns the foreground of each image as a transparent PNG. Fields set the provider (automatic by default); only provider transloadit also allows GIF or WebP output, or keeping the background instead of the foreground.',
|
|
104
|
+
'builtin/transcribe@0.0.1':
|
|
105
|
+
'Transcribe the speech in audio or video files. Returns one transcript per input as timestamped JSON (default), plain text, SRT or WebVTT. The automatic provider detects the spoken language; target_language (such as french) hints it, and source_language (default en-US) sets it for provider aws or gcp. Transcripts are never translated.',
|
|
106
|
+
'builtin/video-covers@0.0.1':
|
|
107
|
+
'Extract cover images from videos. Returns 8 JPEG frames per video by default, taken at regular intervals, or frames at exact offsets in seconds or percentages. Set smart to true to have AI scoring pick the strongest count frames from up to three candidates per frame, capped by smart_max_candidates but never fewer than count. Fields also set format (JPEG or PNG), width and height, which default to the video’s dimensions.',
|
|
108
|
+
}
|
package/src/cli/OutputCtl.ts
CHANGED
|
@@ -60,6 +60,7 @@ export interface IOutputCtl {
|
|
|
60
60
|
info(msg: unknown): void
|
|
61
61
|
debug(msg: unknown): void
|
|
62
62
|
trace(msg: unknown): void
|
|
63
|
+
/** An undefined simple value emits JSON only, preserving binary or URL stdout in text mode. */
|
|
63
64
|
print(simple: unknown, json: unknown): void
|
|
64
65
|
}
|
|
65
66
|
|
|
@@ -110,6 +111,6 @@ export default class OutputCtl implements IOutputCtl {
|
|
|
110
111
|
print(simple: unknown, json: unknown): void {
|
|
111
112
|
if (this.json) console.log(JSON.stringify(json))
|
|
112
113
|
else if (typeof simple === 'string') console.log(simple)
|
|
113
|
-
else console.dir(simple, { depth: null })
|
|
114
|
+
else if (simple !== undefined) console.dir(simple, { depth: null })
|
|
114
115
|
}
|
|
115
116
|
}
|
|
@@ -2,9 +2,14 @@ import type { ResolvedCliConfig } from '../helpers.ts'
|
|
|
2
2
|
import type { IOutputCtl } from '../OutputCtl.ts'
|
|
3
3
|
|
|
4
4
|
import { Command, Option } from 'clipanion'
|
|
5
|
+
import { RequestError } from 'got'
|
|
6
|
+
import { z } from 'zod'
|
|
5
7
|
|
|
8
|
+
import { ApiError } from '../../ApiError.ts'
|
|
9
|
+
import { tryCatch } from '../../alphalib/tryCatch.ts'
|
|
6
10
|
import { Transloadit as TransloaditClient } from '../../Transloadit.ts'
|
|
7
|
-
import {
|
|
11
|
+
import { CliInputError, formatSchemaIssues } from '../errors.ts'
|
|
12
|
+
import { buildMissingAuthMessage, formatAPIError, resolveCliConfig } from '../helpers.ts'
|
|
8
13
|
import OutputCtl, { LOG_LEVEL_DEFAULT, LOG_LEVEL_NAMES, parseLogLevel } from '../OutputCtl.ts'
|
|
9
14
|
|
|
10
15
|
abstract class BaseCommand extends Command {
|
|
@@ -50,6 +55,27 @@ abstract class BaseCommand extends Command {
|
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
abstract override execute(): Promise<number | undefined>
|
|
58
|
+
|
|
59
|
+
protected abstract run(): Promise<number | undefined>
|
|
60
|
+
|
|
61
|
+
/** Report schema, API, and transport failures once; other errors retain Clipanion's diagnostics. */
|
|
62
|
+
protected async runWithErrorReporting(): Promise<number | undefined> {
|
|
63
|
+
const [error, result] = await tryCatch(this.run())
|
|
64
|
+
if (!error) return result
|
|
65
|
+
if (error instanceof z.ZodError) {
|
|
66
|
+
this.output.error(`Invalid options: ${formatSchemaIssues(error.issues)}`)
|
|
67
|
+
return 1
|
|
68
|
+
}
|
|
69
|
+
if (error instanceof RequestError) {
|
|
70
|
+
this.output.error(formatAPIError(error))
|
|
71
|
+
return 1
|
|
72
|
+
}
|
|
73
|
+
if (error instanceof CliInputError || error instanceof ApiError) {
|
|
74
|
+
this.output.error(formatAPIError(error))
|
|
75
|
+
return 1
|
|
76
|
+
}
|
|
77
|
+
throw error
|
|
78
|
+
}
|
|
53
79
|
}
|
|
54
80
|
|
|
55
81
|
export abstract class AuthenticatedCommand extends BaseCommand {
|
|
@@ -58,17 +84,13 @@ export abstract class AuthenticatedCommand extends BaseCommand {
|
|
|
58
84
|
if (!this.setupClient()) {
|
|
59
85
|
return 1
|
|
60
86
|
}
|
|
61
|
-
return await this.
|
|
87
|
+
return await this.runWithErrorReporting()
|
|
62
88
|
}
|
|
63
|
-
|
|
64
|
-
protected abstract run(): Promise<number | undefined>
|
|
65
89
|
}
|
|
66
90
|
|
|
67
91
|
export abstract class UnauthenticatedCommand extends BaseCommand {
|
|
68
92
|
override async execute(): Promise<number | undefined> {
|
|
69
93
|
this.setupOutput()
|
|
70
|
-
return await this.
|
|
94
|
+
return await this.runWithErrorReporting()
|
|
71
95
|
}
|
|
72
|
-
|
|
73
|
-
protected abstract run(): Promise<number | undefined>
|
|
74
96
|
}
|