transloadit 5.0.0 → 5.0.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 CHANGED
@@ -108,9 +108,9 @@ Most commands can authenticate with either `TRANSLOADIT_AUTH_TOKEN` or `TRANSLOA
108
108
 
109
109
  ### Storage images for Next.js
110
110
 
111
- `@transloadit/viewer` is currently an unpublished, private preview. Follow the
112
- [local package instructions](https://github.com/transloadit/node-sdk/blob/img-onboard/docs/img-dogfood.md)
113
- until release. In a Next.js 16.3.3+ App Router project with Storage enabled, run:
111
+ `@transloadit/viewer` is a published alpha. Follow the
112
+ [Viewer Quickstart](https://github.com/transloadit/node-sdk/blob/main/packages/img/README.md)
113
+ to install it. In a Next.js 16.3.3+ App Router project with Storage enabled, run:
114
114
 
115
115
  ```bash
116
116
  yarn transloadit auth login
@@ -143,6 +143,9 @@ Images are never decoded locally. Add `--placeholder blur` to request a server T
143
143
  omission or `--placeholder empty` performs no extraction. Successful extraction adds metadata
144
144
  usage equal to 20% of the file's bytes. Viewer's separate `placeholder="blur"` opts into rendering.
145
145
  Extraction is best-effort: a missing hash does not fail the upload or trigger another one.
