@pipelex/sdk 0.47.0 → 0.48.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -7
- package/dist/artifacts.d.ts +4 -3
- package/dist/artifacts.js +20 -14
- package/dist/artifacts.js.map +1 -1
- package/dist/cli/script.d.ts +1 -1
- package/dist/cli/source.d.ts +8 -7
- package/dist/cli/source.js +11 -5
- package/dist/cli/source.js.map +1 -1
- package/dist/client.d.ts +326 -213
- package/dist/client.js +829 -517
- package/dist/client.js.map +1 -1
- package/dist/codegen-check.d.ts +2 -3
- package/dist/codegen-check.js +2 -3
- package/dist/codegen-check.js.map +1 -1
- package/dist/errors.d.ts +5 -2
- package/dist/errors.js +5 -2
- package/dist/errors.js.map +1 -1
- package/dist/hooks/bundle-gather.d.ts +47 -40
- package/dist/hooks/bundle-gather.js +121 -219
- package/dist/hooks/bundle-gather.js.map +1 -1
- package/dist/hooks/check-core.d.ts +70 -6
- package/dist/hooks/check-core.js +188 -29
- package/dist/hooks/check-core.js.map +1 -1
- package/dist/hooks/claude-mthds-check.d.ts +19 -5
- package/dist/hooks/claude-mthds-check.js +20 -53
- package/dist/hooks/claude-mthds-check.js.map +1 -1
- package/dist/hooks/secret-guard.d.ts +38 -0
- package/dist/hooks/secret-guard.js +134 -0
- package/dist/hooks/secret-guard.js.map +1 -0
- package/dist/hooks/validate-stage.d.ts +29 -0
- package/dist/hooks/validate-stage.js +66 -0
- package/dist/hooks/validate-stage.js.map +1 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/method-trees.d.ts +220 -74
- package/dist/method-trees.js +250 -37
- package/dist/method-trees.js.map +1 -1
- package/dist/models.d.ts +162 -59
- package/dist/node-host/node.d.ts +33 -0
- package/dist/node-host/node.js +27 -0
- package/dist/node-host/node.js.map +1 -0
- package/dist/node-host/unavailable.d.ts +8 -0
- package/dist/node-host/unavailable.js +8 -0
- package/dist/node-host/unavailable.js.map +1 -0
- package/dist/node-host.d.ts +53 -0
- package/dist/node-host.js +72 -0
- package/dist/node-host.js.map +1 -0
- package/dist/prepare-inputs.d.ts +46 -27
- package/dist/prepare-inputs.js +123 -42
- package/dist/prepare-inputs.js.map +1 -1
- package/dist/product-models.d.ts +14 -16
- package/dist/upload.d.ts +4 -9
- package/dist/upload.js +13 -16
- package/dist/upload.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/architecture.md +44 -21
- package/docs/cli.md +1 -1
- package/docs/crate-routes.md +43 -21
- package/docs/errors.md +5 -5
- package/docs/hook-bundle.md +27 -1
- package/docs/input-preparation.md +13 -13
- package/docs/method-trees.md +120 -22
- package/docs/run-results.md +5 -2
- package/package.json +8 -2
- package/dist/bundle-resources.d.ts +0 -62
- package/dist/bundle-resources.js +0 -165
- package/dist/bundle-resources.js.map +0 -1
- package/docs/bundle-resources.md +0 -107
package/dist/models.d.ts
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* the model reference check. Built on the protocol wire types imported from the
|
|
9
9
|
* `mthds/protocol` subpath.
|
|
10
10
|
*/
|
|
11
|
-
import type { InputForm, OutputForm, PipeIOContracts, RunResultExecute, RunResultStart } from "mthds/protocol";
|
|
12
|
-
import type {
|
|
11
|
+
import type { InputForm, MethodFiles, MethodTreeSource, OutputForm, PipeIOContracts, RunResultExecute, RunResultStart } from "mthds/protocol";
|
|
12
|
+
import type { MethodTreeForm, NoMethodTree } from "./method-trees.js";
|
|
13
13
|
export interface DictStuff {
|
|
14
14
|
concept: string;
|
|
15
15
|
content: unknown;
|
|
@@ -75,7 +75,7 @@ export interface PipelexRunResultStart extends RunResultStart {
|
|
|
75
75
|
* The hosted tooling routes' own selector — the layer-3 extension the platform
|
|
76
76
|
* adds on `POST /v1/validate`, `/v1/resolve`, `/v1/codegen`, and `/v1/pipe-io`: a stored
|
|
77
77
|
* method's catalog id (`mt_…`), optionally naming a version, resolved server-side against
|
|
78
|
-
* the org's catalog, the
|
|
78
|
+
* the org's catalog, the tree of the version it names injected as the method's `files`
|
|
79
79
|
* before the runner sees the request. A bare `mt_…` names the latest published version,
|
|
80
80
|
* `mt_…@<n>` version `n` and `mt_…@draft` the draft. A **pass-through to the hosted API**:
|
|
81
81
|
* nothing is expanded client-side, and it is meaningless off-platform (a bare runner
|
|
@@ -97,11 +97,11 @@ export interface PipelexHostedToolingExtensions {
|
|
|
97
97
|
method_id?: string;
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
|
-
* The method selector the tooling routes take in place of
|
|
100
|
+
* The method selector the tooling routes take in place of the method's tree: a
|
|
101
101
|
* `method_ref` address (server-resolved by the runner through the same fetch
|
|
102
102
|
* path as a `method_ref` run) OR a hosted `method_id` (platform-resolved) —
|
|
103
103
|
* never both. The tooling routes are stateless, so the strict XOR applies:
|
|
104
|
-
* exactly one of
|
|
104
|
+
* exactly one of the tree / `method_ref` / `method_id` per request.
|
|
105
105
|
*
|
|
106
106
|
* Lives here, beside the other wire shapes, rather than on the client: it is
|
|
107
107
|
* the request's shape, and a module that composes a `validate` call of its own
|
|
@@ -115,6 +115,23 @@ export type ValidateMethodSelector = {
|
|
|
115
115
|
method_id: string;
|
|
116
116
|
method_ref?: never;
|
|
117
117
|
};
|
|
118
|
+
/**
|
|
119
|
+
* What `validate()` judges: the method's tree, in exactly one of the four forms of
|
|
120
|
+
* `MethodTreeForm` (a `directory`, `contents`, a `tree` or the `files` map), or one of the two
|
|
121
|
+
* selectors of `ValidateMethodSelector`. Each arm pins the others to `never`, so naming two is a
|
|
122
|
+
* compile error; an untyped caller naming none, or more than one, is refused with a
|
|
123
|
+
* `RequestArgumentError` before any request, as the route itself would refuse a second selector
|
|
124
|
+
* with a `422`. At run time a `null` member, an empty `directory` and an empty selector string
|
|
125
|
+
* are absent, and a `files` map or `contents` holding no file is refused, as the MTHDS standard
|
|
126
|
+
* refuses a tree holding no file.
|
|
127
|
+
*
|
|
128
|
+
* It widens the protocol's own `ValidateSource` (`{ files }` or `{ tree }`) with the two forms
|
|
129
|
+
* this client lists or encodes itself and the two selectors the Pipelex API resolves.
|
|
130
|
+
*/
|
|
131
|
+
export type PipelexValidateSource = (MethodTreeForm & {
|
|
132
|
+
method_ref?: never;
|
|
133
|
+
method_id?: never;
|
|
134
|
+
}) | (ValidateMethodSelector & NoMethodTree);
|
|
118
135
|
/** Per-pipe dry-run verdict in `validated_pipes[]` — mirror of pipelex's `DryRunStatus`. */
|
|
119
136
|
export type DryRunStatus = "SUCCESS" | "FAILURE" | "SKIPPED";
|
|
120
137
|
/** One entry of `PipelexValidationReport.validated_pipes` — `{pipe_ref, status}`. */
|
|
@@ -139,6 +156,35 @@ export interface LiftablePipeEntry {
|
|
|
139
156
|
/** Where the possible absence originates (human-readable). */
|
|
140
157
|
absence_source: string;
|
|
141
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* What a step reads a file of its method tree as — mirror of pipelex's `TreeFileUse`:
|
|
161
|
+
* `template`, the template a `PipeDocGen` step fills, named by its `template_file`;
|
|
162
|
+
* `template_asset`, an image, a stylesheet or a font that step's HTML template names by a
|
|
163
|
+
* literal relative URL, or that one of its stylesheets names; `python_module`, the module
|
|
164
|
+
* defining the function a `PipeFunc` step calls, named by the import path of its
|
|
165
|
+
* `function_name`.
|
|
166
|
+
*
|
|
167
|
+
* A report reads it open (see {@link TreeFileRead.use}): a runner of a later version may add
|
|
168
|
+
* a use as another kind of step comes to read files of its tree.
|
|
169
|
+
*/
|
|
170
|
+
export type TreeFileUse = "template" | "template_asset" | "python_module";
|
|
171
|
+
/**
|
|
172
|
+
* One file of its method tree a step reads — mirror of pipelex's `TreeFileRead`, an entry of
|
|
173
|
+
* {@link PipelexValidationReport.tree_files_read}.
|
|
174
|
+
*/
|
|
175
|
+
export interface TreeFileRead {
|
|
176
|
+
/**
|
|
177
|
+
* The file's path from the root of the method's tree, with forward slashes, such as
|
|
178
|
+
* `templates/invoice.html`, never a path on the server.
|
|
179
|
+
*/
|
|
180
|
+
tree_path: string;
|
|
181
|
+
/**
|
|
182
|
+
* What the step reads the file as. Read open: `string & {}` keeps the editor's completion
|
|
183
|
+
* on the uses this SDK knows, and a consumer that switches on this field has to say what a
|
|
184
|
+
* use it does not know does.
|
|
185
|
+
*/
|
|
186
|
+
use: TreeFileUse | (string & {});
|
|
187
|
+
}
|
|
142
188
|
/**
|
|
143
189
|
* Pipelex's `POST /v1/validate` 200 body for a VALID bundle — the canonical
|
|
144
190
|
* `PipelexValidationReport`, carrying the `is_valid: true` discriminant of the
|
|
@@ -209,6 +255,27 @@ export interface PipelexValidationReport {
|
|
|
209
255
|
output_form?: OutputForm;
|
|
210
256
|
/** Pipes the runtime may skip when an optional slot resolves absent. */
|
|
211
257
|
liftable_pipes: LiftablePipeEntry[];
|
|
258
|
+
/**
|
|
259
|
+
* Per step, the files of the method's tree it reads, keyed by namespaced `pipe_ref` over
|
|
260
|
+
* the same set as `pipe_io_contracts`, each file by its tree path with what the step reads
|
|
261
|
+
* it as. A `PipeDocGen` step reads its template and the images, stylesheets and fonts its
|
|
262
|
+
* HTML template names by literal relative URLs; a `PipeFunc` step reads the module of its
|
|
263
|
+
* function when that module is a file of the tree. A step that reads no file of the tree,
|
|
264
|
+
* a controller included, has an empty list. The paths come from what each step already
|
|
265
|
+
* names, so a client can show which step uses a file without parsing the method.
|
|
266
|
+
*
|
|
267
|
+
* OPTIONAL because a runner predating the field sends nothing: an absent field says the
|
|
268
|
+
* server did not report the reads, where an empty list says that step reads no file.
|
|
269
|
+
*/
|
|
270
|
+
tree_files_read?: Record<string, TreeFileRead[]>;
|
|
271
|
+
/**
|
|
272
|
+
* The per-file view of `tree_files_read`: each tree path a step reads, in sorted order, to
|
|
273
|
+
* the namespaced refs of the steps that read it, each listed once. A file of the tree with
|
|
274
|
+
* no entry is read by no step: the bundles themselves, a README, a package's `__init__.py`
|
|
275
|
+
* beside its modules. Optional for the same reason as `tree_files_read`, and present
|
|
276
|
+
* whenever it is.
|
|
277
|
+
*/
|
|
278
|
+
tree_file_readers?: Record<string, string[]>;
|
|
212
279
|
/**
|
|
213
280
|
* The qualified ref of the pipe a selector-less run of THIS request would execute —
|
|
214
281
|
* the primary blueprint's declared `main_pipe` qualified by its domain and, for a
|
|
@@ -326,9 +393,8 @@ export type ValidationErrorCategory = "blueprint_validation" | "pipe_factory" |
|
|
|
326
393
|
* not, so the same item arrives with explicit `null`s there. A truthiness check reads
|
|
327
394
|
* both; an `=== undefined` check would be wrong on one of them.
|
|
328
395
|
*
|
|
329
|
-
* `source` is the declaring file path (CLI) or the
|
|
330
|
-
*
|
|
331
|
-
* diagnostics.
|
|
396
|
+
* `source` is the declaring file: its path (CLI), or its tree path in the tree the
|
|
397
|
+
* request sent — the owning file for cross-file diagnostics.
|
|
332
398
|
*
|
|
333
399
|
* An `unknown_model` item (a model reference the runner's model deck does not know)
|
|
334
400
|
* carries the reference as written, the kind of model the field takes and the close
|
|
@@ -514,50 +580,84 @@ export interface FormatResponse {
|
|
|
514
580
|
diagnostics: Diagnostic[];
|
|
515
581
|
}
|
|
516
582
|
/**
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
* this file, so an invalid verdict can point at the file that caused it.
|
|
583
|
+
* The method every crate route takes — `/v1/resolve`, `/v1/codegen` and `/v1/pipe-io`
|
|
584
|
+
* (mirror of the runner's `MethodTreeRequest`).
|
|
520
585
|
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
*/
|
|
527
|
-
export interface MthdsFileItem {
|
|
528
|
-
content: string;
|
|
529
|
-
source?: string;
|
|
530
|
-
}
|
|
531
|
-
/**
|
|
532
|
-
* The closure selector every crate route shares — `/v1/resolve`, `/v1/codegen` and
|
|
533
|
-
* `/v1/pipe-io` (mirror of the server's `MthdsFilesRequest`).
|
|
586
|
+
* Supply the method EITHER as its tree OR as a `method_ref` — never both, and never neither
|
|
587
|
+
* (both arms are a request-shape `422`); the hosted `method_id` joins them as a third form on
|
|
588
|
+
* each route's own request (see {@link PipelexHostedToolingExtensions}). The tree is the MTHDS
|
|
589
|
+
* protocol's map of file entries, keyed by tree path, given in exactly one of the four forms
|
|
590
|
+
* every route takes (`MethodTreeForms`):
|
|
534
591
|
*
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
* real relative paths as per-file sources. The **registry form** (any non-address
|
|
543
|
-
* reference) stays reserved and answers `501` until a method registry exists.
|
|
592
|
+
* - `directory`, the method's directory on disk, listed by the `mthds` package's lister under
|
|
593
|
+
* the standard's membership rule and the deployment's limits (Node only);
|
|
594
|
+
* - `contents`, each file's bytes or text by tree path;
|
|
595
|
+
* - `tree`, a `MethodTreeSource`, such as the `MethodTree` the `mthds` package's
|
|
596
|
+
* `listMethodTree` returns;
|
|
597
|
+
* - `files`, the map itself, each value the file's text, `{ base64 }` or `{ sha256, size }` for
|
|
598
|
+
* bytes the runner already holds, sent as given.
|
|
544
599
|
*
|
|
545
|
-
* The
|
|
546
|
-
*
|
|
547
|
-
*
|
|
600
|
+
* The client sends a `directory`, `contents` or `tree` inline when its inline map weighs 256 KiB
|
|
601
|
+
* or less and no more than the inline limit the API announces, or whatever its weight when the
|
|
602
|
+
* API keeps no blob store, and otherwise every file by hash, after uploading the files the API
|
|
603
|
+
* lacks, exactly as `createMethod` sends one (see `docs/method-trees.md`). Every `.mthds` file of
|
|
604
|
+
* the tree is one of the method's bundles, named by its tree path in diagnostics and in the
|
|
605
|
+
* crate's `source_map`, and every other file is one a step may read, such as a `PipeDocGen`
|
|
606
|
+
* template.
|
|
548
607
|
*
|
|
549
|
-
* `
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
608
|
+
* An **address-form** `method_ref` (`github.com/<owner>/<repo>[/<selector>][@<tag>]`) is
|
|
609
|
+
* resolved by the server (pipelex-api >= 0.21.0): the package's whole tree is fetched at the tag
|
|
610
|
+
* and read as a tree sent in `files` is. The **registry form** (any non-address reference) stays
|
|
611
|
+
* reserved and answers `501` until a method registry exists.
|
|
612
|
+
*
|
|
613
|
+
* The XOR is a server-side invariant, not a type-level one: expressing it as a union here would
|
|
614
|
+
* make the common `{ files }` call site pick a branch for no gain, and the server rejects the
|
|
615
|
+
* illegal shapes with a typed `ApiResponseError` either way. Two forms of the tree at once are
|
|
616
|
+
* the one shape the client refuses itself, with a `RequestArgumentError`, since it prepares the
|
|
617
|
+
* tree before posting. An empty map or string is absent, as in the Python SDK: `files: {}`,
|
|
618
|
+
* `files: null`, `contents: {}`, `directory: ""` and `dependencies: {}` select and send nothing,
|
|
619
|
+
* so an empty one beside another selector never reaches the wire as a second selector.
|
|
620
|
+
*
|
|
621
|
+
* `dependencies` accompanies the tree: the method packages it calls by address that the runner
|
|
622
|
+
* cannot fetch, each a map of file entries keyed by its address, sent as given. These routes load
|
|
623
|
+
* a package the method calls only from what was shipped with it, so a call into one nothing
|
|
624
|
+
* shipped is the invalid verdict.
|
|
625
|
+
*
|
|
626
|
+
* The files the closure's steps read, such as a `PipeDocGen` step's `template_file`, are files of
|
|
627
|
+
* the tree like any other, so a directory sends them with its bundles.
|
|
628
|
+
*
|
|
629
|
+
* `read_scope` is the Pipelex API's scope the request reads the method under: a hash entry of
|
|
630
|
+
* `files` resolves in that scope's blob store, else in the caller's own. A tree sent by hash asks
|
|
631
|
+
* `POST /v1/blobs/missing` under the same scope, so its blobs are uploaded into the store the
|
|
632
|
+
* request reads. **The hosted platform ignores it**: it stamps the caller's organization as the
|
|
633
|
+
* read scope of every crate request and drops the one the caller sent, so it only reaches a
|
|
634
|
+
* runner called directly.
|
|
555
635
|
*/
|
|
556
636
|
export interface CrateRequestBase {
|
|
557
|
-
|
|
637
|
+
/** The method's directory, listed by the standard's lister and sent as `tree` is. Node only. */
|
|
638
|
+
directory?: string | null;
|
|
639
|
+
/** The method's files, each one's bytes or text by tree path, sent as `tree` is. */
|
|
640
|
+
contents?: Readonly<Record<string, Uint8Array | string>> | null;
|
|
641
|
+
/** The method's tree as a listed source, sent inline when small and by hash otherwise. */
|
|
642
|
+
tree?: MethodTreeSource | null;
|
|
643
|
+
/** The method's tree as the protocol's map of file entries, sent as given. */
|
|
644
|
+
files?: MethodFiles | null;
|
|
645
|
+
/** The method packages the tree calls by address, each a map of file entries keyed by its address. */
|
|
646
|
+
dependencies?: Record<string, MethodFiles>;
|
|
558
647
|
method_ref?: string;
|
|
559
|
-
/** The
|
|
560
|
-
|
|
648
|
+
/** The scope the runner reads the tree under; the hosted platform replaces it with the caller's organization. */
|
|
649
|
+
read_scope?: string;
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* What a crate route call — `resolve`, `codegen`, `pipeIo` — takes beside its request.
|
|
653
|
+
*
|
|
654
|
+
* `signal` is read between the steps a `tree` or `contents` costs before the request, and before
|
|
655
|
+
* the request itself: once it has aborted, no further file of the tree is read, neither the blob
|
|
656
|
+
* route nor an upload starts, and the route is not asked, and the call throws the abort. A request
|
|
657
|
+
* already sent runs to its end, as in `prepareInputs`, which passes its own `signal` here.
|
|
658
|
+
*/
|
|
659
|
+
export interface CrateRouteOptions {
|
|
660
|
+
signal?: AbortSignal;
|
|
561
661
|
}
|
|
562
662
|
/**
|
|
563
663
|
* The `is_valid: false` arm shared by every crate route — `/v1/resolve`,
|
|
@@ -578,7 +678,7 @@ export interface CrateInvalidReport {
|
|
|
578
678
|
}
|
|
579
679
|
/**
|
|
580
680
|
* `POST /v1/resolve` request — the crate envelope (no projection axes) plus the
|
|
581
|
-
* hosted `method_id` selector. Exactly one of
|
|
681
|
+
* hosted `method_id` selector. Exactly one of the tree / `method_ref` /
|
|
582
682
|
* `method_id` — the strict tooling XOR; see {@link PipelexHostedToolingExtensions}.
|
|
583
683
|
*/
|
|
584
684
|
export type ResolveRequest = CrateRequestBase & PipelexHostedToolingExtensions;
|
|
@@ -626,7 +726,7 @@ export type CodegenKind = "types";
|
|
|
626
726
|
export type CodegenTarget = "ts-zod" | "python-pydantic" | "python-structures";
|
|
627
727
|
/**
|
|
628
728
|
* `POST /v1/codegen` request — the crate envelope plus the two explicit projection
|
|
629
|
-
* axes and the hosted `method_id` selector (exactly one of
|
|
729
|
+
* axes and the hosted `method_id` selector (exactly one of the tree / `method_ref` /
|
|
630
730
|
* `method_id`; see {@link PipelexHostedToolingExtensions}).
|
|
631
731
|
*/
|
|
632
732
|
export interface CodegenRequest extends CrateRequestBase, PipelexHostedToolingExtensions {
|
|
@@ -677,7 +777,7 @@ export interface CodegenValidReport {
|
|
|
677
777
|
export type CodegenResponse = CodegenValidReport | CrateInvalidReport;
|
|
678
778
|
/**
|
|
679
779
|
* `POST /v1/pipe-io` request — the crate envelope plus the hosted `method_id` selector
|
|
680
|
-
* (exactly one of
|
|
780
|
+
* (exactly one of the tree / `method_ref` / `method_id`; see
|
|
681
781
|
* {@link PipelexHostedToolingExtensions}), a pipe selector, and two opt-ins.
|
|
682
782
|
*
|
|
683
783
|
* There is no `views` field: the valid arm always carries all three artifacts.
|
|
@@ -685,8 +785,9 @@ export type CodegenResponse = CodegenValidReport | CrateInvalidReport;
|
|
|
685
785
|
export interface PipeIORequest extends CrateRequestBase, PipelexHostedToolingExtensions {
|
|
686
786
|
/**
|
|
687
787
|
* The pipe to describe, as a QUALIFIED `domain.pipe_code` ref. Omit it and the
|
|
688
|
-
* server's selection chain decides:
|
|
689
|
-
* the
|
|
788
|
+
* server's selection chain decides: the `main_pipe` of the `METHODS.toml` at the tree's
|
|
789
|
+
* root, whether the tree was sent or fetched, else the closure's single `main_pipe`
|
|
790
|
+
* declaration. A selection the server refuses is a
|
|
690
791
|
* `422` typed by what went wrong, with `error_domain: "input"` and the candidates, where
|
|
691
792
|
* there are some, in its `detail`: `EntryPipeNotFoundError` for a ref that names no pipe
|
|
692
793
|
* or (without `all_pipes`) a method with no entry pipe, `EntryPipeAmbiguousError` for a
|
|
@@ -705,9 +806,9 @@ export interface PipeIORequest extends CrateRequestBase, PipelexHostedToolingExt
|
|
|
705
806
|
*/
|
|
706
807
|
all_pipes?: boolean;
|
|
707
808
|
/**
|
|
708
|
-
* Echo the
|
|
709
|
-
*
|
|
710
|
-
*
|
|
809
|
+
* Echo the text of the method's own `.mthds` bundles on the valid arm as `files`, keyed
|
|
810
|
+
* by tree path. Defaults to `false` server-side, and the field is then absent from the
|
|
811
|
+
* answer.
|
|
711
812
|
*/
|
|
712
813
|
include_files?: boolean;
|
|
713
814
|
}
|
|
@@ -739,7 +840,8 @@ export interface PipeIOValidReport {
|
|
|
739
840
|
output_form: OutputForm;
|
|
740
841
|
/**
|
|
741
842
|
* The method's own entry pipe: the selection chain without the request's `pipe_ref` —
|
|
742
|
-
* the
|
|
843
|
+
* the `main_pipe` of the `METHODS.toml` at the tree's root, sent or fetched, else the
|
|
844
|
+
* closure's single declaration. A request
|
|
743
845
|
* that omits `pipe_ref` always answers `pipe_ref === default_pipe_ref`. A stated `null`
|
|
744
846
|
* when the chain finds none or several.
|
|
745
847
|
*
|
|
@@ -752,12 +854,13 @@ export interface PipeIOValidReport {
|
|
|
752
854
|
/** `pending_signatures` is empty, as on `validate`. No dry run backs it. */
|
|
753
855
|
is_runnable: boolean;
|
|
754
856
|
/**
|
|
755
|
-
* The
|
|
756
|
-
* when the request passed `include_files: true`:
|
|
757
|
-
*
|
|
758
|
-
*
|
|
857
|
+
* The text of each `.mthds` bundle of the method's own tree, keyed by its tree path.
|
|
858
|
+
* Present only when the request passed `include_files: true`: for a tree the request
|
|
859
|
+
* sent, its bundles, whatever entry form carried them; for a `method_ref`, the fetched
|
|
860
|
+
* package's, keyed by their path from the package root; for a hosted `method_id`, the
|
|
861
|
+
* stored tree's. The tree's other files and its dependencies' bundles are never included.
|
|
759
862
|
*/
|
|
760
|
-
files?:
|
|
863
|
+
files?: Record<string, string>;
|
|
761
864
|
}
|
|
762
865
|
/** The `POST /v1/pipe-io` 200 response — pattern-match `is_valid` before reading the arm. */
|
|
763
866
|
export type PipeIOResponse = PipeIOValidReport | CrateInvalidReport;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Node host as Node resolves it: the one module of the SDK that loads what only Node has,
|
|
3
|
+
* `node:fs/promises`, `node:path`, the `mthds` package's tree lister and `undici`'s `Agent`.
|
|
4
|
+
*
|
|
5
|
+
* Nothing imports this file by its path. `src/node-host.ts` reaches it through `#node-host`, the
|
|
6
|
+
* package's own subpath import, which `package.json` maps to this file under the `node` condition
|
|
7
|
+
* and to `./unavailable.ts` under every other condition set, so a bundler building for a browser
|
|
8
|
+
* or an edge runtime never follows it (see `src/node-host.ts`).
|
|
9
|
+
*
|
|
10
|
+
* The two built-ins load with the host. The `mthds` root entry and `undici` are heavier, and only
|
|
11
|
+
* listing a directory or fetching an artifact needs one of them, so each loads on its first use.
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from "node:fs/promises";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
import type { MethodTreeError, listMethodTree } from "mthds";
|
|
16
|
+
import type { Agent } from "undici";
|
|
17
|
+
/** The `mthds` package's lister of a method directory, and the error it refuses a tree with. */
|
|
18
|
+
export interface TreeLister {
|
|
19
|
+
readonly listMethodTree: typeof listMethodTree;
|
|
20
|
+
readonly MethodTreeError: typeof MethodTreeError;
|
|
21
|
+
}
|
|
22
|
+
/** What only Node has, as the SDK uses it. */
|
|
23
|
+
export interface NodeHost {
|
|
24
|
+
/** `node:fs/promises`. */
|
|
25
|
+
readonly fs: typeof fs;
|
|
26
|
+
/** `node:path`. */
|
|
27
|
+
readonly path: typeof path;
|
|
28
|
+
/** The `mthds` root entry's tree lister, loading that entry on the first call. */
|
|
29
|
+
loadTreeLister(): Promise<TreeLister>;
|
|
30
|
+
/** `undici`'s `Agent`, loading `undici` on the first call. */
|
|
31
|
+
loadAgent(): Promise<typeof Agent>;
|
|
32
|
+
}
|
|
33
|
+
export declare const nodeHost: NodeHost;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Node host as Node resolves it: the one module of the SDK that loads what only Node has,
|
|
3
|
+
* `node:fs/promises`, `node:path`, the `mthds` package's tree lister and `undici`'s `Agent`.
|
|
4
|
+
*
|
|
5
|
+
* Nothing imports this file by its path. `src/node-host.ts` reaches it through `#node-host`, the
|
|
6
|
+
* package's own subpath import, which `package.json` maps to this file under the `node` condition
|
|
7
|
+
* and to `./unavailable.ts` under every other condition set, so a bundler building for a browser
|
|
8
|
+
* or an edge runtime never follows it (see `src/node-host.ts`).
|
|
9
|
+
*
|
|
10
|
+
* The two built-ins load with the host. The `mthds` root entry and `undici` are heavier, and only
|
|
11
|
+
* listing a directory or fetching an artifact needs one of them, so each loads on its first use.
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from "node:fs/promises";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
export const nodeHost = {
|
|
16
|
+
fs,
|
|
17
|
+
path,
|
|
18
|
+
async loadTreeLister() {
|
|
19
|
+
const { listMethodTree, MethodTreeError } = await import("mthds");
|
|
20
|
+
return { listMethodTree, MethodTreeError };
|
|
21
|
+
},
|
|
22
|
+
async loadAgent() {
|
|
23
|
+
const { Agent } = await import("undici");
|
|
24
|
+
return Agent;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/node-host/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAsBlC,MAAM,CAAC,MAAM,QAAQ,GAAa;IAChC,EAAE;IACF,IAAI;IACJ,KAAK,CAAC,cAAc;QAClB,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;QAClE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC;IAC7C,CAAC;IACD,KAAK,CAAC,SAAS;QACb,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Node host as every runtime other than Node resolves it: absent. `package.json` maps
|
|
3
|
+
* `#node-host` to this file under every condition set without `node`, a browser's or an edge
|
|
4
|
+
* runtime's, so the graph a bundler follows there holds no Node built-in, no `undici` and not the
|
|
5
|
+
* `mthds` root entry (see `src/node-host.ts`). It imports nothing at run time.
|
|
6
|
+
*/
|
|
7
|
+
import type { NodeHost } from "./node.js";
|
|
8
|
+
export declare const nodeHost: NodeHost | null;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Node host as every runtime other than Node resolves it: absent. `package.json` maps
|
|
3
|
+
* `#node-host` to this file under every condition set without `node`, a browser's or an edge
|
|
4
|
+
* runtime's, so the graph a bundler follows there holds no Node built-in, no `undici` and not the
|
|
5
|
+
* `mthds` root entry (see `src/node-host.ts`). It imports nothing at run time.
|
|
6
|
+
*/
|
|
7
|
+
export const nodeHost = null;
|
|
8
|
+
//# sourceMappingURL=unavailable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unavailable.js","sourceRoot":"","sources":["../../src/node-host/unavailable.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,CAAC,MAAM,QAAQ,GAAoB,IAAI,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Node host: what the SDK uses that only Node has, behind one import that a bundler building
|
|
3
|
+
* for any other runtime never follows. See `docs/architecture.md`, "The Node host".
|
|
4
|
+
*
|
|
5
|
+
* The operations that need Node, reading a local path (`upload.ts`), downloading a run's files and
|
|
6
|
+
* the undici dispatcher of an artifact fetch (`artifacts.ts`), listing a method directory and
|
|
7
|
+
* writing a saved tree to disk (`method-trees.ts`), get it from `loadNodeHost()`, and never import
|
|
8
|
+
* a Node built-in, `undici` or the `mthds` root entry themselves. `loadNodeHost()` imports
|
|
9
|
+
* `#node-host`, the package's own subpath import, which the `imports` map of `package.json`
|
|
10
|
+
* resolves by condition: under `node` to `node-host/node.ts`, which holds those modules, and under
|
|
11
|
+
* every other condition set, a browser's or an edge runtime's, to `node-host/unavailable.ts`,
|
|
12
|
+
* which holds none. A bundler building for the browser therefore follows no Node built-in from the
|
|
13
|
+
* barrel, statically or dynamically, and `tests/browser-bundle.test.ts` bundles the built package
|
|
14
|
+
* for the browser to hold it to that. Node resolves the same import under its own condition, so
|
|
15
|
+
* the Node-only operations work there as they always did. Where the host cannot be had, outside
|
|
16
|
+
* Node, inside it without the `node` condition, or where the import itself fails, `loadNodeHost()`
|
|
17
|
+
* answers why rather than throwing, so each operation refuses with its own class and verdict.
|
|
18
|
+
*/
|
|
19
|
+
import type { NodeHost } from "./node-host/node.js";
|
|
20
|
+
export type { NodeHost, TreeLister } from "./node-host/node.js";
|
|
21
|
+
/** True when running under Node (has `process.versions.node`). */
|
|
22
|
+
export declare function isNodeRuntime(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* The Node host could not be had: why, for a refusal to say, and the error behind it when the
|
|
25
|
+
* host's import failed.
|
|
26
|
+
*/
|
|
27
|
+
export interface NodeHostAbsence {
|
|
28
|
+
readonly host: null;
|
|
29
|
+
/**
|
|
30
|
+
* Why, as a clause a refusal puts after its own subject; `null` outside Node, where the
|
|
31
|
+
* operation's own "Node only" refusal is the right one.
|
|
32
|
+
*/
|
|
33
|
+
readonly reason: string | null;
|
|
34
|
+
/** The import's own error, when the host's import failed rather than resolving to nothing. */
|
|
35
|
+
readonly cause?: unknown;
|
|
36
|
+
}
|
|
37
|
+
/** The Node host, or why it could not be had. */
|
|
38
|
+
export type NodeHostLoad = {
|
|
39
|
+
readonly host: NodeHost;
|
|
40
|
+
} | NodeHostAbsence;
|
|
41
|
+
/**
|
|
42
|
+
* The Node host, or its absence and why, in three cases: a runtime that is not Node; Node itself
|
|
43
|
+
* where the package was resolved without the `node` export condition, so `#node-host` resolved to
|
|
44
|
+
* the variant holding nothing; and Node where the import of `#node-host` failed, as in a
|
|
45
|
+
* toolchain that does not resolve the `imports` map of `package.json`, whose error is the
|
|
46
|
+
* absence's `cause`. It never throws, so every operation needing Node refuses with its own class
|
|
47
|
+
* and verdict. The runtime is checked first, so nothing is loaded where it is not Node.
|
|
48
|
+
*/
|
|
49
|
+
export declare function loadNodeHost(): Promise<NodeHostLoad>;
|
|
50
|
+
/** The `cause` option of a refusal made for `absence`: the import's own error, when there is one. */
|
|
51
|
+
export declare function absenceCause(absence: NodeHostAbsence): {
|
|
52
|
+
cause?: unknown;
|
|
53
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Node host: what the SDK uses that only Node has, behind one import that a bundler building
|
|
3
|
+
* for any other runtime never follows. See `docs/architecture.md`, "The Node host".
|
|
4
|
+
*
|
|
5
|
+
* The operations that need Node, reading a local path (`upload.ts`), downloading a run's files and
|
|
6
|
+
* the undici dispatcher of an artifact fetch (`artifacts.ts`), listing a method directory and
|
|
7
|
+
* writing a saved tree to disk (`method-trees.ts`), get it from `loadNodeHost()`, and never import
|
|
8
|
+
* a Node built-in, `undici` or the `mthds` root entry themselves. `loadNodeHost()` imports
|
|
9
|
+
* `#node-host`, the package's own subpath import, which the `imports` map of `package.json`
|
|
10
|
+
* resolves by condition: under `node` to `node-host/node.ts`, which holds those modules, and under
|
|
11
|
+
* every other condition set, a browser's or an edge runtime's, to `node-host/unavailable.ts`,
|
|
12
|
+
* which holds none. A bundler building for the browser therefore follows no Node built-in from the
|
|
13
|
+
* barrel, statically or dynamically, and `tests/browser-bundle.test.ts` bundles the built package
|
|
14
|
+
* for the browser to hold it to that. Node resolves the same import under its own condition, so
|
|
15
|
+
* the Node-only operations work there as they always did. Where the host cannot be had, outside
|
|
16
|
+
* Node, inside it without the `node` condition, or where the import itself fails, `loadNodeHost()`
|
|
17
|
+
* answers why rather than throwing, so each operation refuses with its own class and verdict.
|
|
18
|
+
*/
|
|
19
|
+
/** True when running under Node (has `process.versions.node`). */
|
|
20
|
+
export function isNodeRuntime() {
|
|
21
|
+
return (typeof process !== "undefined" && process.versions != null && process.versions.node != null);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Inside Node, the package was resolved without the `node` export condition, as a bundle built
|
|
25
|
+
* for the browser or for esbuild's `neutral` platform resolves it, so `#node-host` resolved to the
|
|
26
|
+
* variant holding nothing.
|
|
27
|
+
*/
|
|
28
|
+
const NODE_CONDITION_MISSING = 'this copy of @pipelex/sdk runs in Node but was resolved without the "node" export ' +
|
|
29
|
+
"condition, which selects the part of the package that reaches Node's file system. Bundle " +
|
|
30
|
+
'it for Node (esbuild platform "node", webpack target "node"), add "node" to the bundler\'s ' +
|
|
31
|
+
"conditions (esbuild conditions, webpack resolve.conditionNames, Vite resolve.conditions), " +
|
|
32
|
+
"or leave @pipelex/sdk out of the bundle.";
|
|
33
|
+
/**
|
|
34
|
+
* Inside Node, the import of `#node-host` itself failed: the toolchain loading the package does
|
|
35
|
+
* not resolve the `imports` map of `package.json`, as Jest before 29.4 does not, or the package is
|
|
36
|
+
* installed in part. `detail` is the import's own error message.
|
|
37
|
+
*/
|
|
38
|
+
function hostImportFailed(detail) {
|
|
39
|
+
return (`the Node host of @pipelex/sdk could not be loaded (${detail}). The SDK reaches Node's file ` +
|
|
40
|
+
'system through "#node-host", an entry of the "imports" map of its package.json, and a ' +
|
|
41
|
+
'toolchain that does not resolve package "imports", such as Jest before 29.4, cannot load ' +
|
|
42
|
+
"it: run under one that does, such as Node's own loader, Jest 29.4 or later or a current " +
|
|
43
|
+
"bundler, or reinstall @pipelex/sdk if it is installed in part.");
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The Node host, or its absence and why, in three cases: a runtime that is not Node; Node itself
|
|
47
|
+
* where the package was resolved without the `node` export condition, so `#node-host` resolved to
|
|
48
|
+
* the variant holding nothing; and Node where the import of `#node-host` failed, as in a
|
|
49
|
+
* toolchain that does not resolve the `imports` map of `package.json`, whose error is the
|
|
50
|
+
* absence's `cause`. It never throws, so every operation needing Node refuses with its own class
|
|
51
|
+
* and verdict. The runtime is checked first, so nothing is loaded where it is not Node.
|
|
52
|
+
*/
|
|
53
|
+
export async function loadNodeHost() {
|
|
54
|
+
if (!isNodeRuntime())
|
|
55
|
+
return { host: null, reason: null };
|
|
56
|
+
let loaded;
|
|
57
|
+
try {
|
|
58
|
+
loaded = await import("#node-host");
|
|
59
|
+
}
|
|
60
|
+
catch (cause) {
|
|
61
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
62
|
+
return { host: null, reason: hostImportFailed(detail), cause };
|
|
63
|
+
}
|
|
64
|
+
return loaded.nodeHost === null
|
|
65
|
+
? { host: null, reason: NODE_CONDITION_MISSING }
|
|
66
|
+
: { host: loaded.nodeHost };
|
|
67
|
+
}
|
|
68
|
+
/** The `cause` option of a refusal made for `absence`: the import's own error, when there is one. */
|
|
69
|
+
export function absenceCause(absence) {
|
|
70
|
+
return absence.cause === undefined ? {} : { cause: absence.cause };
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=node-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-host.js","sourceRoot":"","sources":["../src/node-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,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;AAoBD;;;;GAIG;AACH,MAAM,sBAAsB,GAC1B,oFAAoF;IACpF,2FAA2F;IAC3F,6FAA6F;IAC7F,4FAA4F;IAC5F,0CAA0C,CAAC;AAE7C;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,MAAc;IACtC,OAAO,CACL,sDAAsD,MAAM,iCAAiC;QAC7F,wFAAwF;QACxF,2FAA2F;QAC3F,0FAA0F;QAC1F,gEAAgE,CACjE,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,CAAC,aAAa,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1D,IAAI,MAA8C,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjE,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,KAAK,IAAI;QAC7B,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,sBAAsB,EAAE;QAChD,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,YAAY,CAAC,OAAwB;IACnD,OAAO,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;AACrE,CAAC"}
|