@pipelex/sdk 0.49.0 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -12
- package/dist/cli/script.d.ts +1 -1
- package/dist/client.d.ts +253 -14
- package/dist/client.js +484 -21
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +9 -6
- package/dist/errors.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/product-models.d.ts +458 -20
- package/dist/upload-grant.d.ts +134 -40
- package/dist/upload-grant.js +328 -136
- package/dist/upload-grant.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/architecture.md +5 -5
- package/docs/errors.md +6 -2
- package/docs/files.md +173 -3
- package/docs/input-preparation.md +43 -19
- package/docs/method-examples.md +36 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -172,6 +172,15 @@ for await (const saved of client.iterateMethodExamples(created.method_id)) {
|
|
|
172
172
|
// a nextCursor; iterateFiles follows it.
|
|
173
173
|
const files = await client.listFiles({ q: "invoice", kind: "uploaded", format: ["pdf"] });
|
|
174
174
|
await client.start({ method_id: created.method_id, inputs: { invoice: { url: files.items[0]!.uri } } });
|
|
175
|
+
// One file with its uses, a link that downloads it under its name, and a zip of a run's files.
|
|
176
|
+
const fileDetail = await client.getFile(files.items[0]!.file_id);
|
|
177
|
+
for (const link of (await client.linkFiles([{ file_id: fileDetail.file_id }])).items) {
|
|
178
|
+
// A fifteen-minute link, or why this file got none. Hand link.url to a browser, never a log.
|
|
179
|
+
if (link.error === null) console.log(`${link.name} downloadable until ${link.expires_at}`);
|
|
180
|
+
else console.error(link.error.code);
|
|
181
|
+
}
|
|
182
|
+
const archive = await client.requestFileArchive({ run_id: run.pipeline_run_id });
|
|
183
|
+
// then getFileArchive(archive.archive_id) until its state is ready or failed.
|
|
175
184
|
// An upload recorded as a test file of the method it was made to try.
|
|
176
185
|
await client.uploadFile("cases/receipt.pdf", { kind: "test", method_id: created.method_id });
|
|
177
186
|
|
|
@@ -233,19 +242,18 @@ const client = new PipelexApiClient({ appInfo: { name: "acme-invoicer", version:
|
|
|
233
242
|
|
|
234
243
|
### Uploading from a browser
|
|
235
244
|
|
|
236
|
-
A browser page that holds a file but not the API key can still store it: the server that holds the key asks for an upload grant, and the page sends the file straight to storage with it. The file never crosses your server or the API gateway, so it can be as large as the service's own limit. The page imports `@pipelex/sdk/upload`, which carries only the grant's sender,
|
|
245
|
+
A browser page that holds a file but not the API key can still store it: the page describes the file, its SHA-256 included, the server that holds the key asks for an upload grant with that description, and the page sends the file straight to storage with it, unless the grant says your organization already holds those bytes, in which case nothing is sent at all. The file never crosses your server or the API gateway, so it can be as large as the service's own limit. The page imports `@pipelex/sdk/upload`, which carries only the description, the grant's sender, their types and their errors. Both entries bundle for the browser with nothing marked external, so a page may also import the main entry's error classes and types, while the client itself stays on the server that holds the key.
|
|
237
246
|
|
|
238
247
|
```ts
|
|
239
|
-
// On the server, which holds the key:
|
|
240
|
-
const grant = await client.requestUploadGrant({
|
|
241
|
-
filename: "report.pdf",
|
|
242
|
-
content_type: "application/pdf",
|
|
243
|
-
size: 48213,
|
|
244
|
-
});
|
|
245
|
-
|
|
246
248
|
// In the page, which holds the file:
|
|
247
|
-
import { uploadWithGrant } from "@pipelex/sdk/upload";
|
|
248
|
-
const
|
|
249
|
+
import { describeUpload, uploadWithGrant } from "@pipelex/sdk/upload";
|
|
250
|
+
const description = await describeUpload(file); // { filename, content_type, size, sha256 }
|
|
251
|
+
|
|
252
|
+
// On the server, which holds the key, given the description:
|
|
253
|
+
const grant = await client.requestUploadGrant(description); // { stored, uri, file_id, url, … }
|
|
254
|
+
|
|
255
|
+
// Back in the page, with the grant:
|
|
256
|
+
const { uri, file_id } = await uploadWithGrant(grant, file); // sends nothing when grant.stored
|
|
249
257
|
```
|
|
250
258
|
|
|
251
259
|
The full client surface is documented in [`docs/architecture.md`](./docs/architecture.md).
|
|
@@ -263,8 +271,8 @@ These pages ship inside the published package, so a reader who has only installe
|
|
|
263
271
|
| [`docs/artifact-download.md`](./docs/artifact-download.md) | Turning the `pipelex-storage://` references a run produced back into bytes: `locateArtifacts`, `collectArtifacts`, `resolveArtifacts`, `fetchArtifact`, `downloadArtifacts`, and how a saved file is named after the field it fills |
|
|
264
272
|
| [`docs/input-preparation.md`](./docs/input-preparation.md) | The other direction — `uploadFile` and `prepareInputs`, which turn local files into references a run can take, and the upload grant a browser page sends a file with |
|
|
265
273
|
| [`docs/method-trees.md`](./docs/method-trees.md) | A method's tree: the four forms a run, a validation, a save and the crate routes take it in (a directory on disk among them), how it travels inline or by hash and what is uploaded, the files a step reads, the template check's warnings and which step reads which file of the tree, the deployment's limits, the read's listing with its links, `writeMethodTree`, and `MethodFileTransferError` |
|
|
266
|
-
| [`docs/files.md`](./docs/files.md) | An organization's files: `listFiles` and `iterateFiles`, the row and its provenance, the query and its repeated filters, paging through filtered pages, and an upload recorded as a method's test file with the refusals that come with it |
|
|
267
|
-
| [`docs/method-examples.md`](./docs/method-examples.md) | A method's saved examples: the create, the paged list and its iterator, the edit that raises the input revision, the latest-run write and its `recorded` or `stale` verdict, how an integer past `Number.MAX_SAFE_INTEGER` in the inputs stays exact, and what is refused before sending |
|
|
274
|
+
| [`docs/files.md`](./docs/files.md) | An organization's files: `listFiles` and `iterateFiles`, the row, the whole record and its provenance, the query and its repeated filters, paging through filtered pages, one file and its uses, the records of an address, the rename rule, links that name the file, a zip of files and its caps, a run's files, the copy into a method's draft, and an upload recorded as a method's test file with the refusals that come with it |
|
|
275
|
+
| [`docs/method-examples.md`](./docs/method-examples.md) | A method's saved examples: the create, the paged list and its iterator, the edit that raises the input revision, the latest-run write and its `recorded` or `stale` verdict, the build assistant's save and its `kept` or `created` verdict, how an integer past `Number.MAX_SAFE_INTEGER` in the inputs stays exact, and what is refused before sending |
|
|
268
276
|
| [`docs/organization-branding.md`](./docs/organization-branding.md) | An organization's logos and colours: `getBranding`, which every member and API key reads, `updateOrganizationBranding`, an admin's write that sets, clears or keeps each key, and how a refused logo or colour names its slot in `errors` so a settings screen shows the sentence under it |
|
|
269
277
|
| [`docs/exact-integers.md`](./docs/exact-integers.md) | Which reads keep an integer past `Number.MAX_SAFE_INTEGER` exact, as a `bigint` (a run's inputs and outputs, an example's inputs), how a request body writes it back with its digits, and `parseExactJson` and `stringifyExactJson` for code showing such data as JSON text |
|
|
270
278
|
| [`docs/crate-routes.md`](./docs/crate-routes.md) | `resolve`, `codegen` and `pipeIo` — the method's tree as the protocol's `files` map, with its dependencies, the normalized crate, the stamped types, and a method's I/O artifacts without a validation — and the offline `runCodegenCheck` that guards a committed tree |
|
package/dist/cli/script.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ import type { CommandIO } from "./io.js";
|
|
|
15
15
|
* update notice and npm 12's run notices off the script's stderr, which carries the command's
|
|
16
16
|
* own lines, while npm's warnings and errors still print.
|
|
17
17
|
*/
|
|
18
|
-
export declare const SCRIPT_RUNNER = "npx --yes --no-update-notifier --loglevel=warn @pipelex/sdk@0.
|
|
18
|
+
export declare const SCRIPT_RUNNER = "npx --yes --no-update-notifier --loglevel=warn @pipelex/sdk@0.50.0";
|
|
19
19
|
export declare const SCRIPT_WRITER = "@pipelex/sdk";
|
|
20
20
|
export declare const SCRIPT_NEEDS = "Node 22.12 or later";
|
|
21
21
|
/** Run `pipelex-sdk script` and return its exit code. */
|
package/dist/client.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { MTHDSProtocol, ModelCategory, ModelDeck, RunOptions, StartOptions, VersionInfo } from "mthds/protocol";
|
|
2
2
|
import type { CodegenRequest, CodegenResponse, CrateRouteOptions, DictPipeOutput, FormatResponse, LintResponse, ModelCheckCategory, ModelReferenceVerdict, PipeIORequest, PipeIOResponse, PipelexRunResultStart, PipelexValidateSource, PipelexValidationResult, ResolveRequest, ResolveResponse, ValidateMethodSelector } from "./models.js";
|
|
3
3
|
import { type GetRunResultOptions, type RunProgress, type RunRead, type RunResults, type RunResultState, type StartAndWaitForResultOptions, type WaitForResultOptions } from "./runs.js";
|
|
4
|
-
import type { BillingPortalResponse, ChangePlanResponse, CheckoutResponse, FilePage, FileSummary, InvoiceView, Membership, MembershipsResponse, OrganizationBranding, OrganizationBrandingUpdate, ListFilesQuery, ListMethodExamplesQuery, ListMethodsQuery, ListMethodVersionsQuery, MethodData, MethodDeletionAccepted, MethodDetail, MethodDraftInput, MethodExample, MethodExampleCreateInput, MethodExampleLatestRunInput, MethodExampleLatestRunResult, MethodExamplePage, MethodExampleUpdateInput, MethodPage, MethodPublishInput, MethodPublishResult, MethodRenameInput, MethodSummary, MethodVersion, MethodVersionPage, MethodWriteInput, OnboardingSubmission, PipelexApiKeyCreated, PipelexApiKeyList, ListRunsQuery, RunHistoryItem, RunDetail, RunPage, PlanView, ResolvedStorageUrl, SavedMethodFile, SubscriptionResponse, UpdateRunInput, UploadGrant, UploadGrantInput, UploadInput, UploadedFile, UserProfile } from "./product-models.js";
|
|
4
|
+
import type { BillingPortalResponse, ChangePlanResponse, CheckoutResponse, DraftFileFromFileInput, DraftFileFromFileResult, FileArchive, FileArchiveRequest, FileDetail, FileLinkTarget, FileLinksResult, FilePage, FileRecord, FileRecordList, FileRenameInput, FileSummary, GetFileQuery, GetFilesByUriOptions, InvoiceView, Membership, MembershipsResponse, OrganizationBranding, OrganizationBrandingUpdate, ListFilesQuery, ListMethodExamplesQuery, ListMethodsQuery, ListMethodVersionsQuery, ListRunFilesQuery, MethodData, MethodDeletionAccepted, MethodDetail, MethodDraftInput, MethodExample, MethodExampleAssistantSaveInput, MethodExampleAssistantSaveResult, MethodExampleCreateInput, MethodExampleLatestRunInput, MethodExampleLatestRunResult, MethodExamplePage, MethodExampleUpdateInput, MethodPage, MethodPublishInput, MethodPublishResult, MethodRenameInput, MethodSummary, MethodVersion, MethodVersionPage, MethodWriteInput, OnboardingSubmission, PipelexApiKeyCreated, PipelexApiKeyList, ListRunsQuery, RunHistoryItem, RunDetail, RunFilesPage, RunPage, PlanView, ResolvedStorageUrl, SavedMethodFile, SubscriptionResponse, UpdateRunInput, UploadGrant, UploadGrantInput, UploadInput, UploadedFile, UserProfile } from "./product-models.js";
|
|
5
5
|
import type { MethodTreeForms, MethodTreeLimits } from "./method-trees.js";
|
|
6
6
|
import type { AppInfo } from "./user-agent.js";
|
|
7
7
|
import type { UploadableAsset, UploadFileOptions, UploadRecord } from "./upload.js";
|
|
@@ -1342,6 +1342,36 @@ export declare class PipelexApiClient implements HostedProtocolSurface {
|
|
|
1342
1342
|
* `ApiResponseError` too, read as `publishMethod` reads its verdict.
|
|
1343
1343
|
*/
|
|
1344
1344
|
recordMethodExampleLatestRun(methodId: string, exampleId: string, input: MethodExampleLatestRunInput): Promise<MethodExampleLatestRunResult>;
|
|
1345
|
+
/**
|
|
1346
|
+
* Save the build assistant's test inputs as its example of the method —
|
|
1347
|
+
* `POST /v1/methods/{id}/examples/assistant-save` — **never writing over a person's edit**.
|
|
1348
|
+
*
|
|
1349
|
+
* The assistant keeps one example of a method current with its test inputs, until a person
|
|
1350
|
+
* edits that example's inputs. Find its example as the method's newest with `kept_by_assistant`
|
|
1351
|
+
* true (`listMethodExamples` answers them oldest first), and send its `example_id` with the
|
|
1352
|
+
* `input_revision` you read it at. The platform writes the inputs into it only while it still
|
|
1353
|
+
* exists, still carries the flag and still holds that revision, in one conditional write that it
|
|
1354
|
+
* never retries. Otherwise, and when no example is named, which is how the first save on a
|
|
1355
|
+
* method creates the assistant's example, it saves the inputs as a new example flagged as the
|
|
1356
|
+
* assistant's, under `name`.
|
|
1357
|
+
*
|
|
1358
|
+
* The answer is a `MethodExampleAssistantSaveResult` discriminated on `outcome` — branch on it:
|
|
1359
|
+
* `kept`, the named example now holds the inputs, its name untouched; `created`, a new example
|
|
1360
|
+
* holds them. Both carry the `example`, which is the assistant's from then on. A retry of a save
|
|
1361
|
+
* that landed answers `kept` and writes nothing again.
|
|
1362
|
+
*
|
|
1363
|
+
* Sends `name`, `inputs` and, when given, `example_id` with `input_revision`, and nothing else:
|
|
1364
|
+
* the body is closed, and `null` reads as not given. Throws `RequestArgumentError` before any
|
|
1365
|
+
* request when `name` or `inputs` is not given, for an `example_id` that is not a non-empty
|
|
1366
|
+
* string or an `input_revision` that is not a positive integer, and when only one of the two is
|
|
1367
|
+
* given. Throws `ApiResponseError`: `403` `role_not_permitted` for a role that may not change
|
|
1368
|
+
* methods, such as a runner; `413` `payload_too_large` for an example larger than one stored item
|
|
1369
|
+
* holds; `422` for a name that is empty, blank or over 200 characters, or inputs that are not a
|
|
1370
|
+
* JSON object; and the codes every example route answers. An answer whose `outcome` is neither
|
|
1371
|
+
* arm's, or whose `example` is not an example `readMethodExample` can read, is an answer the SDK
|
|
1372
|
+
* cannot read, thrown as an `ApiResponseError` too.
|
|
1373
|
+
*/
|
|
1374
|
+
saveAssistantMethodExample(methodId: string, input: MethodExampleAssistantSaveInput): Promise<MethodExampleAssistantSaveResult>;
|
|
1345
1375
|
/**
|
|
1346
1376
|
* Delete an example — `DELETE /v1/methods/{id}/examples/{example_id}`. The platform answers
|
|
1347
1377
|
* `204`. Deleting the example leaves its latest run in the method's history.
|
|
@@ -1484,7 +1514,8 @@ export declare class PipelexApiClient implements HostedProtocolSurface {
|
|
|
1484
1514
|
*/
|
|
1485
1515
|
downloadArtifacts(request: DownloadArtifactsRequest): Promise<DownloadArtifactsResult>;
|
|
1486
1516
|
/**
|
|
1487
|
-
* Upload a base64 file — `POST /v1/upload
|
|
1517
|
+
* Upload a base64 file — `POST /v1/upload`, answering the file's `uri`, the `filename` as sent
|
|
1518
|
+
* and the `file_id` of its record. An answer with no non-empty string `uri` names no
|
|
1488
1519
|
* stored file, so it is an answer the SDK cannot read: an `ApiResponseError`, `runtime` and
|
|
1489
1520
|
* not retryable, which `uploadFile` wraps as an `UploadTransportError` with code `unexpected`.
|
|
1490
1521
|
*/
|
|
@@ -1492,18 +1523,24 @@ export declare class PipelexApiClient implements HostedProtocolSurface {
|
|
|
1492
1523
|
/**
|
|
1493
1524
|
* Request a grant to upload one file straight to storage — `POST /v1/upload/grant`.
|
|
1494
1525
|
* `upload` for a caller that holds the bytes but not this client's credential, such
|
|
1495
|
-
* as a browser page: the
|
|
1496
|
-
*
|
|
1497
|
-
*
|
|
1498
|
-
*
|
|
1499
|
-
*
|
|
1500
|
-
*
|
|
1501
|
-
*
|
|
1502
|
-
*
|
|
1503
|
-
*
|
|
1504
|
-
*
|
|
1505
|
-
*
|
|
1506
|
-
* `
|
|
1526
|
+
* as a browser page: the holder of the bytes describes the file with `describeUpload`,
|
|
1527
|
+
* its SHA-256 included, the credential-holding side asks for the grant with that
|
|
1528
|
+
* description and hands the grant over, and the holder of the bytes sends them with
|
|
1529
|
+
* `uploadWithGrant`. Both are on the browser-safe `@pipelex/sdk/upload` entry. The
|
|
1530
|
+
* bytes cross neither this client nor the API gateway, so the gateway's request quota
|
|
1531
|
+
* does not cap the file below the service's own limit (`max_bytes`).
|
|
1532
|
+
*
|
|
1533
|
+
* **Branch on the answer's `stored`.** With the file's `sha256`, the object is named
|
|
1534
|
+
* after its bytes: when the organization already holds them, the grant answers
|
|
1535
|
+
* `stored: true` with the file's `uri` and `file_id` and no upload target, and nothing
|
|
1536
|
+
* is to be sent. Otherwise, and always without a `sha256`, it answers a presigned,
|
|
1537
|
+
* create-only `PUT` whose `uri` exists once the `PUT` succeeds, and not before. That
|
|
1538
|
+
* target is short-lived and a bearer capability, so keep it out of logs. The route
|
|
1539
|
+
* never replays a grant: ask again for a new one rather than retrying; with a
|
|
1540
|
+
* `sha256`, a new grant answers the same file record. A declared `size` over the cap
|
|
1541
|
+
* is a `413` `ApiResponseError` (`code` `payload_too_large`), a malformed `sha256` and
|
|
1542
|
+
* a `size` other than the one the organization holds those bytes at are a `422`, and a
|
|
1543
|
+
* deployment without the route answers a `404`. See `docs/input-preparation.md`.
|
|
1507
1544
|
*/
|
|
1508
1545
|
requestUploadGrant(input: UploadGrantInput, options?: {
|
|
1509
1546
|
signal?: AbortSignal;
|
|
@@ -1595,6 +1632,185 @@ export declare class PipelexApiClient implements HostedProtocolSurface {
|
|
|
1595
1632
|
* `PagingNotTerminatingError` past a page ceiling no real file list reaches.
|
|
1596
1633
|
*/
|
|
1597
1634
|
iterateFiles(query?: Omit<ListFilesQuery, "cursor">): AsyncGenerator<FileSummary, void, undefined>;
|
|
1635
|
+
/**
|
|
1636
|
+
* One file with its provenance, the methods whose lists hold it, and one page of its uses —
|
|
1637
|
+
* `GET /v1/files/{file_id}`.
|
|
1638
|
+
*
|
|
1639
|
+
* The answer is a `FileDetail`: the file's whole record (`FileRecord`), its `method_ids`, and
|
|
1640
|
+
* `uses`, one page of the examples that hold its address, then the runs that took it. Page the
|
|
1641
|
+
* uses by passing `uses.next_cursor` back as `usesCursor`; `null` is the last page. A record whose
|
|
1642
|
+
* upload looked unfinished past the upload grant's lifespan is settled by the read, so it answers
|
|
1643
|
+
* `stored` when its bytes are there.
|
|
1644
|
+
*
|
|
1645
|
+
* Throws `RequestArgumentError` for a file id that is empty, `.` or `..`, or holds a lone
|
|
1646
|
+
* surrogate, before any request. Throws `ApiResponseError`: `404` `not_found` for a file that is
|
|
1647
|
+
* not the organization's; `422` for a `usesLimit` outside 1 to 200 or an id that cannot be one.
|
|
1648
|
+
* An answer that is not an object, or whose `uses` is not a page of `items` and `next_cursor`, is
|
|
1649
|
+
* an answer the SDK cannot read, thrown as an `ApiResponseError` too. See `docs/files.md`.
|
|
1650
|
+
*/
|
|
1651
|
+
getFile(fileId: string, query?: GetFileQuery): Promise<FileDetail>;
|
|
1652
|
+
/**
|
|
1653
|
+
* The records holding one `pipelex-storage://` address — `GET /v1/files/by-uri` — in the order a
|
|
1654
|
+
* surface picks the one to show, the first being it.
|
|
1655
|
+
*
|
|
1656
|
+
* Several records hold one address when several members uploaded the same bytes. With `runId`,
|
|
1657
|
+
* the records of the member who started that run come first, so a run's inputs show the name its
|
|
1658
|
+
* starter gave the file; then the caller's; then the rest, each group oldest first. A record
|
|
1659
|
+
* whose upload has not finished is answered with its `state`, `pending`. An address no record
|
|
1660
|
+
* holds answers an empty `items`, which is how a client tells a file stored before the platform
|
|
1661
|
+
* kept records.
|
|
1662
|
+
*
|
|
1663
|
+
* Throws `RequestArgumentError` for a `uri` that is not a non-empty string, before any request.
|
|
1664
|
+
* Throws `ApiResponseError`: `400` `invalid_storage_uri` for a malformed address, `403`
|
|
1665
|
+
* `forbidden` for another organization's, `404` `run_not_found` for a run that is not the
|
|
1666
|
+
* organization's, and `422` for an address over 512 characters. An answer whose `items` is not an
|
|
1667
|
+
* array is an answer the SDK cannot read, thrown as an `ApiResponseError` too.
|
|
1668
|
+
*/
|
|
1669
|
+
getFilesByUri(uri: string, options?: GetFilesByUriOptions): Promise<FileRecordList>;
|
|
1670
|
+
/**
|
|
1671
|
+
* Rename a file — `PATCH /v1/files/{file_id}` — and return its record as it now stands.
|
|
1672
|
+
*
|
|
1673
|
+
* **The platform holds the name to one rule, for every client**: it removes the characters no
|
|
1674
|
+
* list or header can show (control and format characters, a right-to-left override among
|
|
1675
|
+
* them), trims the ends, refuses a name with nothing left, and adds the file's own extension,
|
|
1676
|
+
* the one its `original_name` ends with, when the name does not end with it, case aside:
|
|
1677
|
+
* `March invoice` becomes `March invoice.pdf`, and `March.docx` becomes `March.docx.pdf`. A file
|
|
1678
|
+
* whose original name has no extension gains none. Read the saved name from the answer's
|
|
1679
|
+
* `name`. The rename changes `name` alone, never the file's bytes, its address or its
|
|
1680
|
+
* `original_name`.
|
|
1681
|
+
*
|
|
1682
|
+
* An `admin` or a `member` renames any file; any other role, a runner among them, only the files
|
|
1683
|
+
* whose record names it as `created_by`: its own uploads and the outputs of the runs it started.
|
|
1684
|
+
*
|
|
1685
|
+
* Sends `name` alone: the body is closed. Throws `RequestArgumentError` for a file id that is
|
|
1686
|
+
* empty, `.` or `..`, or holds a lone surrogate, and for a `name` that is not a string, before
|
|
1687
|
+
* any request. Throws `ApiResponseError`: `403` `role_not_permitted` past the rule above; `404`
|
|
1688
|
+
* `not_found` for a file that is not the organization's; `422` for a name over 512 characters or
|
|
1689
|
+
* with nothing left once cleaned. An answer that is not an object is an answer the SDK cannot
|
|
1690
|
+
* read, thrown as an `ApiResponseError` too.
|
|
1691
|
+
*/
|
|
1692
|
+
renameFile(fileId: string, input: FileRenameInput): Promise<FileRecord>;
|
|
1693
|
+
/**
|
|
1694
|
+
* Fresh links to read files — `POST /v1/files/links` — one per requested file, in the request's
|
|
1695
|
+
* order, each named by exactly one of its record's id (`file_id`) and its address (`uri`).
|
|
1696
|
+
*
|
|
1697
|
+
* **Branch on each item's `error`, never on the status**: the request is a `200` whenever every
|
|
1698
|
+
* file got a verdict. A linked file carries its `url`, a presigned `GET` valid for fifteen
|
|
1699
|
+
* minutes, with its `expires_at`, the `name` the download saves under and its `media_type`, and
|
|
1700
|
+
* a `null` `error`. A file that got no link carries `error`, `{ code, detail }`, and `null` link
|
|
1701
|
+
* members: `not_found` for an unknown file id, `conflict` for a file whose upload has not
|
|
1702
|
+
* finished, `invalid_storage_uri` for a malformed address and `forbidden` for another
|
|
1703
|
+
* organization's.
|
|
1704
|
+
*
|
|
1705
|
+
* Each link is signed with a `Content-Disposition` naming the file, so a download saves under
|
|
1706
|
+
* the name a person sees rather than the bytes' hash. It opens in place (`inline`) for an image,
|
|
1707
|
+
* a PDF or plain text and downloads (`attachment`) for every other type, SVG, HTML and XML
|
|
1708
|
+
* included, so a file that could run scripts never opens from a link. A file named by its id is
|
|
1709
|
+
* linked under its record's name; an address under the name of its first stored record, the
|
|
1710
|
+
* caller's before another member's, whose id the item's `file_id` names. A link is a bearer
|
|
1711
|
+
* capability: keep it out of logs, and ask again for a fresh one rather than storing it.
|
|
1712
|
+
*
|
|
1713
|
+
* Sends each file as `{ file_id }` or `{ uri }` and nothing else: the body is closed. Throws
|
|
1714
|
+
* `RequestArgumentError` before any request when `files` is not a list, or one of its items does
|
|
1715
|
+
* not name exactly one of `file_id` and `uri` as a non-empty string. Throws `ApiResponseError`:
|
|
1716
|
+
* `422` for more than 100 files, or an id or address longer than one can be; `500` `config` when
|
|
1717
|
+
* the platform cannot sign at all. An answer that is not one item per requested file, each an
|
|
1718
|
+
* object with its `url` or its `error`, is an answer the SDK cannot read, thrown as an
|
|
1719
|
+
* `ApiResponseError` whose body hides every link.
|
|
1720
|
+
*/
|
|
1721
|
+
linkFiles(files: readonly FileLinkTarget[]): Promise<FileLinksResult>;
|
|
1722
|
+
/**
|
|
1723
|
+
* Ask for one zip of chosen files, or of a run's files — `POST /v1/files/archives` — and return
|
|
1724
|
+
* the archive, `queued`.
|
|
1725
|
+
*
|
|
1726
|
+
* The platform cannot build a zip inside a request, so the zip is two calls: this one queues the
|
|
1727
|
+
* archive and answers at once (`202`), and `getFileArchive` reads it until its `state` is `ready`,
|
|
1728
|
+
* whose `url` downloads the zip, or `failed`, whose `failure` says why. Name the files by exactly
|
|
1729
|
+
* one of `file_ids`, in the order the zip holds them, and `run_id`, whose zip holds what went in
|
|
1730
|
+
* and what came out of the run, never a file it made along the way nor an input given as a web
|
|
1731
|
+
* link. `name` is the name the zip downloads under (see `FileArchiveRequest`). An archive is never
|
|
1732
|
+
* a file: no list shows it, and it is gone a day after it was asked for.
|
|
1733
|
+
*
|
|
1734
|
+
* Sends `file_ids` or `run_id`, and `name` when given, and nothing else: the body is closed, and a
|
|
1735
|
+
* `null` member reads as not given. Throws `RequestArgumentError` before any request when the
|
|
1736
|
+
* request names both or neither of `file_ids` and `run_id`, when `file_ids` is not a non-empty
|
|
1737
|
+
* list of non-empty strings, when `run_id` is not a non-empty string, and when `name` is not a
|
|
1738
|
+
* string. Throws `ApiResponseError`:
|
|
1739
|
+
*
|
|
1740
|
+
* - `422` `file_archive_too_large` past a cap, at most 500 files or 2,000,000,000 bytes, whose
|
|
1741
|
+
* `problemDocument.limit` names it (`FileArchiveLimit`), so the person can be told how far over
|
|
1742
|
+
* the selection is;
|
|
1743
|
+
* - `422` `validation_failed` for more than 1,000 ids listed, or an id longer than one can be;
|
|
1744
|
+
* - `404` `not_found` for a file that is not the organization's, the `detail` naming up to five
|
|
1745
|
+
* of them, or a run whose files hold nothing stored to zip; `404` `run_not_found` for a run
|
|
1746
|
+
* that is not the organization's;
|
|
1747
|
+
* - `409` `conflict`: an `input` one, not retryable, for a selected file whose upload has not
|
|
1748
|
+
* finished; a `runtime` one, retryable, for a run whose files are not all recorded yet, which
|
|
1749
|
+
* the same request clears a few seconds after the run ends;
|
|
1750
|
+
* - `503` `service_unavailable`, retryable, when the archive could not be queued: the same request
|
|
1751
|
+
* sent again asks for a new archive.
|
|
1752
|
+
*
|
|
1753
|
+
* An answer that is not an archive, an object with a string `archive_id` and a known `state`, is
|
|
1754
|
+
* an answer the SDK cannot read, thrown as an `ApiResponseError` too.
|
|
1755
|
+
*/
|
|
1756
|
+
requestFileArchive(request: FileArchiveRequest): Promise<FileArchive>;
|
|
1757
|
+
/**
|
|
1758
|
+
* Where an archive stands — `GET /v1/files/archives/{archive_id}` — with a fresh link to its zip
|
|
1759
|
+
* once it is `ready`.
|
|
1760
|
+
*
|
|
1761
|
+
* **Branch on `state`.** `queued` and `building` mean read it again shortly: a zip of a few files
|
|
1762
|
+
* is ready within seconds, and the largest the caps allow within a few minutes. `ready` carries
|
|
1763
|
+
* `url`, a presigned `GET` of the zip valid for fifteen minutes and signed with a
|
|
1764
|
+
* `Content-Disposition` naming the archive's `name`, with `archive_bytes` and `ready_at`; each read
|
|
1765
|
+
* signs a fresh link, so a caller that let one lapse reads the archive again. `failed` carries
|
|
1766
|
+
* `failure`, `file_gone` or `build_failed`, and the remedy for both is a new request. An archive
|
|
1767
|
+
* still `queued` or `building` an hour after it was asked for reads as `failed`.
|
|
1768
|
+
*
|
|
1769
|
+
* Throws `RequestArgumentError` for an archive id that is empty, `.` or `..`, or holds a lone
|
|
1770
|
+
* surrogate, before any request. Throws `ApiResponseError`: `404` `not_found` for an archive that
|
|
1771
|
+
* is not the organization's, never existed, or has expired, a day after `created_at`; `500` when
|
|
1772
|
+
* the link cannot be signed. An answer that is not an archive is an answer the SDK cannot read,
|
|
1773
|
+
* thrown as an `ApiResponseError` whose body hides the link.
|
|
1774
|
+
*/
|
|
1775
|
+
getFileArchive(archiveId: string): Promise<FileArchive>;
|
|
1776
|
+
/**
|
|
1777
|
+
* An archive as `res` carried it, checked to be one: an object with a string `archive_id` and a
|
|
1778
|
+
* `state` this SDK knows, the field a caller branches on. Anything else is an answer the SDK
|
|
1779
|
+
* cannot read, thrown as the `ApiResponseError` `unreadableAnswer` builds with every link hidden,
|
|
1780
|
+
* since a ready archive's answer carries one.
|
|
1781
|
+
*/
|
|
1782
|
+
private readFileArchive;
|
|
1783
|
+
/**
|
|
1784
|
+
* Copy one of the organization's files into a method's draft —
|
|
1785
|
+
* `POST /v1/methods/{id}/draft/files/from-file`, "Add to method files".
|
|
1786
|
+
*
|
|
1787
|
+
* The file becomes a file of the draft at `path`, replacing a file already there. Its bytes are
|
|
1788
|
+
* copied into the organization's blob store by the storage service itself, so they never cross
|
|
1789
|
+
* the client or the API whatever their size, and are skipped when the store already holds them.
|
|
1790
|
+
* The method file then lives apart from its source: erasing the file's record, the run that made
|
|
1791
|
+
* it or the method it came from leaves it readable.
|
|
1792
|
+
*
|
|
1793
|
+
* The answer is a `DraftFileFromFileResult`, a `200` discriminated on `blob`: `copied`, or
|
|
1794
|
+
* `already_held` when the store held the bytes and nothing was copied. Both carry the `file` as
|
|
1795
|
+
* the draft's tree now names it and the `method` as the draft write stored it, whose
|
|
1796
|
+
* `updated_at` is the new draft token. With `expected_updated_at`, the write is a
|
|
1797
|
+
* compare-and-swap on the draft token; without it, the file is added to the draft as it stands,
|
|
1798
|
+
* never erasing someone else's save.
|
|
1799
|
+
*
|
|
1800
|
+
* Takes a bare catalog id, as `writeDraft` does. Sends `file_id`, `path` and, when given,
|
|
1801
|
+
* `expected_updated_at`, and nothing else: the body is closed, and a `null` token reads as not
|
|
1802
|
+
* given. Throws `RequestArgumentError` before any request for a `file_id` or a `path` that is not
|
|
1803
|
+
* a non-empty string, and an `expected_updated_at` that is not a string. Throws
|
|
1804
|
+
* `ApiResponseError`: `403` `role_not_permitted` for a role that may not change methods; `404`
|
|
1805
|
+
* for an unknown method or a file that is not the organization's; `409` `method_being_deleted`,
|
|
1806
|
+
* `409` `method_update_conflict` for a stale `expected_updated_at`, and `409` `conflict` for a
|
|
1807
|
+
* file whose upload has not finished or whose stored bytes do not match its record; `422`
|
|
1808
|
+
* `invalid_method_files` for a path the draft cannot hold, such as `.env` or `../logo.png`, and
|
|
1809
|
+
* `422` `method_tree_too_large` past the deployment's limits. An answer whose `blob` is neither
|
|
1810
|
+
* arm's, or whose `file` or `method` is not an object, is an answer the SDK cannot read, thrown
|
|
1811
|
+
* as an `ApiResponseError` too.
|
|
1812
|
+
*/
|
|
1813
|
+
copyFileIntoDraft(methodId: string, input: DraftFileFromFileInput): Promise<DraftFileFromFileResult>;
|
|
1598
1814
|
/**
|
|
1599
1815
|
* One PAGE of a method's runs, newest first — `GET /v1/runs?method_id=`.
|
|
1600
1816
|
*
|
|
@@ -1673,6 +1889,29 @@ export declare class PipelexApiClient implements HostedProtocolSurface {
|
|
|
1673
1889
|
* example's go back as the run used them.
|
|
1674
1890
|
*/
|
|
1675
1891
|
getRunDetail(runId: string): Promise<RunDetail>;
|
|
1892
|
+
/**
|
|
1893
|
+
* One page of a run's files, sorted by where they sit in the run — `GET /v1/runs/{id}/files`.
|
|
1894
|
+
*
|
|
1895
|
+
* Each entry carries its `mark`, `input`, `final` or `intermediate`, and the record a surface
|
|
1896
|
+
* shows for it (`RunFileEntry`): `inputs` are what went in, the inputs given by their address
|
|
1897
|
+
* with the record of the member who started the run first, then the inline inputs; `outputs` are
|
|
1898
|
+
* the run's final outputs; `intermediates` the files it made along the way. An input given as a
|
|
1899
|
+
* web link gets no record and is listed in `links`, with the warning that replaying the run needs
|
|
1900
|
+
* it to still serve the same file.
|
|
1901
|
+
*
|
|
1902
|
+
* **`state` is `listing` until the platform has recorded every file of the run**, a few seconds
|
|
1903
|
+
* after it ends: read it again until it is `listed` before taking the list as whole. The run's
|
|
1904
|
+
* own records are paged by address with `limit` and `cursor`; the inputs by address and the links
|
|
1905
|
+
* come on the first page only. Pass `nextCursor` back as `cursor`; `null` is the last page.
|
|
1906
|
+
*
|
|
1907
|
+
* Throws `RequestArgumentError` for a run id that is empty, `.` or `..`, or holds a lone
|
|
1908
|
+
* surrogate, before any request. Throws `ApiResponseError`: `404` for a run that is not the
|
|
1909
|
+
* organization's, exactly as for one that does not exist; `400` for a run id holding a character
|
|
1910
|
+
* outside letters, digits, `_` and `-`, or a cursor another listing issued; `422` for a `limit`
|
|
1911
|
+
* outside 1 to 200. A page whose `state` is unknown, whose lists are not arrays, or whose `next_cursor` is neither a
|
|
1912
|
+
* string nor `null`, is an answer the SDK cannot read, thrown as an `ApiResponseError` too.
|
|
1913
|
+
*/
|
|
1914
|
+
listRunFiles(runId: string, query?: ListRunFilesQuery): Promise<RunFilesPage>;
|
|
1676
1915
|
/** Patch a run's status (admin/manual) — `PUT /v1/runs/{id}`. */
|
|
1677
1916
|
updateRun(runId: string, input: UpdateRunInput): Promise<void>;
|
|
1678
1917
|
/**
|