@pipelex/sdk 0.23.0 → 0.25.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/dist/artifacts.d.ts +4 -1
- package/dist/artifacts.js +6 -1
- package/dist/artifacts.js.map +1 -1
- package/dist/client.d.ts +7 -13
- package/dist/client.js +15 -16
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +30 -5
- package/dist/errors.js +9 -5
- package/dist/errors.js.map +1 -1
- package/dist/hooks/check-core.d.ts +97 -8
- package/dist/hooks/check-core.js +164 -15
- package/dist/hooks/check-core.js.map +1 -1
- package/dist/hooks/claude-mthds-check.d.ts +9 -1
- package/dist/hooks/claude-mthds-check.js +48 -31
- package/dist/hooks/claude-mthds-check.js.map +1 -1
- package/dist/hooks/patch-envelope.d.ts +66 -0
- package/dist/hooks/patch-envelope.js +127 -0
- package/dist/hooks/patch-envelope.js.map +1 -0
- package/dist/hooks/shell-script.d.ts +92 -0
- package/dist/hooks/shell-script.js +1304 -0
- package/dist/hooks/shell-script.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js.map +1 -1
- package/dist/product-models.d.ts +1 -9
- package/dist/product-models.js +1 -1
- package/dist/runs.d.ts +10 -1
- package/dist/runs.js +17 -1
- package/dist/runs.js.map +1 -1
- package/dist/timers.d.ts +11 -0
- package/dist/timers.js +14 -0
- package/dist/timers.js.map +1 -0
- package/dist/upload-grant.d.ts +38 -15
- package/dist/upload-grant.js +200 -67
- package/dist/upload-grant.js.map +1 -1
- package/dist/upload.js +9 -2
- package/dist/upload.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/architecture.md +4 -4
- package/docs/artifact-download.md +1 -1
- package/docs/hook-bundle.md +88 -0
- package/docs/input-preparation.md +14 -8
- package/package.json +2 -2
package/dist/upload-grant.js
CHANGED
|
@@ -7,13 +7,29 @@
|
|
|
7
7
|
*
|
|
8
8
|
* **This module is the browser-safe entry, `@pipelex/sdk/upload`.** Its runtime
|
|
9
9
|
* import graph must never reach a Node builtin, `undici` or the client: a page
|
|
10
|
-
* bundles it as is, with nothing marked external. It imports the error classes
|
|
11
|
-
*
|
|
12
|
-
* browser with esbuild to hold it
|
|
10
|
+
* bundles it as is, with nothing marked external. It imports the error classes,
|
|
11
|
+
* the timer bound in `timers.ts` and the wire types only, and
|
|
12
|
+
* `tests/upload-grant.test.ts` bundles it for the browser with esbuild to hold it
|
|
13
|
+
* to that.
|
|
13
14
|
*/
|
|
14
|
-
import { RejectedAssetError, UploadTransportError } from "./errors.js";
|
|
15
|
+
import { InputPreparationError, RejectedAssetError, UploadTransportError } from "./errors.js";
|
|
16
|
+
import { MAX_TIMER_DELAY_MS, isTimerDelay } from "./timers.js";
|
|
15
17
|
// The classes `uploadWithGrant` raises, so a page can branch on them without the main entry.
|
|
16
18
|
export { InputPreparationError, RejectedAssetError, UploadTransportError } from "./errors.js";
|
|
19
|
+
/**
|
|
20
|
+
* The default time limit on the `PUT`: a minute to open the exchange and hear back,
|
|
21
|
+
* plus a second for every started 128 KiB of the file, about 1 Mbit/s — 460 s at the
|
|
22
|
+
* 50 MiB cap. The grant's expiry bounds nothing here: storage checks the signature
|
|
23
|
+
* when the request starts, not when it ends.
|
|
24
|
+
*/
|
|
25
|
+
const DEFAULT_TIMEOUT_BASE_MS = 60_000;
|
|
26
|
+
const DEFAULT_TIMEOUT_BYTES_PER_SECOND = 128 * 1024;
|
|
27
|
+
/**
|
|
28
|
+
* How much of storage's error body is read. S3 writes `<Code>` and `<Message>` first,
|
|
29
|
+
* and the longest document this meets, a signature mismatch echoing the canonical
|
|
30
|
+
* request, runs to a few kilobytes after them.
|
|
31
|
+
*/
|
|
32
|
+
const ERROR_BODY_MAX_BYTES = 16 * 1024;
|
|
17
33
|
/**
|
|
18
34
|
* `PUT` a file to storage with an upload grant, and return the reference it now
|
|
19
35
|
* carries. The file goes as the raw body with the grant's signed headers
|
|
@@ -30,85 +46,202 @@ export { InputPreparationError, RejectedAssetError, UploadTransportError } from
|
|
|
30
46
|
* (`unsigned_header`), or when the grant has expired (`grant_expired`); any other
|
|
31
47
|
* `4xx` (`store_refused`). Each asks for a new grant, or for the file the grant
|
|
32
48
|
* was requested for.
|
|
33
|
-
* - `UploadTransportError` (`status` is storage's when it answered
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
49
|
+
* - `UploadTransportError` (`status` is storage's when it answered, `code` says
|
|
50
|
+
* which) — the time limit running out (`timeout`), storage unreachable
|
|
51
|
+
* (`unreachable`), a `5xx` (`server_error`), storage timing out on the body
|
|
52
|
+
* (`storage_timeout`, a `400 RequestTimeout`, which wrote nothing), another upload
|
|
53
|
+
* with the same grant still in progress (`conflict`, a `409
|
|
54
|
+
* ConditionalRequestConflict`), or a redirect, which is refused rather than
|
|
55
|
+
* followed (`redirected`). In a browser a refused cross-origin request looks like
|
|
56
|
+
* an unreachable host, so the message names that too. A grant whose `url` is not
|
|
57
|
+
* an absolute `http(s)` URL free of user info is refused the same way, before
|
|
58
|
+
* anything is sent (`invalid_grant_url`).
|
|
59
|
+
*
|
|
60
|
+
* The whole exchange runs under a time limit: `timeoutMs` when given, else 60 s plus
|
|
61
|
+
* 1 s for every started 128 KiB of the file. A caller's `signal` can end it sooner,
|
|
62
|
+
* and its abort propagates as the signal's own reason, unwrapped, even when the time
|
|
63
|
+
* limit ran out too. Only the first 16 KiB of storage's error body are read, and when
|
|
64
|
+
* the limit runs out while that body is still arriving, storage has already answered:
|
|
65
|
+
* the call settles as that answer, classified from its status and whatever part of the
|
|
66
|
+
* body arrived.
|
|
39
67
|
*
|
|
40
|
-
* A `5xx
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
68
|
+
* A timeout, a `5xx`, a conflict and a connection lost after the file went out leave
|
|
69
|
+
* it unknown whether the object was written: retrying with the same grant before it
|
|
70
|
+
* expires either stores it or answers the `412` of a used grant, and then the
|
|
71
|
+
* grant's `uri` already names the file. The grant is a bearer capability: nothing
|
|
72
|
+
* here logs it, and no error this throws carries its URL, storage's error body or a
|
|
44
73
|
* runtime error that could hold either.
|
|
45
74
|
*/
|
|
46
75
|
export async function uploadWithGrant(grant, file, options = {}) {
|
|
47
76
|
const label = fileLabel(grant, file);
|
|
48
|
-
const { signal } = options;
|
|
49
|
-
// A caller's abort wins over a grant this would refuse, as it does over a
|
|
77
|
+
const { signal, timeoutMs } = options;
|
|
78
|
+
// A caller's abort wins over a grant or an option this would refuse, as it does over a
|
|
79
|
+
// failed request.
|
|
50
80
|
if (signal?.aborted)
|
|
51
81
|
throw signal.reason;
|
|
82
|
+
if (timeoutMs !== undefined)
|
|
83
|
+
requireTimeout(timeoutMs);
|
|
84
|
+
const limitMs = timeoutMs ?? defaultTimeoutMs(file.size);
|
|
52
85
|
const target = storageTarget(grant, label);
|
|
53
|
-
|
|
86
|
+
// The call's own controller carries both ways the exchange can be cut short: the
|
|
87
|
+
// caller's signal, forwarded into it, and the time limit, which also covers reading
|
|
88
|
+
// storage's error body.
|
|
89
|
+
const controller = new AbortController();
|
|
90
|
+
let timedOut = false;
|
|
91
|
+
const timer = setTimeout(() => {
|
|
92
|
+
timedOut = true;
|
|
93
|
+
controller.abort(new DOMException("The upload timed out.", "TimeoutError"));
|
|
94
|
+
}, limitMs);
|
|
95
|
+
const onCallerAbort = () => controller.abort(signal?.reason);
|
|
96
|
+
signal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
54
97
|
try {
|
|
55
|
-
response
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
98
|
+
let response;
|
|
99
|
+
try {
|
|
100
|
+
response = await fetch(grant.url, {
|
|
101
|
+
method: "PUT",
|
|
102
|
+
headers: grant.headers,
|
|
103
|
+
body: file,
|
|
104
|
+
// A presigned URL signs its host, so a redirect could never succeed; refusing
|
|
105
|
+
// it keeps the file from being sent anywhere the grant did not name.
|
|
106
|
+
redirect: "manual",
|
|
107
|
+
signal: controller.signal,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
// The signals' outcome, not the runtime's error: some runtimes reject with a generic
|
|
112
|
+
// AbortError instead of the reason. A caller's abort wins over the time limit, since
|
|
113
|
+
// it is the one the caller can see and act on.
|
|
114
|
+
if (signal?.aborted)
|
|
115
|
+
throw signal.reason;
|
|
116
|
+
if (timedOut)
|
|
117
|
+
throw timeoutError(label, limitMs, grant);
|
|
118
|
+
// Neither the runtime's message nor the error itself is kept: either can carry the
|
|
119
|
+
// request URL, and with it the grant's credential (Bun puts it on the error's `path`).
|
|
120
|
+
throw new UploadTransportError(`Upload of "${label}" could not reach storage at ${target.origin} ` +
|
|
121
|
+
`(${describeNetworkFailure(error)}). In a browser, a refused cross-origin request ` +
|
|
122
|
+
"looks the same: check that the page may connect to the storage origin (its CSP " +
|
|
123
|
+
"connect-src). If the connection failed after the file went out, storage may have " +
|
|
124
|
+
`stored it anyway. ${sameGrantRetry(grant)}`, { code: "unreachable" });
|
|
125
|
+
}
|
|
126
|
+
// A body is cancelled, never awaited: a stream's cancel can outlive any time limit.
|
|
127
|
+
if (response.status >= 200 && response.status < 300) {
|
|
128
|
+
void response.body?.cancel().catch(() => undefined);
|
|
129
|
+
return { uri: grant.uri };
|
|
130
|
+
}
|
|
131
|
+
// A browser reports a refused redirect as an opaque response with status 0.
|
|
132
|
+
if (response.type === "opaqueredirect" || (response.status >= 300 && response.status < 400)) {
|
|
133
|
+
void response.body?.cancel().catch(() => undefined);
|
|
134
|
+
throw new UploadTransportError(`Upload of "${label}" was redirected by storage, and the redirect was refused: a ` +
|
|
135
|
+
"presigned upload is valid only at the URL it was signed for.",
|
|
136
|
+
// A refused redirect in a browser is opaque, with status 0: no status reached us.
|
|
137
|
+
{ status: response.status || undefined, code: "redirected" });
|
|
138
|
+
}
|
|
139
|
+
// Only the error's code and message are kept, never the body: S3 echoes the
|
|
140
|
+
// canonical request on a signature mismatch, and with it the grant's credential.
|
|
141
|
+
const body = await readErrorPrefix(response, ERROR_BODY_MAX_BYTES, controller.signal);
|
|
142
|
+
// A caller's abort while the body streams stays the caller's, unwrapped. The time limit
|
|
143
|
+
// running out then is no timeout: storage has answered, and its status says what
|
|
144
|
+
// happened, read with whatever part of the body arrived.
|
|
68
145
|
if (signal?.aborted)
|
|
69
146
|
throw signal.reason;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
`
|
|
74
|
-
|
|
75
|
-
|
|
147
|
+
const refusal = parseStorageError(body);
|
|
148
|
+
const status = response.status;
|
|
149
|
+
if (status === 400 && refusal.code === "RequestTimeout") {
|
|
150
|
+
throw new UploadTransportError(`Upload of "${label}" timed out at storage (${describeStatus(response, refusal)}): ` +
|
|
151
|
+
"storage stopped waiting for the file's bytes and wrote nothing. Retry with the same " +
|
|
152
|
+
`grant before it expires at ${grant.expires_at}, or with a new one.`, { status, code: "storage_timeout" });
|
|
153
|
+
}
|
|
154
|
+
// S3 answers this when two create-only PUTs for one key overlap, and documents it as
|
|
155
|
+
// retryable: it says nothing about this file, so it is no refusal of it.
|
|
156
|
+
if (status === 409 && refusal.code === "ConditionalRequestConflict") {
|
|
157
|
+
throw new UploadTransportError(`Upload of "${label}" met another upload with the same grant still in progress at ` +
|
|
158
|
+
`storage (${describeStatus(response, refusal)}), so whether the file was stored is ` +
|
|
159
|
+
`unknown. Send a grant once at a time. ${sameGrantRetry(grant)}`, { status, code: "conflict" });
|
|
160
|
+
}
|
|
161
|
+
if (status >= 400 && status < 500) {
|
|
162
|
+
const { code, advice } = classifyRefusal(status, refusal, grant);
|
|
163
|
+
throw new RejectedAssetError(`Storage refused the upload of "${label}" (${describeStatus(response, refusal)}): ${advice}`, label, status, { code });
|
|
164
|
+
}
|
|
165
|
+
throw new UploadTransportError(`Upload of "${label}" failed at storage (${describeStatus(response, refusal)})` +
|
|
166
|
+
(refusal.message ? `: ${withoutFinalPeriod(refusal.message)}` : "") +
|
|
167
|
+
`. Whether the file was stored is unknown. ${sameGrantRetry(grant)}`, { status, code: status >= 500 ? "server_error" : "unexpected" });
|
|
76
168
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
169
|
+
finally {
|
|
170
|
+
clearTimeout(timer);
|
|
171
|
+
signal?.removeEventListener("abort", onCallerAbort);
|
|
80
172
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
173
|
+
}
|
|
174
|
+
/** The default time limit for a file of `size` bytes, capped at what a timer honours. */
|
|
175
|
+
function defaultTimeoutMs(size) {
|
|
176
|
+
const seconds = Math.ceil(size / DEFAULT_TIMEOUT_BYTES_PER_SECOND);
|
|
177
|
+
return Math.min(DEFAULT_TIMEOUT_BASE_MS + seconds * 1_000, MAX_TIMER_DELAY_MS);
|
|
178
|
+
}
|
|
179
|
+
/** A caller's `timeoutMs`, refused before anything is sent when no timer could honour it. */
|
|
180
|
+
function requireTimeout(timeoutMs) {
|
|
181
|
+
if (!isTimerDelay(timeoutMs)) {
|
|
182
|
+
throw new InputPreparationError(`"timeoutMs" must be a positive number no larger than ${MAX_TIMER_DELAY_MS}, got ` +
|
|
183
|
+
`${String(timeoutMs)}.`);
|
|
88
184
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
185
|
+
}
|
|
186
|
+
function timeoutError(label, limitMs, grant) {
|
|
187
|
+
return new UploadTransportError(`Upload of "${label}" did not finish within the ${formatSeconds(limitMs)} s allowed, so ` +
|
|
188
|
+
"whether storage stored the file is unknown. On a slow link, pass a longer timeoutMs. " +
|
|
189
|
+
sameGrantRetry(grant), { code: "timeout" });
|
|
190
|
+
}
|
|
191
|
+
/** What to do when the upload may have been stored: the grant itself tells, on a retry. */
|
|
192
|
+
function sameGrantRetry(grant) {
|
|
193
|
+
return (`Retrying with the same grant before it expires at ${grant.expires_at} either stores ` +
|
|
194
|
+
"the file or reports the grant as used, and then the grant's uri already names the file.");
|
|
195
|
+
}
|
|
196
|
+
function formatSeconds(ms) {
|
|
197
|
+
return String(Number((ms / 1_000).toFixed(3)));
|
|
198
|
+
}
|
|
199
|
+
/** A message whose own final period would double the one the sentence adds after it. */
|
|
200
|
+
function withoutFinalPeriod(message) {
|
|
201
|
+
return message.replace(/\.\s*$/, "");
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* The first `maxBytes` of storage's error body as text: whatever arrived before the body
|
|
205
|
+
* ended, failed, reached the cap or was cut short by `abort`, since even a partial body
|
|
206
|
+
* may carry S3's code. The rest is cancelled unread, and the cancellation is never
|
|
207
|
+
* awaited, since a stream's cancel can outlive any time limit.
|
|
208
|
+
*/
|
|
209
|
+
async function readErrorPrefix(response, maxBytes, abort) {
|
|
210
|
+
if (response.body === null)
|
|
96
211
|
return "";
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
212
|
+
const reader = response.body.getReader();
|
|
213
|
+
// Cancelled explicitly on abort, on top of the request's own abort, so a stalled body
|
|
214
|
+
// never holds the read past the time limit: a cancel ends a pending read at once.
|
|
215
|
+
const cancel = () => {
|
|
216
|
+
void reader.cancel().catch(() => undefined);
|
|
217
|
+
};
|
|
218
|
+
if (abort.aborted) {
|
|
219
|
+
cancel();
|
|
220
|
+
return "";
|
|
221
|
+
}
|
|
222
|
+
abort.addEventListener("abort", cancel, { once: true });
|
|
223
|
+
const decoder = new TextDecoder();
|
|
224
|
+
let text = "";
|
|
225
|
+
let received = 0;
|
|
226
|
+
try {
|
|
227
|
+
while (received < maxBytes) {
|
|
228
|
+
const chunk = await reader.read();
|
|
229
|
+
if (chunk.done)
|
|
230
|
+
break;
|
|
231
|
+
const bytes = chunk.value.subarray(0, maxBytes - received);
|
|
232
|
+
received += bytes.byteLength;
|
|
233
|
+
text += decoder.decode(bytes, { stream: true });
|
|
234
|
+
}
|
|
235
|
+
if (received >= maxBytes)
|
|
236
|
+
cancel();
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// The body failed mid-stream, or a runtime errored it on abort: what arrived stands.
|
|
104
240
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
throw new RejectedAssetError(`Storage refused the upload of "${label}" (${describeStatus(response, refusal)}): ${advice}`, label, status, { code });
|
|
241
|
+
finally {
|
|
242
|
+
abort.removeEventListener("abort", cancel);
|
|
108
243
|
}
|
|
109
|
-
|
|
110
|
-
(refusal.message ? `: ${refusal.message}` : "") +
|
|
111
|
-
". Retrying with the same grant either stores the file or reports the grant as used.", { status });
|
|
244
|
+
return text + decoder.decode();
|
|
112
245
|
}
|
|
113
246
|
/**
|
|
114
247
|
* The grant's URL, parsed before anything is sent. A runtime that cannot build a request
|
|
@@ -131,7 +264,7 @@ function storageTarget(grant, label) {
|
|
|
131
264
|
target.password !== "") {
|
|
132
265
|
throw new UploadTransportError(`Upload of "${label}" was not sent: the grant's url is not an absolute http(s) URL ` +
|
|
133
266
|
"free of user info, so it is not the one requestUploadGrant returned. Pass the grant " +
|
|
134
|
-
"on unchanged.");
|
|
267
|
+
"on unchanged.", { code: "invalid_grant_url" });
|
|
135
268
|
}
|
|
136
269
|
return target;
|
|
137
270
|
}
|
package/dist/upload-grant.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload-grant.js","sourceRoot":"","sources":["../src/upload-grant.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"upload-grant.js","sourceRoot":"","sources":["../src/upload-grant.ts"],"names":[],"mappings":"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"}
|
package/dist/upload.js
CHANGED
|
@@ -135,11 +135,17 @@ function mapUploadError(error, filename) {
|
|
|
135
135
|
return new UnsupportedUploadCapabilityError("The configured Pipelex deployment does not support file upload (no /v1/upload route). " +
|
|
136
136
|
"Upload is a hosted Pipelex capability.", { cause: error });
|
|
137
137
|
default:
|
|
138
|
-
return new UploadTransportError(`Upload of "${filename}" failed (${error.status}): ${error.serverMessage ?? error.statusText}.`, {
|
|
138
|
+
return new UploadTransportError(`Upload of "${filename}" failed (${error.status}): ${error.serverMessage ?? error.statusText}.`, {
|
|
139
|
+
cause: error,
|
|
140
|
+
status: error.status,
|
|
141
|
+
code: error.status >= 500 ? "server_error" : "unexpected",
|
|
142
|
+
});
|
|
139
143
|
}
|
|
140
144
|
}
|
|
141
145
|
if (error instanceof ApiUnreachableError) {
|
|
142
|
-
return new UploadTransportError(`Upload of "${filename}" could not reach the Pipelex API (${error.code ?? "unreachable"}).`,
|
|
146
|
+
return new UploadTransportError(`Upload of "${filename}" could not reach the Pipelex API (${error.code ?? "unreachable"}).`,
|
|
147
|
+
// The client's own request timeout surfaces as an unreachable host with this code.
|
|
148
|
+
{ cause: error, code: error.code === "ABORT_TIMEOUT" ? "timeout" : "unreachable" });
|
|
143
149
|
}
|
|
144
150
|
// Only errors thrown by the `client.upload()` call reach here — the local-source
|
|
145
151
|
// and asset-type failures are raised in `toAssetBytes`, before this try block. Any
|
|
@@ -149,6 +155,7 @@ function mapUploadError(error, filename) {
|
|
|
149
155
|
const detail = error instanceof Error ? error.message : String(error);
|
|
150
156
|
return new UploadTransportError(`Upload of "${filename}" failed unexpectedly: ${detail}.`, {
|
|
151
157
|
cause: error,
|
|
158
|
+
code: "unexpected",
|
|
152
159
|
});
|
|
153
160
|
}
|
|
154
161
|
//# sourceMappingURL=upload.js.map
|
package/dist/upload.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,gCAAgC,GACjC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAmCpE,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AACxD,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAEtC,MAAM,cAAc,GAA2B;IAC7C,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,YAAY;IACjB,GAAG,EAAE,UAAU;IACf,IAAI,EAAE,kBAAkB;CACzB,CAAC;AAEF,kEAAkE;AAClE,MAAM,UAAU,aAAa;IAC3B,OAAO,CACL,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAC5F,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;AACzC,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,oBAAoB,CAAC;IACxE,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAClD,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,oBAAoB,CAAC;AACrD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,uBAAuB,CAC/B,+BAA+B,IAAI,+CAA+C;YAChF,+FAA+F,EACjG,IAAI,CACL,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACtD,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,uBAAuB,CAC/B,+BAA+B,IAAI,MAAO,KAA2B,CAAC,IAAI,IAAI,YAAY,IAAI,EAC9F,IAAI,EACJ,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;AACH,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,aAAa,CAAC,KAAiB;IAC7C,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,kDAAkD;IACxE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,KAAK,EAAE,CAAC;QACzD,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AASD,6EAA6E;AAC7E,KAAK,UAAU,YAAY,CACzB,KAAsB,EACtB,OAA0B;IAE1B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC7F,CAAC;IACD,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,OAAO,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO,oBAAoB,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IACD,0DAA0D;IAC1D,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,IAAK,KAAc,CAAC,IAAI,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC;IACnE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAiB,EAAE,OAA0B;IACzE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,gBAAgB,CAAC;IACtD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC;AAC7F,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAA2B,EAC3B,KAAsB,EACtB,UAA6B,EAAE;IAE/B,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC5E,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,QAA2C,CAAC;IAChD,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;IAChF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;AAC7F,CAAC;AAED,sFAAsF;AACtF,SAAS,cAAc,CAAC,KAAc,EAAE,QAAgB;IACtD,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;QACtC,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;YACrB,KAAK,GAAG;gBACN,OAAO,IAAI,kBAAkB,CAC3B,wBAAwB,QAAQ,MAAM,KAAK,CAAC,aAAa,IAAI,sCAAsC,GAAG,EACtG,QAAQ,EACR,KAAK,CAAC,MAAM,EACZ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CACpC,CAAC;YACJ,KAAK,GAAG,CAAC;YACT,KAAK,GAAG;gBACN,OAAO,IAAI,yBAAyB,CAClC,cAAc,QAAQ,yBAAyB,KAAK,CAAC,MAAM,0CAA0C,EACrG,KAAK,CAAC,MAAM,EACZ,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;YACJ,KAAK,GAAG;gBACN,OAAO,IAAI,gCAAgC,CACzC,wFAAwF;oBACtF,wCAAwC,EAC1C,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;YACJ;gBACE,OAAO,IAAI,oBAAoB,CAC7B,cAAc,QAAQ,aAAa,KAAK,CAAC,MAAM,MAAM,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,UAAU,GAAG,EAC/F;oBACE,KAAK,EAAE,KAAK;oBACZ,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,IAAI,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY;iBAC1D,CACF,CAAC;QACN,CAAC;IACH,CAAC;IACD,IAAI,KAAK,YAAY,mBAAmB,EAAE,CAAC;QACzC,OAAO,IAAI,oBAAoB,CAC7B,cAAc,QAAQ,sCAAsC,KAAK,CAAC,IAAI,IAAI,aAAa,IAAI;QAC3F,mFAAmF;QACnF,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,EAAE,CACnF,CAAC;IACJ,CAAC;IACD,iFAAiF;IACjF,mFAAmF;IACnF,qFAAqF;IACrF,kFAAkF;IAClF,2EAA2E;IAC3E,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtE,OAAO,IAAI,oBAAoB,CAAC,cAAc,QAAQ,0BAA0B,MAAM,GAAG,EAAE;QACzF,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,YAAY;KACnB,CAAC,CAAC;AACL,CAAC"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/docs/architecture.md
CHANGED
|
@@ -32,7 +32,7 @@ The package is ESM-only (`"type": "module"`, `dist/index.js` built by `tsc` with
|
|
|
32
32
|
|
|
33
33
|
Condition order in `exports` matters: `types` is listed first (TS/Node resolution convention — the type-checker looks at the first matching condition), then `import`, then `default` as the CJS fallback.
|
|
34
34
|
|
|
35
|
-
The map has a second entry, **`@pipelex/sdk/upload`** (`dist/upload-grant.js`), the browser-safe one. The main entry is Node-first — `upload.ts` names `node:fs/promises` and `artifacts.ts` names `undici`, so a browser-targeting bundler must mark them external — because the client holds an API key and belongs on a server. The subpath carries only what a page needs to store a file with an upload grant: `uploadWithGrant`, the grant types and the three error classes it raises. Its runtime import graph is `errors.ts` and `mthds/protocol`, nothing else, and the unit suite bundles it for the browser with esbuild, nothing marked external, so a Node-only module becoming reachable fails a test rather than a consumer's build. Both entries load the same `dist/errors.js` and `dist/upload-grant.js`, so the function and the error classes are identical whichever entry a consumer imports them through. Whether the main entry should become browser-safe as a whole is a separate question, because it touches how path strings are read.
|
|
35
|
+
The map has a second entry, **`@pipelex/sdk/upload`** (`dist/upload-grant.js`), the browser-safe one. The main entry is Node-first — `upload.ts` names `node:fs/promises` and `artifacts.ts` names `undici`, so a browser-targeting bundler must mark them external — because the client holds an API key and belongs on a server. The subpath carries only what a page needs to store a file with an upload grant: `uploadWithGrant`, the grant types and the three error classes it raises. Its runtime import graph is `errors.ts`, `timers.ts` and `mthds/protocol`, nothing else, and the unit suite bundles it for the browser with esbuild, nothing marked external, so a Node-only module becoming reachable fails a test rather than a consumer's build. Both entries load the same `dist/errors.js` and `dist/upload-grant.js`, so the function and the error classes are identical whichever entry a consumer imports them through. Whether the main entry should become browser-safe as a whole is a separate question, because it touches how path strings are read.
|
|
36
36
|
|
|
37
37
|
## Wire conventions
|
|
38
38
|
|
|
@@ -86,13 +86,14 @@ Flat `src/` (mirrors `mthds-js`'s `runners/api` flatness — the SDK has one cli
|
|
|
86
86
|
- `product-models.ts` — the snake_case wire shapes for the hosted-product management routes (profile, methods catalog, organizations, billing, API keys, gateway key, onboarding, storage, runs list/detail/update). Each interface models only the fields the product actually consumes — no speculative mirrors.
|
|
87
87
|
- `method-source.ts` — `methodSourceToContents`, the canonical parser turning a stored method's polymorphic `mthds` source (raw single-bundle text XOR a JSON `{name, content}[]` file array) into a flat list of file contents. A verbatim port of the platform's `_method_source_to_contents` so the SDK and runtime read a stored source identically; exported from the barrel and consumed by `getMethodClosure`. See [input-preparation.md](./input-preparation.md#getmethodclosure--the-explicit-expansion-utility).
|
|
88
88
|
- `codegen-check.ts` — `runCodegenCheck`, the **pure** offline drift check over a committed codegen tree: the stamp grammar, the `codegen.lock` parser, the hash, and the drift taxonomy, ported from pipelex's `codegen/check.py` so a verdict computed here equals the one `pipelex codegen check` computes over the same bytes (the drift `detail` sentences included, verbatim). It touches neither the client nor `mthds/protocol` — its only import is `smol-toml` — and it hashes through WebCrypto rather than `node:crypto` so it adds no Node builtin to the barrel's import graph (`upload.ts` still names `node:fs/promises`, so a browser-targeting bundler must mark `node:*` external). It raises `CodegenLockError`, which extends `Error` rather than the protocol base. No filesystem, no fetch, no API key — the caller walks its own tree and hands in the text. See [crate-routes.md](./crate-routes.md#the-offline-check--runcodegencheck).
|
|
89
|
-
- `upload-grant.ts` — `uploadWithGrant`, the sender of an upload grant (`requestUploadGrant`, `POST /v1/upload/grant`): the file as the raw body of a `PUT` to the grant's URL with its signed headers unchanged, redirects refused, and storage's refusals mapped onto the input-preparation errors (`RejectedAssetError` with a `code` for a `4xx` such as the `412` of a used grant or the `403` of a signature mismatch, `UploadTransportError` for a `5xx`, storage's `RequestTimeout`, a redirect or no response). It is the browser-safe `@pipelex/sdk/upload` entry, so it imports the error classes and the wire types only, never the client. See [input-preparation.md](./input-preparation.md#uploading-with-a-grant--requestuploadgrant--uploadwithgrant).
|
|
89
|
+
- `upload-grant.ts` — `uploadWithGrant`, the sender of an upload grant (`requestUploadGrant`, `POST /v1/upload/grant`): the file as the raw body of a `PUT` to the grant's URL with its signed headers unchanged, redirects refused, the whole exchange bounded by a time limit scaled by the file's size unless the caller passes `timeoutMs`, only the first 16 KiB of storage's error body read, and storage's refusals mapped onto the input-preparation errors (`RejectedAssetError` with a `code` for a `4xx` such as the `412` of a used grant or the `403` of a signature mismatch, `UploadTransportError` with a `code` for the time limit running out, a `5xx`, storage's `RequestTimeout`, a `409` conflict, a redirect or no response). It is the browser-safe `@pipelex/sdk/upload` entry, so it imports the error classes, the timer bound in `timers.ts` and the wire types only, never the client. See [input-preparation.md](./input-preparation.md#uploading-with-a-grant--requestuploadgrant--uploadwithgrant).
|
|
90
90
|
- `artifacts.ts` — the artifact stack, the download twin of `prepareInputs`, in layers: `locateArtifacts` (a pure, exported walk for `pipelex-storage://` references, each with every `$`-rooted path it sits at) and `collectArtifacts` (the same walk's bare references), `resolveArtifacts` (the bulk resolve route over a whole list, chunked at its bound), `fetchArtifact` (one reference as a bounded `Response`) and `downloadArtifacts` (Node-only, a run's produced files saved under a directory as a produced verdict), plus `artifactFilename`, the rule that names a saved file after the field it fills. The three network operations are client methods over a small structural seam (`ArtifactCapableClient`: the raw `resolveStorageUrls` call and `getRunResult`); the module's static import graph stays free of Node builtins, because `node:fs/promises`, `node:path` and `undici` are loaded by dynamic import behind `isNodeRuntime()` — a browser-targeting bundler still has to mark `node:*` and `undici` external, as it already must for `upload.ts`. `undici` is a runtime dependency for one reason: the fetch runs on an `Agent` carrying `headersTimeout` and `bodyTimeout`, the per-stall bounds an `AbortSignal` budget does not give, and Node exposes its bundled undici's `fetch` but not its `Agent`. See [artifact-download.md](./artifact-download.md).
|
|
91
91
|
- `runs.ts` — the run-lifecycle types (`RunStatus`, `RunRead`, `RunResults`, `RunResultState`) and the single poll loop (`pollUntilResult`). `RunResults.main_stuff` (the resolved main output content) is always present for a completed run: on the hosted path it is the `main_stuff.json` S3 artifact; on the bare-runner blocking path the SDK resolves it from the returned working memory via the response's `main_stuff_name`, so both paths deliver the same shape. Consumers read `main_stuff` directly. `working_memory` — every named stuff of the run, `{ root, aliases }`, typed `DictWorkingMemory` from `models.ts` — reads the same on both paths: the hosted path relays the `working_memory.json` artifact, and the blocking path lifts it off `pipe_output`, which still rides whole (blocking path only). `graph_spec` — the executed graph — also reaches the client on both paths: the hosted path relays the `graphspec.json` artifact, and the blocking path lifts it off `pipe_output` beside `graph_assembly_error`, the graph's twin of `usage_assembly_error`. That error field is declared ahead of the wire on the hosted side, where the platform's results body relays no such key and the field is therefore absent, reading `undefined` rather than `null`. A completed run that cannot deliver a main stuff throws `MissingMainStuffError`. `runs.ts` also owns `TokensUsageRecord` — one client-facing usage record per inference call, carried by `RunResults.tokens_usages` on both paths. That is a mirror of a wire contract this SDK does not own (inference accounting is a Pipelex runtime extension rather than part of the MTHDS standard): every field is optional and the interface carries an index signature so pre-contract artifacts (relayed verbatim, never migrated) still type-check. See [`run-usage.md`](./run-usage.md) for the field reference, the cost/null semantics, and the old-artifact rules, and [`run-results.md`](./run-results.md) for the field-by-field account of `RunResults` — the durable handle, the output and how to read it, the run's working memory, the executed graph and how to render or keep it, and the produced files with their short-lived links.
|
|
92
92
|
- `usage.ts` — `summarizeUsage`, the **pure** fold of a run's usage pair (`tokens_usages` / `usage_assembly_error`) into one `UsageSummary`: a `state` (`records`, `no_inference` or `unavailable`), the null-aware total cost with its `cost_partial` flag, the `input` and `output` token totals, the call count, the relayed assembly error, and a `by_pipe` rollup sorted by cost with the unattributed calls grouped under a `null` `pipe_code`. It applies the rules [`run-usage.md`](./run-usage.md#summarizing-a-run--summarizeusage) states, so that every consumer reads one computation rather than re-deriving those rules by hand. It imports types from `runs.ts` and nothing else: no client, no fetch, no `mthds/protocol`.
|
|
93
93
|
- `execute-result.ts` — `PipelexExecuteResult`, a `DictRunResultExecute` subtype that adds a resolved `.main_stuff` accessor (dug out of `pipe_output`'s working memory via the response's `main_stuff_name`, throwing `MissingMainStuffError` if unlocatable). `execute()` returns it, giving blocking and durable results the **same output accessor** — `result.main_stuff` — so callers never branch on which path ran. The neutral `mthds` wire model leaves `main_stuff_name` in its extension index signature; this Pipelex-branded subtype declares it as a typed field (Pipelex owns that concept). `resultsFromExecute` (the public lift from that result onto `RunResults`, in the same module) reads that accessor too, keeping the resolution single-sourced; the `executeBlocking` fallback is its only caller inside the SDK, and a consumer driving `execute()` directly calls it by name.
|
|
94
94
|
- `errors.ts` — the transport and run-lifecycle typed errors, the input-preparation family under `InputPreparationError`, and the artifact family under `ArtifactOperationError` (`ScopeUnavailableError`, `ArtifactFetchError`, `ArtifactAuthenticationError`, the last carrying the download verdict so far); all derive from the protocol-base `PipelineRequestError` (re-exported from `mthds/protocol`) except `ClientAuthenticationError`. It is not the whole error surface: `codegen-check.ts` exports `CodegenLockError`, which extends plain `Error` because nothing was requested over the wire.
|
|
95
95
|
- `user-agent.ts` — client identification per the workspace spec `docs/specs/client-identification.md`: the exported `AppInfo` option, its RFC 9110 token validation (a `TypeError` on a bad field, a `RangeError` past the 512-character ceiling), its rendering, the runtime detection (Node, Bun, Deno, or a browser, where no header is set) and `buildUserAgent`, which the client calls once at construction. The client's private `requestHeaders` is the one place API request headers are built, so every route carries the value; the artifact fetch of a presigned link never goes through it. See [client-identification.md](./client-identification.md).
|
|
96
|
+
- `timers.ts` — `MAX_TIMER_DELAY_MS`, the longest delay `setTimeout` honours, and `isTimerDelay`, which every caller-supplied `timeoutMs` is checked against before it reaches a timer: a longer delay overflows and fires at once. It imports nothing, so the browser-safe upload entry uses it too.
|
|
96
97
|
- `version.ts` — `SDK_VERSION`, in its own module so the client stamps it on the `User-Agent` without importing the barrel, which re-exports it.
|
|
97
98
|
- `index.ts` — the public barrel: `export * from "mthds/protocol"` (single import source for the standard surface) plus the client, models, run types, the standalone pure helpers (`runCodegenCheck`, `summarizeUsage`, `locateArtifacts`, `collectArtifacts`, `artifactFilename`), and errors.
|
|
98
99
|
|
|
@@ -118,14 +119,13 @@ The hosted catalog/account routes the webapp drives. All ride the same `{base}/v
|
|
|
118
119
|
- **Organizations:** `listMemberships`, `createOrganization`, `renameOrganization` (`PATCH`). The org "switch" is a WorkOS-session op (`/api/active-org`), not a `/v1` route — out of SDK scope.
|
|
119
120
|
- **Billing:** `getSubscription`, `listPlans`, `listInvoices`, `createCheckout`, `changePlan` (409 `conflict` ⇒ no subscription), `getBillingPortal` (409 `conflict` ⇒ no subscription).
|
|
120
121
|
- **Pipelex API keys (`plx_sk_…`):** `listPipelexApiKeys`, `createPipelexApiKey` (409 `pipelex_api_key_limit_reached`), `revokePipelexApiKey`, `rotatePipelexApiKey`. The plaintext `api_key` is returned once, on create/rotate.
|
|
121
|
-
- **Gateway API key (LLM inference key):** `createGatewayApiKey` (the JSON body is always sent, even with `promo_code: null`), `getGatewayApiKey`.
|
|
122
122
|
- **Onboarding:** `submitOnboarding`.
|
|
123
123
|
- **Storage:** `resolveStorageUrl`, `resolveStorageUrls` (`POST /v1/resolve-storage-url/bulk` — the single route applied to a list of at most 100 references, one verdict per reference in request order, a refused reference a value on its item; a deployment without the route answers a `404` `ApiResponseError`), `upload` (JSON base64 — the multipart hop is browser→BFF only), `requestUploadGrant` (`POST /v1/upload/grant` — a presigned, create-only `PUT` for one new object, which the holder of the bytes sends with the standalone `uploadWithGrant`, also exported from the browser-safe `@pipelex/sdk/upload` entry; a declared size over the cap is a `413` `ApiResponseError`). The higher-level `uploadFile` / `prepareInputs` preparation surface is built on top of `upload`; `prepareInputs` additionally composes one `validate` call with `views: ["input_form"]` for the signature it walks, and takes the method as inline `files`, a `method_ref` or a `method_id` like every other method-taking operation — see [input-preparation.md](./input-preparation.md). The download twin — `locateArtifacts`, `collectArtifacts`, `resolveArtifacts`, `fetchArtifact`, `downloadArtifacts` — is built on top of `resolveStorageUrls` and `getRunResult`, never on the embedded `public_url`, and is documented on [artifact-download.md](./artifact-download.md); downloading is a separate explicit gesture, and no run call takes a `download` option.
|
|
124
124
|
- **Runs list/detail/update:** `listRuns` (by `method_id`) returns **one page**, not the whole history — a `RunPage` (`{items, nextCursor}`) served from a time-ordered index, so its cost is the page size rather than the size of the history. `iterateRuns` is the async iterator that follows the cursor for callers who genuinely want everything (`for await (const run of client.iterateRuns(id))`); it is deliberately not a `listAllRuns(): Promise<PipelineRun[]>`, because an all-at-once helper needs a page cap and a cap means silently returning a truncated list. Both accept `createdFrom` / `createdTo`, applied server-side as index key conditions — these are **instants, not days** (ISO-8601 with a UTC offset; a naive timestamp is a 400), because only the caller knows which timezone's day it means. `getRunDetail` (`GET /v1/runs/{id}`) is the only call returning `mthds_contents` — what the run actually executed — and `inputs`; it is kept off the status read that pollers hit every few seconds and off the list, where the bundle would be multiplied by the page size. `updateRun` is the admin/manual status patch. The status/results/start lifecycle routes live in the run-lifecycle section above.
|
|
125
125
|
|
|
126
126
|
## Hook bundle (`dist-hooks/check.mjs`)
|
|
127
127
|
|
|
128
|
-
`src/hooks/` holds the post-edit `.mthds` hook pipeline (local lint/format via `@pipelex/tools-wasm`, then a `POST /v1/validate` verdict through this SDK), bundled into a single dependency-free ESM file by `npm run build:hook`. Its validate client is built by `src/hooks/validate-client.ts` with `appInfo: { name: "pipelex-mthds-check", version: SDK_VERSION }`, the `hook` surface's registry token, so the platform attributes its calls to the hook rather than to a plain SDK caller. The one specifier left external is `undici`, reached only by the artifact fetch path through a dynamic import the hook never executes, so the bundle does not inline an HTTP client it cannot use. **Distribution is source-checkout vendoring, not npm:** `pipelex-plugins` runs `make vendor-hook`, which builds `dist-hooks/check.mjs` in a sibling checkout of this repo and copies it in as a static hook asset — the published `@pipelex/sdk` tarball deliberately does not ship the bundle (it inlines the ~4 MB WASM engine, and no npm consumer of the SDK's library API uses it). `dist-hooks/` is gitignored; the consumer repo's own checks gate a stale vendored copy.
|
|
128
|
+
`src/hooks/` holds the post-edit `.mthds` hook pipeline (local lint/format via `@pipelex/tools-wasm`, then a `POST /v1/validate` verdict through this SDK), bundled into a single dependency-free ESM file by `npm run build:hook`. Its validate client is built by `src/hooks/validate-client.ts` with `appInfo: { name: "pipelex-mthds-check", version: SDK_VERSION }`, the `hook` surface's registry token, so the platform attributes its calls to the hook rather than to a plain SDK caller. The one specifier left external is `undici`, reached only by the artifact fetch path through a dynamic import the hook never executes, so the bundle does not inline an HTTP client it cannot use. **Distribution is source-checkout vendoring, not npm:** `pipelex-plugins` runs `make vendor-hook`, which builds `dist-hooks/check.mjs` in a sibling checkout of this repo and copies it in as a static hook asset — the published `@pipelex/sdk` tarball deliberately does not ship the bundle (it inlines the ~4 MB WASM engine, and no npm consumer of the SDK's library API uses it). `dist-hooks/` is gitignored; the consumer repo's own checks gate a stale vendored copy. `@pipelex/tools-wasm` is pinned to an exact version in `package.json`, because the engine carries the MTHDS schema the hook lints against: a newer schema reaches the hook only by a deliberate bump followed by a rebuild and a re-vendor, and the bundle's provenance line (`@pipelex/sdk <version> (<commit>) + @pipelex/tools-wasm <version> (npm)`) names the engine it embeds. Which file the hook checks on each platform, and how it finds the file a Codex patch run through the shell wrote, is in [`hook-bundle.md`](./hook-bundle.md).
|
|
129
129
|
|
|
130
130
|
## Testing
|
|
131
131
|
|
|
@@ -74,7 +74,7 @@ export async function GET(request: Request, { params }: { params: { uri: string
|
|
|
74
74
|
|
|
75
75
|
Resolves the reference fresh and returns the object store's response as a bounded `Response`. The bounds:
|
|
76
76
|
|
|
77
|
-
- **A timeout** covering the connection, the headers and the whole body (`timeoutMs`, default 120 s). On Node the fetch also runs on an `undici` dispatcher carrying `headersTimeout` and `bodyTimeout` at the same value, the per-stall bounds an `AbortSignal` alone does not give.
|
|
77
|
+
- **A timeout** covering the connection, the headers and the whole body (`timeoutMs`, default 120 s). On Node the fetch also runs on an `undici` dispatcher carrying `headersTimeout` and `bodyTimeout` at the same value, the per-stall bounds an `AbortSignal` alone does not give. It must be a positive number no larger than 2147483647, the longest delay a timer honours, or the call throws an `ArtifactOperationError` before anything is resolved.
|
|
78
78
|
- **Redirects refused** (`redirect: "manual"`): a presigned link has no reason to redirect, and one that does is refused rather than followed.
|
|
79
79
|
- **The byte cap enforced mid-stream** (`maxBytes`, default 1 GiB): a declared `Content-Length` over the cap is refused before a byte is read, and a body that crosses the cap while streaming errors the returned stream — never buffered.
|
|
80
80
|
- **No credentials forwarded**: the request carries no headers of ours. The link's authorization is in its query string, and nothing else may ride along to the store.
|