@masters-union/union-stack 0.3.16 → 0.3.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/loader.v1.global.js +2 -2
- package/dist/cdn/loader.v1.global.js.map +1 -1
- package/dist/{chunk-3FCZBKNN.cjs → chunk-4645KBSE.cjs} +8 -8
- package/dist/{chunk-3FCZBKNN.cjs.map → chunk-4645KBSE.cjs.map} +1 -1
- package/dist/{chunk-XBQENFBZ.js → chunk-G2H5WZDV.js} +14 -12
- package/dist/chunk-G2H5WZDV.js.map +1 -0
- package/dist/{chunk-EBE7EIOZ.cjs → chunk-PVM2ZX45.cjs} +14 -14
- package/dist/{chunk-EBE7EIOZ.cjs.map → chunk-PVM2ZX45.cjs.map} +1 -1
- package/dist/{chunk-OZGVTEMZ.js → chunk-QQFNG3ZF.js} +4 -4
- package/dist/{chunk-OZGVTEMZ.js.map → chunk-QQFNG3ZF.js.map} +1 -1
- package/dist/{chunk-7NJTA5ZD.js → chunk-RYS4MXXL.js} +4 -4
- package/dist/{chunk-7NJTA5ZD.js.map → chunk-RYS4MXXL.js.map} +1 -1
- package/dist/{chunk-GTE65IAM.cjs → chunk-TQDC5KIC.cjs} +14 -12
- package/dist/chunk-TQDC5KIC.cjs.map +1 -0
- package/dist/{client-BCLIIiX2.d.ts → client-BofkorBV.d.ts} +1 -1
- package/dist/{client-CSZ-4GVl.d.cts → client-C_pEvbZS.d.cts} +1 -1
- package/dist/index.cjs +5 -5
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -4
- package/dist/node.cjs +8 -8
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +2 -2
- package/dist/picker.cjs +3 -3
- package/dist/picker.d.cts +3 -3
- package/dist/picker.d.ts +3 -3
- package/dist/picker.js +1 -1
- package/dist/react.cjs +4 -4
- package/dist/react.d.cts +4 -4
- package/dist/react.d.ts +4 -4
- package/dist/react.js +3 -3
- package/dist/{types-BWs1slkL.d.cts → types-BsGu9Oi3.d.cts} +2 -0
- package/dist/{types-BWs1slkL.d.ts → types-BsGu9Oi3.d.ts} +2 -0
- package/package.json +1 -1
- package/dist/chunk-GTE65IAM.cjs.map +0 -1
- package/dist/chunk-XBQENFBZ.js.map +0 -1
|
@@ -8,6 +8,7 @@ function makeError(code, message, opts = {}) {
|
|
|
8
8
|
message,
|
|
9
9
|
status: opts.status,
|
|
10
10
|
retryable: opts.retryable ?? defaultRetryable(code, opts.status),
|
|
11
|
+
docs: opts.docs,
|
|
11
12
|
cause: opts.cause
|
|
12
13
|
};
|
|
13
14
|
}
|
|
@@ -20,39 +21,40 @@ function fromApiResponse(status, body) {
|
|
|
20
21
|
const err = body?.error;
|
|
21
22
|
const msg = err?.message || `Request failed with status ${status}`;
|
|
22
23
|
const code = (err?.code || "").toUpperCase();
|
|
24
|
+
const docs = typeof err?.docs === "string" ? err.docs : void 0;
|
|
23
25
|
if (status === 401) {
|
|
24
|
-
return makeError("AUTH", msg, { status, retryable: false });
|
|
26
|
+
return makeError("AUTH", msg, { status, retryable: false, docs });
|
|
25
27
|
}
|
|
26
28
|
if (status === 403) {
|
|
27
|
-
return makeError("AUTH", msg, { status, retryable: false });
|
|
29
|
+
return makeError("AUTH", msg, { status, retryable: false, docs });
|
|
28
30
|
}
|
|
29
31
|
if (status === 413) {
|
|
30
|
-
return makeError("VALIDATION", msg, { status, retryable: false });
|
|
32
|
+
return makeError("VALIDATION", msg, { status, retryable: false, docs });
|
|
31
33
|
}
|
|
32
34
|
if (status === 415) {
|
|
33
|
-
return makeError("VALIDATION", msg, { status, retryable: false });
|
|
35
|
+
return makeError("VALIDATION", msg, { status, retryable: false, docs });
|
|
34
36
|
}
|
|
35
37
|
if (status === 422) {
|
|
36
38
|
if (code === "EMPTY_UPLOAD") {
|
|
37
|
-
return makeError("EMPTY_FILE", EMPTY_FILE_MESSAGE, { status, retryable: false });
|
|
39
|
+
return makeError("EMPTY_FILE", EMPTY_FILE_MESSAGE, { status, retryable: false, docs });
|
|
38
40
|
}
|
|
39
|
-
return makeError("VALIDATION", msg, { status, retryable: false });
|
|
41
|
+
return makeError("VALIDATION", msg, { status, retryable: false, docs });
|
|
40
42
|
}
|
|
41
43
|
if (status === 426) {
|
|
42
|
-
return makeError("CONFIG", msg, { status, retryable: false });
|
|
44
|
+
return makeError("CONFIG", msg, { status, retryable: false, docs });
|
|
43
45
|
}
|
|
44
46
|
if (status === 429) {
|
|
45
47
|
const isQuota = code === "QUOTA_EXCEEDED";
|
|
46
|
-
return makeError(isQuota ? "QUOTA" : "NETWORK", msg, { status, retryable: !isQuota });
|
|
48
|
+
return makeError(isQuota ? "QUOTA" : "NETWORK", msg, { status, retryable: !isQuota, docs });
|
|
47
49
|
}
|
|
48
50
|
if (status >= 500) {
|
|
49
|
-
return makeError("SERVER", msg, { status, retryable: true });
|
|
51
|
+
return makeError("SERVER", msg, { status, retryable: true, docs });
|
|
50
52
|
}
|
|
51
|
-
return makeError("SERVER", msg, { status, retryable: false });
|
|
53
|
+
return makeError("SERVER", msg, { status, retryable: false, docs });
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
exports.EMPTY_FILE_MESSAGE = EMPTY_FILE_MESSAGE;
|
|
55
57
|
exports.fromApiResponse = fromApiResponse;
|
|
56
58
|
exports.makeError = makeError;
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
59
|
+
//# sourceMappingURL=chunk-TQDC5KIC.cjs.map
|
|
60
|
+
//# sourceMappingURL=chunk-TQDC5KIC.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts"],"names":[],"mappings":";;;AAMO,IAAM,kBAAA,GACX;AAGK,SAAS,SAAA,CACd,IAAA,EACA,OAAA,EACA,IAAA,GAAiF,EAAC,EACrE;AACb,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,WAAW,IAAA,CAAK,SAAA,IAAa,gBAAA,CAAiB,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,IAC/D,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,OAAO,IAAA,CAAK;AAAA,GACd;AACF;AAEA,SAAS,gBAAA,CAAiB,MAAuB,MAAA,EAA0B;AACzE,EAAA,IAAI,IAAA,KAAS,SAAA,IAAa,IAAA,KAAS,aAAA,EAAe,OAAO,IAAA;AACzD,EAAA,IAAI,IAAA,KAAS,QAAA,IAAY,MAAA,IAAU,MAAA,IAAU,KAAK,OAAO,IAAA;AACzD,EAAA,OAAO,KAAA;AACT;AAGO,SAAS,eAAA,CAAgB,QAAgB,IAAA,EAA4B;AAC1E,EAAA,MAAM,MAAO,IAAA,EAAgF,KAAA;AAC7F,EAAA,MAAM,GAAA,GAAM,GAAA,EAAK,OAAA,IAAW,CAAA,2BAAA,EAA8B,MAAM,CAAA,CAAA;AAChE,EAAA,MAAM,IAAA,GAAA,CAAQ,GAAA,EAAK,IAAA,IAAQ,EAAA,EAAI,WAAA,EAAY;AAG3C,EAAA,MAAM,OAAO,OAAO,GAAA,EAAK,IAAA,KAAS,QAAA,GAAW,IAAI,IAAA,GAAO,MAAA;AAExD,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,SAAA,CAAU,QAAQ,GAAA,EAAK,EAAE,QAAQ,SAAA,EAAW,KAAA,EAAO,MAAM,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,SAAA,CAAU,QAAQ,GAAA,EAAK,EAAE,QAAQ,SAAA,EAAW,KAAA,EAAO,MAAM,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,SAAA,CAAU,cAAc,GAAA,EAAK,EAAE,QAAQ,SAAA,EAAW,KAAA,EAAO,MAAM,CAAA;AAAA,EACxE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,SAAA,CAAU,cAAc,GAAA,EAAK,EAAE,QAAQ,SAAA,EAAW,KAAA,EAAO,MAAM,CAAA;AAAA,EACxE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAKlB,IAAA,IAAI,SAAS,cAAA,EAAgB;AAC3B,MAAA,OAAO,SAAA,CAAU,cAAc,kBAAA,EAAoB,EAAE,QAAQ,SAAA,EAAW,KAAA,EAAO,MAAM,CAAA;AAAA,IACvF;AACA,IAAA,OAAO,SAAA,CAAU,cAAc,GAAA,EAAK,EAAE,QAAQ,SAAA,EAAW,KAAA,EAAO,MAAM,CAAA;AAAA,EACxE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAGlB,IAAA,OAAO,SAAA,CAAU,UAAU,GAAA,EAAK,EAAE,QAAQ,SAAA,EAAW,KAAA,EAAO,MAAM,CAAA;AAAA,EACpE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,MAAM,UAAU,IAAA,KAAS,gBAAA;AACzB,IAAA,OAAO,SAAA,CAAU,OAAA,GAAU,OAAA,GAAU,SAAA,EAAW,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,CAAC,OAAA,EAAS,IAAA,EAAM,CAAA;AAAA,EAC5F;AACA,EAAA,IAAI,UAAU,GAAA,EAAK;AACjB,IAAA,OAAO,SAAA,CAAU,UAAU,GAAA,EAAK,EAAE,QAAQ,SAAA,EAAW,IAAA,EAAM,MAAM,CAAA;AAAA,EACnE;AACA,EAAA,OAAO,SAAA,CAAU,UAAU,GAAA,EAAK,EAAE,QAAQ,SAAA,EAAW,KAAA,EAAO,MAAM,CAAA;AACpE","file":"chunk-TQDC5KIC.cjs","sourcesContent":["import type { UploadError, UploadErrorCode } from './types.js';\n\n// Single source of truth for the 0-byte message. Used by the client-side guard\n// (uploader), the picker UI, and the server-side reject (mapped from a 422\n// EMPTY_UPLOAD), so the end user sees the same actionable text no matter where\n// the empty file was caught.\nexport const EMPTY_FILE_MESSAGE =\n \"This file is empty (0 bytes) and can't be uploaded. If it's stored in iCloud, \" +\n 'OneDrive, or Google Drive, open it once to download it to this device, then try again.';\n\nexport function makeError(\n code: UploadErrorCode,\n message: string,\n opts: { status?: number; retryable?: boolean; docs?: string; cause?: unknown } = {}\n): UploadError {\n return {\n code,\n message,\n status: opts.status,\n retryable: opts.retryable ?? defaultRetryable(code, opts.status),\n docs: opts.docs,\n cause: opts.cause,\n };\n}\n\nfunction defaultRetryable(code: UploadErrorCode, status?: number): boolean {\n if (code === 'NETWORK' || code === 'PART_FAILED') return true;\n if (code === 'SERVER' && status && status >= 500) return true;\n return false;\n}\n\n/** Map an HTTP error response from the cdn-be API to an UploadError. */\nexport function fromApiResponse(status: number, body: unknown): UploadError {\n const err = (body as { error?: { code?: string; message?: string; docs?: string } } | null)?.error;\n const msg = err?.message || `Request failed with status ${status}`;\n const code = (err?.code || '').toUpperCase();\n // Docs deep-link the API attaches to some errors (e.g. ORIGIN_NOT_ALLOWED).\n // Passed through on every mapping so callers can surface a \"learn more\" link.\n const docs = typeof err?.docs === 'string' ? err.docs : undefined;\n\n if (status === 401) {\n return makeError('AUTH', msg, { status, retryable: false, docs });\n }\n if (status === 403) {\n return makeError('AUTH', msg, { status, retryable: false, docs });\n }\n if (status === 413) {\n return makeError('VALIDATION', msg, { status, retryable: false, docs });\n }\n if (status === 415) {\n return makeError('VALIDATION', msg, { status, retryable: false, docs });\n }\n if (status === 422) {\n // Server rejected the assembled object. EMPTY_UPLOAD (0 bytes landed) gets\n // the dedicated code + canonical message so it reads the same as a\n // client-side empty catch; other 422s fall back to VALIDATION. Either way,\n // retrying the same source file won't help, so it's not retryable.\n if (code === 'EMPTY_UPLOAD') {\n return makeError('EMPTY_FILE', EMPTY_FILE_MESSAGE, { status, retryable: false, docs });\n }\n return makeError('VALIDATION', msg, { status, retryable: false, docs });\n }\n if (status === 426) {\n // Server-enforced minimum SDK version. Not retryable — the integrator\n // must upgrade the package (or reload, for script-loader users).\n return makeError('CONFIG', msg, { status, retryable: false, docs });\n }\n if (status === 429) {\n const isQuota = code === 'QUOTA_EXCEEDED';\n return makeError(isQuota ? 'QUOTA' : 'NETWORK', msg, { status, retryable: !isQuota, docs });\n }\n if (status >= 500) {\n return makeError('SERVER', msg, { status, retryable: true, docs });\n }\n return makeError('SERVER', msg, { status, retryable: false, docs });\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BatchUploadOptions, a as PickedFile, P as PickResponse, f as PickerConfig, C as ClientConfig, d as UploadOptions, e as UploadedFile, R as ResolvedClientConfig } from './types-
|
|
1
|
+
import { B as BatchUploadOptions, a as PickedFile, P as PickResponse, f as PickerConfig, C as ClientConfig, d as UploadOptions, e as UploadedFile, R as ResolvedClientConfig } from './types-BsGu9Oi3.js';
|
|
2
2
|
|
|
3
3
|
interface PickerTheme {
|
|
4
4
|
/** Primary accent color (buttons, progress bar, focus rings). */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BatchUploadOptions, a as PickedFile, P as PickResponse, f as PickerConfig, C as ClientConfig, d as UploadOptions, e as UploadedFile, R as ResolvedClientConfig } from './types-
|
|
1
|
+
import { B as BatchUploadOptions, a as PickedFile, P as PickResponse, f as PickerConfig, C as ClientConfig, d as UploadOptions, e as UploadedFile, R as ResolvedClientConfig } from './types-BsGu9Oi3.cjs';
|
|
2
2
|
|
|
3
3
|
interface PickerTheme {
|
|
4
4
|
/** Primary accent color (buttons, progress bar, focus rings). */
|
package/dist/index.cjs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-
|
|
5
|
-
require('./chunk-
|
|
3
|
+
var chunk4645KBSE_cjs = require('./chunk-4645KBSE.cjs');
|
|
4
|
+
require('./chunk-PVM2ZX45.cjs');
|
|
5
|
+
require('./chunk-TQDC5KIC.cjs');
|
|
6
6
|
|
|
7
7
|
// src/index.ts
|
|
8
8
|
var UnionStack = {
|
|
9
9
|
init(cfg) {
|
|
10
|
-
return new
|
|
10
|
+
return new chunk4645KBSE_cjs.UnionStackClient(cfg);
|
|
11
11
|
}
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
Object.defineProperty(exports, "UnionStackClient", {
|
|
15
15
|
enumerable: true,
|
|
16
|
-
get: function () { return
|
|
16
|
+
get: function () { return chunk4645KBSE_cjs.UnionStackClient; }
|
|
17
17
|
});
|
|
18
18
|
exports.UnionStack = UnionStack;
|
|
19
19
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { U as UnionStackClient } from './client-
|
|
2
|
-
import { C as ClientConfig } from './types-
|
|
3
|
-
export { B as BatchUploadOptions, P as PickResponse, a as PickedFile, b as ProgressEvent, S as Source, U as UploadError, c as UploadErrorCode, d as UploadOptions, e as UploadedFile } from './types-
|
|
1
|
+
import { U as UnionStackClient } from './client-C_pEvbZS.cjs';
|
|
2
|
+
import { C as ClientConfig } from './types-BsGu9Oi3.cjs';
|
|
3
|
+
export { B as BatchUploadOptions, P as PickResponse, a as PickedFile, b as ProgressEvent, S as Source, U as UploadError, c as UploadErrorCode, d as UploadOptions, e as UploadedFile } from './types-BsGu9Oi3.cjs';
|
|
4
4
|
|
|
5
5
|
declare const UnionStack: {
|
|
6
6
|
init(cfg: ClientConfig): UnionStackClient;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { U as UnionStackClient } from './client-
|
|
2
|
-
import { C as ClientConfig } from './types-
|
|
3
|
-
export { B as BatchUploadOptions, P as PickResponse, a as PickedFile, b as ProgressEvent, S as Source, U as UploadError, c as UploadErrorCode, d as UploadOptions, e as UploadedFile } from './types-
|
|
1
|
+
import { U as UnionStackClient } from './client-BofkorBV.js';
|
|
2
|
+
import { C as ClientConfig } from './types-BsGu9Oi3.js';
|
|
3
|
+
export { B as BatchUploadOptions, P as PickResponse, a as PickedFile, b as ProgressEvent, S as Source, U as UploadError, c as UploadErrorCode, d as UploadOptions, e as UploadedFile } from './types-BsGu9Oi3.js';
|
|
4
4
|
|
|
5
5
|
declare const UnionStack: {
|
|
6
6
|
init(cfg: ClientConfig): UnionStackClient;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { UnionStackClient } from './chunk-
|
|
2
|
-
export { UnionStackClient } from './chunk-
|
|
3
|
-
import './chunk-
|
|
4
|
-
import './chunk-
|
|
1
|
+
import { UnionStackClient } from './chunk-QQFNG3ZF.js';
|
|
2
|
+
export { UnionStackClient } from './chunk-QQFNG3ZF.js';
|
|
3
|
+
import './chunk-RYS4MXXL.js';
|
|
4
|
+
import './chunk-G2H5WZDV.js';
|
|
5
5
|
|
|
6
6
|
// src/index.ts
|
|
7
7
|
var UnionStack = {
|
package/dist/node.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkPVM2ZX45_cjs = require('./chunk-PVM2ZX45.cjs');
|
|
4
|
+
var chunkTQDC5KIC_cjs = require('./chunk-TQDC5KIC.cjs');
|
|
5
5
|
var path = require('path');
|
|
6
6
|
var promises = require('fs/promises');
|
|
7
7
|
var fs = require('fs');
|
|
@@ -98,7 +98,7 @@ async function resolveSource(source, opts = {}) {
|
|
|
98
98
|
const blob = openAsBlob2 ? await openAsBlob2(source, { type: mimetype }) : new Blob([toBlobPart(await promises.readFile(source))], { type: mimetype });
|
|
99
99
|
return { blob, filename, mimetype };
|
|
100
100
|
} catch (cause) {
|
|
101
|
-
throw
|
|
101
|
+
throw chunkTQDC5KIC_cjs.makeError("VALIDATION", `Could not read file at "${source}".`, {
|
|
102
102
|
retryable: false,
|
|
103
103
|
cause
|
|
104
104
|
});
|
|
@@ -121,7 +121,7 @@ async function resolveSource(source, opts = {}) {
|
|
|
121
121
|
const mimetype = opts.mimeType || mimeFromName(filename);
|
|
122
122
|
return { blob: new Blob([toBlobPart(source)], { type: mimetype }), filename, mimetype };
|
|
123
123
|
}
|
|
124
|
-
throw
|
|
124
|
+
throw chunkTQDC5KIC_cjs.makeError(
|
|
125
125
|
"VALIDATION",
|
|
126
126
|
"Unsupported upload source. Pass a file path, Buffer, Uint8Array, ArrayBuffer, Blob, or Readable stream.",
|
|
127
127
|
{ retryable: false }
|
|
@@ -134,7 +134,7 @@ var DEFAULT_FILE_CONCURRENCY = 5;
|
|
|
134
134
|
var UnionStackNodeClient = class {
|
|
135
135
|
constructor(cfg) {
|
|
136
136
|
if (!cfg?.apiKey) {
|
|
137
|
-
throw
|
|
137
|
+
throw chunkTQDC5KIC_cjs.makeError("CONFIG", 'apiKey is required. Pass { apiKey: "unionstack_live_\u2026" }.', {
|
|
138
138
|
retryable: false
|
|
139
139
|
});
|
|
140
140
|
}
|
|
@@ -145,9 +145,9 @@ var UnionStackNodeClient = class {
|
|
|
145
145
|
skipConfigPrefetch: true,
|
|
146
146
|
// Tag the traffic as server-to-server ("node/…") so cdn-be can tell it
|
|
147
147
|
// apart from browser SDK calls ("js/…").
|
|
148
|
-
sdkHeader:
|
|
148
|
+
sdkHeader: chunkPVM2ZX45_cjs.NODE_SDK_VERSION_HEADER
|
|
149
149
|
};
|
|
150
|
-
this.uploader = new
|
|
150
|
+
this.uploader = new chunkPVM2ZX45_cjs.Uploader(this.cfg);
|
|
151
151
|
}
|
|
152
152
|
/**
|
|
153
153
|
* Upload one file. Accepts a path on disk, a Buffer/Uint8Array/ArrayBuffer, a
|
|
@@ -169,7 +169,7 @@ var UnionStackNodeClient = class {
|
|
|
169
169
|
*/
|
|
170
170
|
async uploadMany(sources, opts = {}) {
|
|
171
171
|
if (!Array.isArray(sources) || sources.length === 0) {
|
|
172
|
-
const err =
|
|
172
|
+
const err = chunkTQDC5KIC_cjs.makeError("VALIDATION", "uploadMany requires a non-empty array of sources.", {
|
|
173
173
|
retryable: false
|
|
174
174
|
});
|
|
175
175
|
opts.onError?.(err);
|
package/dist/node.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
|
-
import { C as ClientConfig, d as UploadOptions, e as UploadedFile, B as BatchUploadOptions, P as PickResponse, R as ResolvedClientConfig } from './types-
|
|
3
|
-
export { a as PickedFile, b as ProgressEvent, S as Source, U as UploadError, c as UploadErrorCode } from './types-
|
|
2
|
+
import { C as ClientConfig, d as UploadOptions, e as UploadedFile, B as BatchUploadOptions, P as PickResponse, R as ResolvedClientConfig } from './types-BsGu9Oi3.cjs';
|
|
3
|
+
export { a as PickedFile, b as ProgressEvent, S as Source, U as UploadError, c as UploadErrorCode } from './types-BsGu9Oi3.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Anything the Node client knows how to turn into an upload.
|
package/dist/node.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
|
-
import { C as ClientConfig, d as UploadOptions, e as UploadedFile, B as BatchUploadOptions, P as PickResponse, R as ResolvedClientConfig } from './types-
|
|
3
|
-
export { a as PickedFile, b as ProgressEvent, S as Source, U as UploadError, c as UploadErrorCode } from './types-
|
|
2
|
+
import { C as ClientConfig, d as UploadOptions, e as UploadedFile, B as BatchUploadOptions, P as PickResponse, R as ResolvedClientConfig } from './types-BsGu9Oi3.js';
|
|
3
|
+
export { a as PickedFile, b as ProgressEvent, S as Source, U as UploadError, c as UploadErrorCode } from './types-BsGu9Oi3.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Anything the Node client knows how to turn into an upload.
|
package/dist/node.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { NODE_SDK_VERSION_HEADER, Uploader } from './chunk-
|
|
2
|
-
import { makeError } from './chunk-
|
|
1
|
+
import { NODE_SDK_VERSION_HEADER, Uploader } from './chunk-RYS4MXXL.js';
|
|
2
|
+
import { makeError } from './chunk-G2H5WZDV.js';
|
|
3
3
|
import { basename, extname } from 'path';
|
|
4
4
|
import { readFile } from 'fs/promises';
|
|
5
5
|
import * as fs from 'fs';
|
package/dist/picker.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkTQDC5KIC_cjs = require('./chunk-TQDC5KIC.cjs');
|
|
4
4
|
|
|
5
5
|
// src/picker/styles.ts
|
|
6
6
|
var STYLE_ID = "unionstack-picker-styles";
|
|
@@ -1713,7 +1713,7 @@ var Picker = class {
|
|
|
1713
1713
|
edited: false,
|
|
1714
1714
|
state: "failed",
|
|
1715
1715
|
progress: 0,
|
|
1716
|
-
error:
|
|
1716
|
+
error: chunkTQDC5KIC_cjs.EMPTY_FILE_MESSAGE,
|
|
1717
1717
|
errorCode: "EMPTY_FILE"
|
|
1718
1718
|
};
|
|
1719
1719
|
this.items.push(item2);
|
|
@@ -2114,7 +2114,7 @@ var Picker = class {
|
|
|
2114
2114
|
item.errorCode = err.code;
|
|
2115
2115
|
this.setItemState(item, "failed");
|
|
2116
2116
|
}
|
|
2117
|
-
if (err.code === "EMPTY_FILE") this.flashNotice(
|
|
2117
|
+
if (err.code === "EMPTY_FILE") this.flashNotice(chunkTQDC5KIC_cjs.EMPTY_FILE_MESSAGE);
|
|
2118
2118
|
this.opts.onFileUploadFailed?.(p, err);
|
|
2119
2119
|
},
|
|
2120
2120
|
onUploadDone: (r) => {
|
package/dist/picker.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { U as UnionStackClient, P as PickerOptions, a as PickerHandle } from './client-
|
|
2
|
-
export { b as PickerBranding, c as PickerTheme } from './client-
|
|
3
|
-
import { P as PickResponse } from './types-
|
|
1
|
+
import { U as UnionStackClient, P as PickerOptions, a as PickerHandle } from './client-C_pEvbZS.cjs';
|
|
2
|
+
export { b as PickerBranding, c as PickerTheme } from './client-C_pEvbZS.cjs';
|
|
3
|
+
import { P as PickResponse } from './types-BsGu9Oi3.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Single-shot file picker modal. Built imperatively (no framework) so it can
|
package/dist/picker.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { U as UnionStackClient, P as PickerOptions, a as PickerHandle } from './client-
|
|
2
|
-
export { b as PickerBranding, c as PickerTheme } from './client-
|
|
3
|
-
import { P as PickResponse } from './types-
|
|
1
|
+
import { U as UnionStackClient, P as PickerOptions, a as PickerHandle } from './client-BofkorBV.js';
|
|
2
|
+
export { b as PickerBranding, c as PickerTheme } from './client-BofkorBV.js';
|
|
3
|
+
import { P as PickResponse } from './types-BsGu9Oi3.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Single-shot file picker modal. Built imperatively (no framework) so it can
|
package/dist/picker.js
CHANGED
package/dist/react.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-
|
|
5
|
-
require('./chunk-
|
|
3
|
+
var chunk4645KBSE_cjs = require('./chunk-4645KBSE.cjs');
|
|
4
|
+
require('./chunk-PVM2ZX45.cjs');
|
|
5
|
+
require('./chunk-TQDC5KIC.cjs');
|
|
6
6
|
var React3 = require('react');
|
|
7
7
|
|
|
8
8
|
function _interopNamespace(e) {
|
|
@@ -28,7 +28,7 @@ var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
|
|
|
28
28
|
var UnionStackContext = React3__namespace.createContext(null);
|
|
29
29
|
function UnionStackProvider({ children, ...cfg }) {
|
|
30
30
|
const client = React3__namespace.useMemo(
|
|
31
|
-
() => new
|
|
31
|
+
() => new chunk4645KBSE_cjs.UnionStackClient(cfg),
|
|
32
32
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
33
33
|
[cfg.apiKey, cfg.chunkSize]
|
|
34
34
|
);
|
package/dist/react.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { U as UnionStackClient, P as PickerOptions } from './client-
|
|
3
|
-
export { b as PickerBranding, a as PickerHandle, c as PickerTheme } from './client-
|
|
4
|
-
import { C as ClientConfig, e as UploadedFile, a as PickedFile, U as UploadError, B as BatchUploadOptions, P as PickResponse } from './types-
|
|
5
|
-
export { b as ProgressEvent, c as UploadErrorCode, d as UploadOptions } from './types-
|
|
2
|
+
import { U as UnionStackClient, P as PickerOptions } from './client-C_pEvbZS.cjs';
|
|
3
|
+
export { b as PickerBranding, a as PickerHandle, c as PickerTheme } from './client-C_pEvbZS.cjs';
|
|
4
|
+
import { C as ClientConfig, e as UploadedFile, a as PickedFile, U as UploadError, B as BatchUploadOptions, P as PickResponse } from './types-BsGu9Oi3.cjs';
|
|
5
|
+
export { b as ProgressEvent, c as UploadErrorCode, d as UploadOptions } from './types-BsGu9Oi3.cjs';
|
|
6
6
|
|
|
7
7
|
interface UnionStackProviderProps extends ClientConfig {
|
|
8
8
|
children: React.ReactNode;
|
package/dist/react.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { U as UnionStackClient, P as PickerOptions } from './client-
|
|
3
|
-
export { b as PickerBranding, a as PickerHandle, c as PickerTheme } from './client-
|
|
4
|
-
import { C as ClientConfig, e as UploadedFile, a as PickedFile, U as UploadError, B as BatchUploadOptions, P as PickResponse } from './types-
|
|
5
|
-
export { b as ProgressEvent, c as UploadErrorCode, d as UploadOptions } from './types-
|
|
2
|
+
import { U as UnionStackClient, P as PickerOptions } from './client-BofkorBV.js';
|
|
3
|
+
export { b as PickerBranding, a as PickerHandle, c as PickerTheme } from './client-BofkorBV.js';
|
|
4
|
+
import { C as ClientConfig, e as UploadedFile, a as PickedFile, U as UploadError, B as BatchUploadOptions, P as PickResponse } from './types-BsGu9Oi3.js';
|
|
5
|
+
export { b as ProgressEvent, c as UploadErrorCode, d as UploadOptions } from './types-BsGu9Oi3.js';
|
|
6
6
|
|
|
7
7
|
interface UnionStackProviderProps extends ClientConfig {
|
|
8
8
|
children: React.ReactNode;
|
package/dist/react.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { UnionStackClient } from './chunk-
|
|
2
|
-
import './chunk-
|
|
3
|
-
import './chunk-
|
|
1
|
+
import { UnionStackClient } from './chunk-QQFNG3ZF.js';
|
|
2
|
+
import './chunk-RYS4MXXL.js';
|
|
3
|
+
import './chunk-G2H5WZDV.js';
|
|
4
4
|
import * as React3 from 'react';
|
|
5
5
|
|
|
6
6
|
var UnionStackContext = React3.createContext(null);
|
|
@@ -5,6 +5,8 @@ interface UploadError {
|
|
|
5
5
|
status?: number;
|
|
6
6
|
/** True if a retry has a reasonable chance of succeeding. */
|
|
7
7
|
retryable: boolean;
|
|
8
|
+
/** Docs deep-link to the fix for this error, when the API provides one. */
|
|
9
|
+
docs?: string;
|
|
8
10
|
/** Raw error from fetch / server (debugging only — don't display). */
|
|
9
11
|
cause?: unknown;
|
|
10
12
|
}
|
|
@@ -5,6 +5,8 @@ interface UploadError {
|
|
|
5
5
|
status?: number;
|
|
6
6
|
/** True if a retry has a reasonable chance of succeeding. */
|
|
7
7
|
retryable: boolean;
|
|
8
|
+
/** Docs deep-link to the fix for this error, when the API provides one. */
|
|
9
|
+
docs?: string;
|
|
8
10
|
/** Raw error from fetch / server (debugging only — don't display). */
|
|
9
11
|
cause?: unknown;
|
|
10
12
|
}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts"],"names":[],"mappings":";;;AAMO,IAAM,kBAAA,GACX;AAGK,SAAS,SAAA,CACd,IAAA,EACA,OAAA,EACA,IAAA,GAAkE,EAAC,EACtD;AACb,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,WAAW,IAAA,CAAK,SAAA,IAAa,gBAAA,CAAiB,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,IAC/D,OAAO,IAAA,CAAK;AAAA,GACd;AACF;AAEA,SAAS,gBAAA,CAAiB,MAAuB,MAAA,EAA0B;AACzE,EAAA,IAAI,IAAA,KAAS,SAAA,IAAa,IAAA,KAAS,aAAA,EAAe,OAAO,IAAA;AACzD,EAAA,IAAI,IAAA,KAAS,QAAA,IAAY,MAAA,IAAU,MAAA,IAAU,KAAK,OAAO,IAAA;AACzD,EAAA,OAAO,KAAA;AACT;AAGO,SAAS,eAAA,CAAgB,QAAgB,IAAA,EAA4B;AAC1E,EAAA,MAAM,MAAO,IAAA,EAAiE,KAAA;AAC9E,EAAA,MAAM,GAAA,GAAM,GAAA,EAAK,OAAA,IAAW,CAAA,2BAAA,EAA8B,MAAM,CAAA,CAAA;AAChE,EAAA,MAAM,IAAA,GAAA,CAAQ,GAAA,EAAK,IAAA,IAAQ,EAAA,EAAI,WAAA,EAAY;AAE3C,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,UAAU,MAAA,EAAQ,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAC5D;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,UAAU,MAAA,EAAQ,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAC5D;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,UAAU,YAAA,EAAc,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,UAAU,YAAA,EAAc,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAKlB,IAAA,IAAI,SAAS,cAAA,EAAgB;AAC3B,MAAA,OAAO,UAAU,YAAA,EAAc,kBAAA,EAAoB,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,IACjF;AACA,IAAA,OAAO,UAAU,YAAA,EAAc,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAGlB,IAAA,OAAO,UAAU,QAAA,EAAU,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAC9D;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,MAAM,UAAU,IAAA,KAAS,gBAAA;AACzB,IAAA,OAAO,SAAA,CAAU,OAAA,GAAU,OAAA,GAAU,SAAA,EAAW,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,CAAC,OAAA,EAAS,CAAA;AAAA,EACtF;AACA,EAAA,IAAI,UAAU,GAAA,EAAK;AACjB,IAAA,OAAO,UAAU,QAAA,EAAU,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,MAAM,CAAA;AAAA,EAC7D;AACA,EAAA,OAAO,UAAU,QAAA,EAAU,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAC9D","file":"chunk-GTE65IAM.cjs","sourcesContent":["import type { UploadError, UploadErrorCode } from './types.js';\n\n// Single source of truth for the 0-byte message. Used by the client-side guard\n// (uploader), the picker UI, and the server-side reject (mapped from a 422\n// EMPTY_UPLOAD), so the end user sees the same actionable text no matter where\n// the empty file was caught.\nexport const EMPTY_FILE_MESSAGE =\n \"This file is empty (0 bytes) and can't be uploaded. If it's stored in iCloud, \" +\n 'OneDrive, or Google Drive, open it once to download it to this device, then try again.';\n\nexport function makeError(\n code: UploadErrorCode,\n message: string,\n opts: { status?: number; retryable?: boolean; cause?: unknown } = {}\n): UploadError {\n return {\n code,\n message,\n status: opts.status,\n retryable: opts.retryable ?? defaultRetryable(code, opts.status),\n cause: opts.cause,\n };\n}\n\nfunction defaultRetryable(code: UploadErrorCode, status?: number): boolean {\n if (code === 'NETWORK' || code === 'PART_FAILED') return true;\n if (code === 'SERVER' && status && status >= 500) return true;\n return false;\n}\n\n/** Map an HTTP error response from the cdn-be API to an UploadError. */\nexport function fromApiResponse(status: number, body: unknown): UploadError {\n const err = (body as { error?: { code?: string; message?: string } } | null)?.error;\n const msg = err?.message || `Request failed with status ${status}`;\n const code = (err?.code || '').toUpperCase();\n\n if (status === 401) {\n return makeError('AUTH', msg, { status, retryable: false });\n }\n if (status === 403) {\n return makeError('AUTH', msg, { status, retryable: false });\n }\n if (status === 413) {\n return makeError('VALIDATION', msg, { status, retryable: false });\n }\n if (status === 415) {\n return makeError('VALIDATION', msg, { status, retryable: false });\n }\n if (status === 422) {\n // Server rejected the assembled object. EMPTY_UPLOAD (0 bytes landed) gets\n // the dedicated code + canonical message so it reads the same as a\n // client-side empty catch; other 422s fall back to VALIDATION. Either way,\n // retrying the same source file won't help, so it's not retryable.\n if (code === 'EMPTY_UPLOAD') {\n return makeError('EMPTY_FILE', EMPTY_FILE_MESSAGE, { status, retryable: false });\n }\n return makeError('VALIDATION', msg, { status, retryable: false });\n }\n if (status === 426) {\n // Server-enforced minimum SDK version. Not retryable — the integrator\n // must upgrade the package (or reload, for script-loader users).\n return makeError('CONFIG', msg, { status, retryable: false });\n }\n if (status === 429) {\n const isQuota = code === 'QUOTA_EXCEEDED';\n return makeError(isQuota ? 'QUOTA' : 'NETWORK', msg, { status, retryable: !isQuota });\n }\n if (status >= 500) {\n return makeError('SERVER', msg, { status, retryable: true });\n }\n return makeError('SERVER', msg, { status, retryable: false });\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts"],"names":[],"mappings":";AAMO,IAAM,kBAAA,GACX;AAGK,SAAS,SAAA,CACd,IAAA,EACA,OAAA,EACA,IAAA,GAAkE,EAAC,EACtD;AACb,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,WAAW,IAAA,CAAK,SAAA,IAAa,gBAAA,CAAiB,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,IAC/D,OAAO,IAAA,CAAK;AAAA,GACd;AACF;AAEA,SAAS,gBAAA,CAAiB,MAAuB,MAAA,EAA0B;AACzE,EAAA,IAAI,IAAA,KAAS,SAAA,IAAa,IAAA,KAAS,aAAA,EAAe,OAAO,IAAA;AACzD,EAAA,IAAI,IAAA,KAAS,QAAA,IAAY,MAAA,IAAU,MAAA,IAAU,KAAK,OAAO,IAAA;AACzD,EAAA,OAAO,KAAA;AACT;AAGO,SAAS,eAAA,CAAgB,QAAgB,IAAA,EAA4B;AAC1E,EAAA,MAAM,MAAO,IAAA,EAAiE,KAAA;AAC9E,EAAA,MAAM,GAAA,GAAM,GAAA,EAAK,OAAA,IAAW,CAAA,2BAAA,EAA8B,MAAM,CAAA,CAAA;AAChE,EAAA,MAAM,IAAA,GAAA,CAAQ,GAAA,EAAK,IAAA,IAAQ,EAAA,EAAI,WAAA,EAAY;AAE3C,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,UAAU,MAAA,EAAQ,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAC5D;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,UAAU,MAAA,EAAQ,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAC5D;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,UAAU,YAAA,EAAc,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,UAAU,YAAA,EAAc,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAKlB,IAAA,IAAI,SAAS,cAAA,EAAgB;AAC3B,MAAA,OAAO,UAAU,YAAA,EAAc,kBAAA,EAAoB,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,IACjF;AACA,IAAA,OAAO,UAAU,YAAA,EAAc,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAGlB,IAAA,OAAO,UAAU,QAAA,EAAU,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,EAC9D;AACA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,MAAM,UAAU,IAAA,KAAS,gBAAA;AACzB,IAAA,OAAO,SAAA,CAAU,OAAA,GAAU,OAAA,GAAU,SAAA,EAAW,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,CAAC,OAAA,EAAS,CAAA;AAAA,EACtF;AACA,EAAA,IAAI,UAAU,GAAA,EAAK;AACjB,IAAA,OAAO,UAAU,QAAA,EAAU,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,MAAM,CAAA;AAAA,EAC7D;AACA,EAAA,OAAO,UAAU,QAAA,EAAU,GAAA,EAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAC9D","file":"chunk-XBQENFBZ.js","sourcesContent":["import type { UploadError, UploadErrorCode } from './types.js';\n\n// Single source of truth for the 0-byte message. Used by the client-side guard\n// (uploader), the picker UI, and the server-side reject (mapped from a 422\n// EMPTY_UPLOAD), so the end user sees the same actionable text no matter where\n// the empty file was caught.\nexport const EMPTY_FILE_MESSAGE =\n \"This file is empty (0 bytes) and can't be uploaded. If it's stored in iCloud, \" +\n 'OneDrive, or Google Drive, open it once to download it to this device, then try again.';\n\nexport function makeError(\n code: UploadErrorCode,\n message: string,\n opts: { status?: number; retryable?: boolean; cause?: unknown } = {}\n): UploadError {\n return {\n code,\n message,\n status: opts.status,\n retryable: opts.retryable ?? defaultRetryable(code, opts.status),\n cause: opts.cause,\n };\n}\n\nfunction defaultRetryable(code: UploadErrorCode, status?: number): boolean {\n if (code === 'NETWORK' || code === 'PART_FAILED') return true;\n if (code === 'SERVER' && status && status >= 500) return true;\n return false;\n}\n\n/** Map an HTTP error response from the cdn-be API to an UploadError. */\nexport function fromApiResponse(status: number, body: unknown): UploadError {\n const err = (body as { error?: { code?: string; message?: string } } | null)?.error;\n const msg = err?.message || `Request failed with status ${status}`;\n const code = (err?.code || '').toUpperCase();\n\n if (status === 401) {\n return makeError('AUTH', msg, { status, retryable: false });\n }\n if (status === 403) {\n return makeError('AUTH', msg, { status, retryable: false });\n }\n if (status === 413) {\n return makeError('VALIDATION', msg, { status, retryable: false });\n }\n if (status === 415) {\n return makeError('VALIDATION', msg, { status, retryable: false });\n }\n if (status === 422) {\n // Server rejected the assembled object. EMPTY_UPLOAD (0 bytes landed) gets\n // the dedicated code + canonical message so it reads the same as a\n // client-side empty catch; other 422s fall back to VALIDATION. Either way,\n // retrying the same source file won't help, so it's not retryable.\n if (code === 'EMPTY_UPLOAD') {\n return makeError('EMPTY_FILE', EMPTY_FILE_MESSAGE, { status, retryable: false });\n }\n return makeError('VALIDATION', msg, { status, retryable: false });\n }\n if (status === 426) {\n // Server-enforced minimum SDK version. Not retryable — the integrator\n // must upgrade the package (or reload, for script-loader users).\n return makeError('CONFIG', msg, { status, retryable: false });\n }\n if (status === 429) {\n const isQuota = code === 'QUOTA_EXCEEDED';\n return makeError(isQuota ? 'QUOTA' : 'NETWORK', msg, { status, retryable: !isQuota });\n }\n if (status >= 500) {\n return makeError('SERVER', msg, { status, retryable: true });\n }\n return makeError('SERVER', msg, { status, retryable: false });\n}\n"]}
|