146
+ For live user-upload galleries, use [dynamic React receipts](https://github.com/transloadit/node-sdk/blob/main/packages/img/docs/react-storage.md)
147
+ instead of a committed catalog. Authorize preview access before returning a receipt's ThumbHash;
148
+ the hash contains recognizable image data.
146
149
  An occupied path conflicts unless `--overwrite` is explicit; prefer `--hashed` for immutable
147
150
  filenames. Matching receipts skip repeat uploads; changed bytes get a new name.
148
151
  Storage receipts pin the returned `asset_id` and `version_id`. The image URL selects that exact
@@ -0,0 +1,29 @@
1
+ import type { StoredAsset } from './storageAsset.ts';
2
+ import { z } from 'zod';
3
+ /** Server-owned Assembly identity and expected Workspace, never untrusted notification fields. */
4
+ export declare const storedAssemblyResultsOptionsSchema: z.ZodObject<{
5
+ assemblyId: z.ZodString;
6
+ workspace: z.ZodString;
7
+ }, "strip", z.ZodTypeAny, {
8
+ workspace: string;
9
+ assemblyId: string;
10
+ }, {
11
+ workspace: string;
12
+ assemblyId: string;
13
+ }>;
14
+ export type GetStoredAssemblyResultsOptions = z.infer<typeof storedAssemblyResultsOptionsSchema>;
15
+ /** Canonical retained receipt and producing result provenance, for idempotent registration. */
16
+ export interface StoredAssemblyResult {
17
+ assembly_id: string;
18
+ step: string;
19
+ result_id: string;
20
+ original_id?: string | (string | null)[];
21
+ asset: StoredAsset;
22
+ }
23
+ /**
24
+ * Pure extraction from a fetched/verified Assembly bound to an authorized app upload. Validates
25
+ * every retained result atomically; temporary outputs are ignored, partial receipts are rejected.
26
+ * This does not authenticate notifications or check application permissions.
27
+ */
28
+ export declare function extractStoredAssemblyResults(input: unknown, options: GetStoredAssemblyResultsOptions): StoredAssemblyResult[];
29
+ //# sourceMappingURL=storageResults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storageResults.d.ts","sourceRoot":"","sources":["../../../src/alphalib/types/storageResults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAOvB,kGAAkG;AAClG,eAAO,MAAM,kCAAkC;;;;;;;;;EAG7C,CAAA;AAEF,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAA;AAEhG,+FAA+F;AAC/F,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;IACxC,KAAK,EAAE,WAAW,CAAA;CACnB;AAaD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,+BAA+B,GACvC,oBAAoB,EAAE,CA6BxB"}
@@ -0,0 +1,53 @@
1
+ import { z } from 'zod';
2
+ import { storedAssetSchema } from "./storageAsset.js";
3
+ // SDK-owned extraction is outside alphalib-sync's explicit node-sdk syncIncludes. Co-location
4
+ // reuses canonical schemas and their Types/Zod generation without adding a runtime package.
5
+ /** Server-owned Assembly identity and expected Workspace, never untrusted notification fields. */
6
+ export const storedAssemblyResultsOptionsSchema = z.object({
7
+ assemblyId: z.string().regex(/^[A-Za-z0-9_-]+$/),
8
+ workspace: z.string().min(1),
9
+ });
10
+ const resultSchema = storedAssetSchema.extend({
11
+ id: z.string().min(1),
12
+ original_id: z.union([z.string(), z.array(z.string().nullable())]).optional(),
13
+ });
14
+ const assemblySchema = z.object({
15
+ assembly_id: z.string(),
16
+ ok: z.string().nullable().optional(),
17
+ error: z.string().optional(),
18
+ results: z.record(z.array(z.record(z.unknown()))).optional(),
19
+ });
20
+ /**
21
+ * Pure extraction from a fetched/verified Assembly bound to an authorized app upload. Validates
22
+ * every retained result atomically; temporary outputs are ignored, partial receipts are rejected.
23
+ * This does not authenticate notifications or check application permissions.
24
+ */
25
+ export function extractStoredAssemblyResults(input, options) {
26
+ const { assemblyId, workspace } = storedAssemblyResultsOptionsSchema.parse(options);
27
+ const assembly = assemblySchema.parse(input);
28
+ if (assembly.assembly_id !== assemblyId)
29
+ throw new Error('The response did not match the requested Assembly');
30
+ if (assembly.error !== undefined || assembly.ok !== 'ASSEMBLY_COMPLETED')
31
+ throw new Error(`The Storage Assembly is not complete (${assembly.error ?? assembly.ok})`);
32
+ if (assembly.results === undefined)
33
+ throw new Error('The completed Assembly did not contain results');
34
+ const results = [];
35
+ for (const [step, files] of Object.entries(assembly.results)) {
36
+ for (const file of files) {
37
+ if (file.asset_id === undefined &&
38
+ file.version_id === undefined &&
39
+ file.workspace === undefined)
40
+ continue;
41
+ const parsed = resultSchema.safeParse(file);
42
+ if (!parsed.success || parsed.data.workspace !== workspace) {
43
+ throw new Error('The Assembly returned an invalid or cross-Workspace Storage result', {
44
+ cause: { assemblyId, step },
45
+ });
46
+ }
47
+ const { id, original_id, ...asset } = parsed.data;
48
+ results.push({ assembly_id: assemblyId, step, result_id: id, original_id, asset });
49
+ }
50
+ }
51
+ return results;
52
+ }
53
+ //# sourceMappingURL=storageResults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storageResults.js","sourceRoot":"","sources":["../../../src/alphalib/types/storageResults.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { StoredAsset } from './alphalib/types/storageAsset.ts';
2
+ import type { GetStoredAssemblyResultsOptions, StoredAssemblyResult } from './alphalib/types/storageResults.ts';
2
3
  import type { Transloadit } from './Transloadit.ts';
3
4
  /** Original-byte delivery, not a preview or transcode; authorize the application's asset first. */
4
5
  export interface StoredAssetUrlOptions {
@@ -9,19 +10,7 @@ export interface StoredAssetUrlOptions {
9
10
  }
10
11
  /** Signs a retained original, including non-image media, without fetching or proxying its bytes. */
11
12
  export declare function getStoredAssetUrl(client: Transloadit, input: StoredAsset, options?: StoredAssetUrlOptions): string;
12
- /** Server-owned Assembly identity and expected Workspace, not values from an untrusted notification. */
13
- export interface GetStoredAssemblyResultsOptions {
14
- assemblyId: string;
15
- workspace: string;
16
- }
17
- /** A canonical stored asset with the producing result's provenance; one input can have many outputs. */
18
- export interface StoredAssemblyResult {
19
- assembly_id: string;
20
- step: string;
21
- result_id: string;
22
- original_id?: string | (string | null)[];
23
- asset: StoredAsset;
24
- }
13
+ export type { GetStoredAssemblyResultsOptions, StoredAssemblyResult, } from './alphalib/types/storageResults.ts';
25
14
  /**
26
15
  * Fetches a completed Assembly and verifies all retained results, including non-image media.
27
16
  * The caller must first bind the Assembly to an authorized application upload. Register results
@@ -1 +1 @@
1
- {"version":3,"file":"storageResults.d.ts","sourceRoot":"","sources":["../src/storageResults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AASnD,mGAAmG;AACnG,MAAM,WAAW,qBAAqB;IACpC,yFAAyF;IACzF,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC3B,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,oGAAoG;AACpG,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAuBR;AAED,wGAAwG;AACxG,MAAM,WAAW,+BAA+B;IAC9C,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,wGAAwG;AACxG,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;IACxC,KAAK,EAAE,WAAW,CAAA;CACnB;AAWD;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAsCjC"}
1
+ {"version":3,"file":"storageResults.d.ts","sourceRoot":"","sources":["../src/storageResults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,KAAK,EACV,+BAA+B,EAC/B,oBAAoB,EACrB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAWnD,mGAAmG;AACnG,MAAM,WAAW,qBAAqB;IACpC,yFAAyF;IACzF,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC3B,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,oGAAoG;AACpG,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAuBR;AAED,YAAY,EACV,+BAA+B,EAC/B,oBAAoB,GACrB,MAAM,oCAAoC,CAAA;AAE3C;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAcjC"}
@@ -1,7 +1,7 @@
1
- import { z } from 'zod';
2
1
  import { ApiError } from "./ApiError.js";
3
2
  import { robotFileServeInstructionsSchema } from "./alphalib/types/robots/file-serve.js";
4
3
  import { storedAssetSchema } from "./alphalib/types/storageAsset.js";
4
+ import { extractStoredAssemblyResults, storedAssemblyResultsOptionsSchema, } from "./alphalib/types/storageResults.js";
5
5
  import InconsistentResponseError from "./InconsistentResponseError.js";
6
6
  /** Signs a retained original, including non-image media, without fetching or proxying its bytes. */
7
7
  export function getStoredAssetUrl(client, input, options = {}) {
@@ -28,52 +28,27 @@ export function getStoredAssetUrl(client, input, options = {}) {
28
28
  expiresAt,
29
29
  });
30
30
  }
31
- const requestSchema = z.object({
32
- assemblyId: z.string().regex(/^[A-Za-z0-9_-]+$/),
33
- workspace: z.string().min(1),
34
- });
35
- const resultSchema = storedAssetSchema.extend({
36
- id: z.string().min(1),
37
- original_id: z.union([z.string(), z.array(z.string().nullable())]).optional(),
38
- });
39
31
  /**
40
32
  * Fetches a completed Assembly and verifies all retained results, including non-image media.
41
33
  * The caller must first bind the Assembly to an authorized application upload. Register results
42
34
  * idempotently by Assembly/step/result ID (or asset/version), not by filename or notification count.
43
35
  */
44
36
  export async function getStoredAssemblyResults(client, options) {
45
- const { assemblyId, workspace } = requestSchema.parse(options);
37
+ const { assemblyId, workspace } = storedAssemblyResultsOptionsSchema.parse(options);
46
38
  const assembly = await client.getAssembly(assemblyId);
47
39
  if (assembly.assembly_id !== assemblyId) {
48
40
  throw new InconsistentResponseError('The response did not match the requested Assembly');
49
41
  }
50
42
  if (typeof assembly.error === 'string')
51
43
  throw new ApiError({ body: assembly });
52
- if (assembly.ok !== 'ASSEMBLY_COMPLETED') {
53
- throw new InconsistentResponseError(`The Storage Assembly is not complete (${assembly.ok})`);
44
+ try {
45
+ return extractStoredAssemblyResults(assembly, { assemblyId, workspace });
54
46
  }
55
- if (assembly.results === undefined) {
56
- throw new InconsistentResponseError('The completed Assembly did not contain results');
47
+ catch (error) {
48
+ // Keep the Node SDK error contract while sharing strict extraction with Web runtimes.
49
+ if (!(error instanceof Error))
50
+ throw new Error('Invalid Assembly response', { cause: error });
51
+ throw new InconsistentResponseError(error.message, { cause: error.cause ?? error });
57
52
  }
58
- const results = [];
59
- for (const [step, files] of Object.entries(assembly.results)) {
60
- for (const file of files) {
61
- // Ordinary temporary/exported outputs are not Storage receipts. Partial Storage records
62
- // must fail validation rather than disappearing from an otherwise successful batch.
63
- if (file.asset_id === undefined &&
64
- file.version_id === undefined &&
65
- file.workspace === undefined)
66
- continue;
67
- const parsed = resultSchema.safeParse(file);
68
- if (!parsed.success || parsed.data.workspace !== workspace) {
69
- throw new InconsistentResponseError('The Assembly returned an invalid or cross-Workspace Storage result', {
70
- cause: { assemblyId, step },
71
- });
72
- }
73
- const { id, original_id, ...asset } = parsed.data;
74
- results.push({ assembly_id: assemblyId, step, result_id: id, original_id, asset });
75
- }
76
- }
77
- return results;
78
53
  }
79
54
  //# sourceMappingURL=storageResults.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storageResults.js","sourceRoot":"","sources":["../src/storageResults.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storageResults.js","sourceRoot":"","sources":["../src/storageResults.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "transloadit",
3
- "version": "5.0.0",
3
+ "version": "5.0.1",
4
4
  "description": "Node.js SDK for Transloadit",
5
5
  "homepage": "https://github.com/transloadit/node-sdk/tree/main/packages/node",
6
6
  "bugs": {
@@ -0,0 +1,75 @@
1
+ import type { StoredAsset } from './storageAsset.ts'
2
+
3
+ import { z } from 'zod'
4
+
5
+ import { storedAssetSchema } from './storageAsset.ts'
6
+
7
+ // SDK-owned extraction is outside alphalib-sync's explicit node-sdk syncIncludes. Co-location
8
+ // reuses canonical schemas and their Types/Zod generation without adding a runtime package.
9
+
10
+ /** Server-owned Assembly identity and expected Workspace, never untrusted notification fields. */
11
+ export const storedAssemblyResultsOptionsSchema = z.object({
12
+ assemblyId: z.string().regex(/^[A-Za-z0-9_-]+$/),
13
+ workspace: z.string().min(1),
14
+ })
15
+
16
+ export type GetStoredAssemblyResultsOptions = z.infer<typeof storedAssemblyResultsOptionsSchema>
17
+
18
+ /** Canonical retained receipt and producing result provenance, for idempotent registration. */
19
+ export interface StoredAssemblyResult {
20
+ assembly_id: string
21
+ step: string
22
+ result_id: string
23
+ original_id?: string | (string | null)[]
24
+ asset: StoredAsset
25
+ }
26
+
27
+ const resultSchema = storedAssetSchema.extend({
28
+ id: z.string().min(1),
29
+ original_id: z.union([z.string(), z.array(z.string().nullable())]).optional(),
30
+ })
31
+ const assemblySchema = z.object({
32
+ assembly_id: z.string(),
33
+ ok: z.string().nullable().optional(),
34
+ error: z.string().optional(),
35
+ results: z.record(z.array(z.record(z.unknown()))).optional(),
36
+ })
37
+
38
+ /**
39
+ * Pure extraction from a fetched/verified Assembly bound to an authorized app upload. Validates
40
+ * every retained result atomically; temporary outputs are ignored, partial receipts are rejected.
41
+ * This does not authenticate notifications or check application permissions.
42
+ */
43
+ export function extractStoredAssemblyResults(
44
+ input: unknown,
45
+ options: GetStoredAssemblyResultsOptions,
46
+ ): StoredAssemblyResult[] {
47
+ const { assemblyId, workspace } = storedAssemblyResultsOptionsSchema.parse(options)
48
+ const assembly = assemblySchema.parse(input)
49
+ if (assembly.assembly_id !== assemblyId)
50
+ throw new Error('The response did not match the requested Assembly')
51
+ if (assembly.error !== undefined || assembly.ok !== 'ASSEMBLY_COMPLETED')
52
+ throw new Error(`The Storage Assembly is not complete (${assembly.error ?? assembly.ok})`)
53
+ if (assembly.results === undefined)
54
+ throw new Error('The completed Assembly did not contain results')
55
+ const results: StoredAssemblyResult[] = []
56
+ for (const [step, files] of Object.entries(assembly.results)) {
57
+ for (const file of files) {
58
+ if (
59
+ file.asset_id === undefined &&
60
+ file.version_id === undefined &&
61
+ file.workspace === undefined
62
+ )
63
+ continue
64
+ const parsed = resultSchema.safeParse(file)
65
+ if (!parsed.success || parsed.data.workspace !== workspace) {
66
+ throw new Error('The Assembly returned an invalid or cross-Workspace Storage result', {
67
+ cause: { assemblyId, step },
68
+ })
69
+ }
70
+ const { id, original_id, ...asset } = parsed.data
71
+ results.push({ assembly_id: assemblyId, step, result_id: id, original_id, asset })
72
+ }
73
+ }
74
+ return results
75
+ }
@@ -1,11 +1,17 @@
1
1
  import type { StoredAsset } from './alphalib/types/storageAsset.ts'
2
+ import type {
3
+ GetStoredAssemblyResultsOptions,
4
+ StoredAssemblyResult,
5
+ } from './alphalib/types/storageResults.ts'
2
6
  import type { Transloadit } from './Transloadit.ts'
3
7
 
4
- import { z } from 'zod'
5
-
6
8
  import { ApiError } from './ApiError.ts'
7
9
  import { robotFileServeInstructionsSchema } from './alphalib/types/robots/file-serve.ts'
8
10
  import { storedAssetSchema } from './alphalib/types/storageAsset.ts'
11
+ import {
12
+ extractStoredAssemblyResults,
13
+ storedAssemblyResultsOptionsSchema,
14
+ } from './alphalib/types/storageResults.ts'
9
15
  import InconsistentResponseError from './InconsistentResponseError.ts'
10
16
 
11
17
  /** Original-byte delivery, not a preview or transcode; authorize the application's asset first. */
@@ -46,29 +52,10 @@ export function getStoredAssetUrl(
46
52
  })
47
53
  }
48
54
 
49
- /** Server-owned Assembly identity and expected Workspace, not values from an untrusted notification. */
50
- export interface GetStoredAssemblyResultsOptions {
51
- assemblyId: string
52
- workspace: string
53
- }
54
-
55
- /** A canonical stored asset with the producing result's provenance; one input can have many outputs. */
56
- export interface StoredAssemblyResult {
57
- assembly_id: string
58
- step: string
59
- result_id: string
60
- original_id?: string | (string | null)[]
61
- asset: StoredAsset
62
- }
63
-
64
- const requestSchema = z.object({
65
- assemblyId: z.string().regex(/^[A-Za-z0-9_-]+$/),
66
- workspace: z.string().min(1),
67
- })
68
- const resultSchema = storedAssetSchema.extend({
69
- id: z.string().min(1),
70
- original_id: z.union([z.string(), z.array(z.string().nullable())]).optional(),
71
- })
55
+ export type {
56
+ GetStoredAssemblyResultsOptions,
57
+ StoredAssemblyResult,
58
+ } from './alphalib/types/storageResults.ts'
72
59
 
73
60
  /**
74
61
  * Fetches a completed Assembly and verifies all retained results, including non-image media.
@@ -79,41 +66,17 @@ export async function getStoredAssemblyResults(
79
66
  client: Transloadit,
80
67
  options: GetStoredAssemblyResultsOptions,
81
68
  ): Promise<StoredAssemblyResult[]> {
82
- const { assemblyId, workspace } = requestSchema.parse(options)
69
+ const { assemblyId, workspace } = storedAssemblyResultsOptionsSchema.parse(options)
83
70
  const assembly = await client.getAssembly(assemblyId)
84
71
  if (assembly.assembly_id !== assemblyId) {
85
72
  throw new InconsistentResponseError('The response did not match the requested Assembly')
86
73
  }
87
74
  if (typeof assembly.error === 'string') throw new ApiError({ body: assembly })
88
- if (assembly.ok !== 'ASSEMBLY_COMPLETED') {
89
- throw new InconsistentResponseError(`The Storage Assembly is not complete (${assembly.ok})`)
90
- }
91
- if (assembly.results === undefined) {
92
- throw new InconsistentResponseError('The completed Assembly did not contain results')
93
- }
94
- const results: StoredAssemblyResult[] = []
95
- for (const [step, files] of Object.entries(assembly.results)) {
96
- for (const file of files) {
97
- // Ordinary temporary/exported outputs are not Storage receipts. Partial Storage records
98
- // must fail validation rather than disappearing from an otherwise successful batch.
99
- if (
100
- file.asset_id === undefined &&
101
- file.version_id === undefined &&
102
- file.workspace === undefined
103
- )
104
- continue
105
- const parsed = resultSchema.safeParse(file)
106
- if (!parsed.success || parsed.data.workspace !== workspace) {
107
- throw new InconsistentResponseError(
108
- 'The Assembly returned an invalid or cross-Workspace Storage result',
109
- {
110
- cause: { assemblyId, step },
111
- },
112
- )
113
- }
114
- const { id, original_id, ...asset } = parsed.data
115
- results.push({ assembly_id: assemblyId, step, result_id: id, original_id, asset })
116
- }
75
+ try {
76
+ return extractStoredAssemblyResults(assembly, { assemblyId, workspace })
77
+ } catch (error) {
78
+ // Keep the Node SDK error contract while sharing strict extraction with Web runtimes.
79
+ if (!(error instanceof Error)) throw new Error('Invalid Assembly response', { cause: error })
80
+ throw new InconsistentResponseError(error.message, { cause: error.cause ?? error })
117
81
  }
118
- return results
119
82
  }