@w6w/sdk 0.1.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/LICENSE +21 -0
- package/README.md +131 -0
- package/dist/mod.d.ts +37 -0
- package/dist/mod.d.ts.map +1 -0
- package/dist/mod.js +51 -0
- package/dist/mod.js.map +1 -0
- package/dist/src/client.d.ts +134 -0
- package/dist/src/client.d.ts.map +1 -0
- package/dist/src/client.js +165 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/config.d.ts +151 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +161 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/connections.d.ts +58 -0
- package/dist/src/connections.d.ts.map +1 -0
- package/dist/src/connections.js +52 -0
- package/dist/src/connections.js.map +1 -0
- package/dist/src/documents.d.ts +168 -0
- package/dist/src/documents.d.ts.map +1 -0
- package/dist/src/documents.js +178 -0
- package/dist/src/documents.js.map +1 -0
- package/dist/src/env.d.ts +61 -0
- package/dist/src/env.d.ts.map +1 -0
- package/dist/src/env.js +73 -0
- package/dist/src/env.js.map +1 -0
- package/dist/src/errors.d.ts +79 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +88 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/http.d.ts +130 -0
- package/dist/src/http.d.ts.map +1 -0
- package/dist/src/http.js +150 -0
- package/dist/src/http.js.map +1 -0
- package/dist/src/me.d.ts +53 -0
- package/dist/src/me.d.ts.map +1 -0
- package/dist/src/me.js +77 -0
- package/dist/src/me.js.map +1 -0
- package/dist/src/run.d.ts +92 -0
- package/dist/src/run.d.ts.map +1 -0
- package/dist/src/run.js +83 -0
- package/dist/src/run.js.map +1 -0
- package/dist/src/types.d.ts +362 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +109 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/vars.d.ts +149 -0
- package/dist/src/vars.d.ts.map +1 -0
- package/dist/src/vars.js +149 -0
- package/dist/src/vars.js.map +1 -0
- package/dist/src/version.d.ts +14 -0
- package/dist/src/version.d.ts.map +1 -0
- package/dist/src/version.js +14 -0
- package/dist/src/version.js.map +1 -0
- package/dist/src/workflows.d.ts +180 -0
- package/dist/src/workflows.d.ts.map +1 -0
- package/dist/src/workflows.js +160 -0
- package/dist/src/workflows.js.map +1 -0
- package/package.json +36 -0
package/dist/src/vars.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.vars.*` — typed variables, addressed the way the server addresses
|
|
3
|
+
* them.
|
|
4
|
+
*
|
|
5
|
+
* Six operations, one HTTP call each. **Create by `name`, read by id or by
|
|
6
|
+
* name, update and delete by id** (`docs/implementation.md` §7, D6 amended by
|
|
7
|
+
* D12). No client-side list-then-filter: `getByName` targets a real route,
|
|
8
|
+
* `GET /vars/by-name/{name}` (verified live 2026-07-28).
|
|
9
|
+
*
|
|
10
|
+
* **There is no scoping query parameter on any variable operation, and this
|
|
11
|
+
* module cannot invent one.** Variables are scoped by tenant/subject only; the
|
|
12
|
+
* server's `vars` routes read no such parameter and the table has no column for
|
|
13
|
+
* it, while every document route does — so the two asset surfaces are
|
|
14
|
+
* deliberately asymmetric (`docs/implementation.md` §7, and `src/documents.ts`
|
|
15
|
+
* for the other half). The asymmetry is enforced structurally rather than by
|
|
16
|
+
* discipline: {@linkcode VarsHost} exposes the transport and **not** the
|
|
17
|
+
* client's resolved configuration, so nothing in this file can reach a default
|
|
18
|
+
* scope to send even by accident. Adding the parameter later, once the server
|
|
19
|
+
* honours it, is purely additive; adding it now would be an argument the server
|
|
20
|
+
* ignores — a lie that typechecks.
|
|
21
|
+
*
|
|
22
|
+
* @module
|
|
23
|
+
*/
|
|
24
|
+
import { path } from "./http.js";
|
|
25
|
+
import { unwrap } from "./types.js";
|
|
26
|
+
/**
|
|
27
|
+
* The `vars` namespace on a `W6wClient`.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const v = await client.vars.create({ name: "sender_email", type: "string", value: "a@b.c" });
|
|
32
|
+
* await client.vars.update(v.id, { value: "c@d.e" });
|
|
33
|
+
* await client.vars.delete(v.id);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export class VarsApi {
|
|
37
|
+
#host;
|
|
38
|
+
/**
|
|
39
|
+
* @param host - The client this namespace issues requests through.
|
|
40
|
+
*/
|
|
41
|
+
constructor(host) {
|
|
42
|
+
this.#host = host;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* List the caller's variables.
|
|
46
|
+
*
|
|
47
|
+
* @returns The variables, unwrapped from the `vars` envelope.
|
|
48
|
+
* @throws {ApiError} On any non-2xx.
|
|
49
|
+
*/
|
|
50
|
+
async list() {
|
|
51
|
+
const res = await this.#host.request({ method: "GET", path: "/vars" });
|
|
52
|
+
return unwrap(res, "vars");
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Fetch one variable by its server-issued id.
|
|
56
|
+
*
|
|
57
|
+
* @param id - The `var_…` id.
|
|
58
|
+
* @returns The variable.
|
|
59
|
+
* @throws {ApiError} `404 unknown_var` when there is no such id.
|
|
60
|
+
*/
|
|
61
|
+
async get(id) {
|
|
62
|
+
const res = await this.#host.request({ method: "GET", path: path `/vars/${id}` });
|
|
63
|
+
// The singular envelope key is `var` — a reserved word in TypeScript, so it
|
|
64
|
+
// is read as a property and never destructured into a binding.
|
|
65
|
+
return unwrap(res, "var");
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Fetch one variable by the `name` its author chose.
|
|
69
|
+
*
|
|
70
|
+
* The name is percent-encoded at interpolation by the `path` tag. The server's
|
|
71
|
+
* own rule (`^[a-z_][a-z0-9_]*$`) contains nothing that needs encoding — but
|
|
72
|
+
* that rule is the *server's* to enforce, and this method encodes rather than
|
|
73
|
+
* validates: a name the server accepts is sent as-is (encoded), and a name it
|
|
74
|
+
* rejects comes back as `400 invalid_name` from the one place that owns the
|
|
75
|
+
* rule, instead of as a client-side error that would go stale the moment the
|
|
76
|
+
* rule changed.
|
|
77
|
+
*
|
|
78
|
+
* @param name - The variable name, sent encoded and otherwise untouched.
|
|
79
|
+
* @returns The variable.
|
|
80
|
+
* @throws {ApiError} `404 unknown_var` when there is no such name.
|
|
81
|
+
*/
|
|
82
|
+
async getByName(name) {
|
|
83
|
+
const res = await this.#host.request({
|
|
84
|
+
method: "GET",
|
|
85
|
+
path: path `/vars/by-name/${name}`,
|
|
86
|
+
});
|
|
87
|
+
return unwrap(res, "var");
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Create a typed variable under a caller-chosen name.
|
|
91
|
+
*
|
|
92
|
+
* @param input - `name`, `type` and `value` are required.
|
|
93
|
+
* @returns The created variable (the server answers `201`).
|
|
94
|
+
* @throws {ApiError} `409 var_exists` on a duplicate name — the code reaches the caller intact.
|
|
95
|
+
*/
|
|
96
|
+
async create(input) {
|
|
97
|
+
const res = await this.#host.request({
|
|
98
|
+
method: "POST",
|
|
99
|
+
path: "/vars",
|
|
100
|
+
// Assembled field by field rather than forwarded wholesale: the body that
|
|
101
|
+
// goes on the wire is exactly the four documented fields, and `undefined`
|
|
102
|
+
// ones are dropped by JSON serialisation.
|
|
103
|
+
body: {
|
|
104
|
+
name: input.name,
|
|
105
|
+
type: input.type,
|
|
106
|
+
value: input.value,
|
|
107
|
+
description: input.description,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
return unwrap(res, "var");
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Patch a variable's type, value or description.
|
|
114
|
+
*
|
|
115
|
+
* Addressed by id, never by name, and the name itself cannot be changed.
|
|
116
|
+
*
|
|
117
|
+
* @param id - The `var_…` id.
|
|
118
|
+
* @param patch - The fields to change; omitted fields are left alone.
|
|
119
|
+
* @returns The updated variable.
|
|
120
|
+
* @throws {ApiError} `404 unknown_var` when there is no such id.
|
|
121
|
+
*/
|
|
122
|
+
async update(id, patch) {
|
|
123
|
+
const res = await this.#host.request({
|
|
124
|
+
method: "PATCH",
|
|
125
|
+
path: path `/vars/${id}`,
|
|
126
|
+
body: {
|
|
127
|
+
type: patch.type,
|
|
128
|
+
value: patch.value,
|
|
129
|
+
description: patch.description,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
return unwrap(res, "var");
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Delete a variable.
|
|
136
|
+
*
|
|
137
|
+
* Returns nothing: the server's `{ok: true}` carries no information a caller
|
|
138
|
+
* can use. Deleting an unknown id is `404 unknown_var`, **not** a silent
|
|
139
|
+
* success — the delete is not idempotent and this method does not pretend
|
|
140
|
+
* otherwise.
|
|
141
|
+
*
|
|
142
|
+
* @param id - The `var_…` id.
|
|
143
|
+
* @throws {ApiError} `404 unknown_var` when there is no such id.
|
|
144
|
+
*/
|
|
145
|
+
async delete(id) {
|
|
146
|
+
await this.#host.request({ method: "DELETE", path: path `/vars/${id}` });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=vars.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vars.js","sourceRoot":"","sources":["../../src/vars.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAqB,IAAI,EAAuB,MAAM,WAAW,CAAC;AACzE,OAAO,EAAE,MAAM,EAA0B,MAAM,YAAY,CAAC;AAiD5D;;;;;;;;;GASG;AACH,MAAM,OAAO,OAAO;IACT,KAAK,CAAW;IAEzB;;OAEG;IACH,YAAY,IAAc;QACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAChF,OAAO,MAAM,CAAQ,GAAG,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAA,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1F,4EAA4E;QAC5E,+DAA+D;QAC/D,OAAO,MAAM,CAAM,GAAG,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,SAAS,CAAC,IAAY;QAC1B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAC5C,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAAI,CAAA,iBAAiB,IAAI,EAAE;SAClC,CAAC,CAAC;QACH,OAAO,MAAM,CAAM,GAAG,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,CAAC,KAAqB;QAChC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAC5C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,OAAO;YACb,0EAA0E;YAC1E,0EAA0E;YAC1E,0CAA0C;YAC1C,IAAI,EAAE;gBACJ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B;SACF,CAAC,CAAC;QACH,OAAO,MAAM,CAAM,GAAG,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,KAAe;QACtC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAC5C,MAAM,EAAE,OAAO;YACf,IAAI,EAAE,IAAI,CAAA,SAAS,EAAE,EAAE;YACvB,IAAI,EAAE;gBACJ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B;SACF,CAAC,CAAC;QACH,OAAO,MAAM,CAAM,GAAG,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAA,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;IACnF,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The published version of this package.
|
|
3
|
+
*
|
|
4
|
+
* It is the same string as `deno.json`'s `version`, `package.json`'s `version`
|
|
5
|
+
* and the monorepo's `packages/wrappers/VERSION` — the single source of truth all
|
|
6
|
+
* three w6w wrappers publish under (see `docs/parity.md`). `tests/version_test.ts`
|
|
7
|
+
* fails if any of those four disagree, so this constant cannot drift silently.
|
|
8
|
+
*
|
|
9
|
+
* The explicit `: string` annotation is required, not decorative: JSR publishes
|
|
10
|
+
* this file as TypeScript source and rejects inferred public types ("no slow
|
|
11
|
+
* types").
|
|
12
|
+
*/
|
|
13
|
+
export declare const VERSION: string;
|
|
14
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO,EAAE,MAAgB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The published version of this package.
|
|
3
|
+
*
|
|
4
|
+
* It is the same string as `deno.json`'s `version`, `package.json`'s `version`
|
|
5
|
+
* and the monorepo's `packages/wrappers/VERSION` — the single source of truth all
|
|
6
|
+
* three w6w wrappers publish under (see `docs/parity.md`). `tests/version_test.ts`
|
|
7
|
+
* fails if any of those four disagree, so this constant cannot drift silently.
|
|
8
|
+
*
|
|
9
|
+
* The explicit `: string` annotation is required, not decorative: JSR publishes
|
|
10
|
+
* this file as TypeScript source and rejects inferred public types ("no slow
|
|
11
|
+
* types").
|
|
12
|
+
*/
|
|
13
|
+
export const VERSION = "0.1.0";
|
|
14
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,OAAO,GAAW,OAAO,CAAC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.workflows.*` — discovery and the typed run.
|
|
3
|
+
*
|
|
4
|
+
* Two operations: `list` (T2.1.4) and `run` (T2.1.5). `list` earns its place in
|
|
5
|
+
* a minimal surface for the same reason `connections.list` does (D4): it is how
|
|
6
|
+
* a caller discovers a `wf_…` id to pass to `run`.
|
|
7
|
+
*
|
|
8
|
+
* ── `run`, and the three things this API gets called wrong ──
|
|
9
|
+
* 1. **`202` is success.** No `wait` → the run is queued and the server answers
|
|
10
|
+
* `202 {runId, status:"queued"}`. With `?wait=true` and a timeout → `202`
|
|
11
|
+
* again, with the current status. Neither raises.
|
|
12
|
+
* 2. **A failed run is data.** `?wait=true` on a run that failed is a plain
|
|
13
|
+
* `200` carrying `status: "failed"` and an `error`. This module returns it
|
|
14
|
+
* like any other result. Mapping it to an exit code is the CLI's job
|
|
15
|
+
* (`cli.exitCodes` in `endpoints.json`), not the SDK's.
|
|
16
|
+
* 3. **No client-side polling.** The server already polls internally for
|
|
17
|
+
* `?wait=true`, up to its own `RUN_WAIT_TIMEOUT_SEC`. The studio's 600 × 500 ms
|
|
18
|
+
* browser loop predates that and is deliberately **not** transcribed
|
|
19
|
+
* (`docs/implementation.md` §4): three wrappers each re-implementing a poll
|
|
20
|
+
* would be three timeout policies and three retry-storm bugs to keep in sync.
|
|
21
|
+
* There is no timer, no delay and no retry anywhere in this package — a `202`
|
|
22
|
+
* hands the caller `runId` and lets them decide.
|
|
23
|
+
*
|
|
24
|
+
* Workflows are **project-scoped**, like documents and unlike vars: the route
|
|
25
|
+
* accepts an optional `?project=`, resolved per call, then from the client's
|
|
26
|
+
* default, and otherwise left to the server. This host therefore sees the
|
|
27
|
+
* client's resolved configuration, which `connections` and `vars` deliberately
|
|
28
|
+
* do not.
|
|
29
|
+
*
|
|
30
|
+
* ── Pagination ──
|
|
31
|
+
* The route is **not paginated today** and this module does not pretend
|
|
32
|
+
* otherwise: there is no `cursor` argument, no `cursor` field, and no
|
|
33
|
+
* client-side paging loop. `list` returns the unwrapped array, exactly as
|
|
34
|
+
* `docs/implementation.md` §6 pins it.
|
|
35
|
+
*
|
|
36
|
+
* That is not a corner this signature is painted into. A JavaScript array is an
|
|
37
|
+
* object, so the day the server grows a cursor the wrapper can return an array
|
|
38
|
+
* that carries it (`WorkflowSummary[] & {cursor?: string}`) and widen this
|
|
39
|
+
* return type to match — every existing caller, which only ever reads the list,
|
|
40
|
+
* keeps compiling and keeps working. Inventing the field now would put a key on
|
|
41
|
+
* the type that no server has ever sent, which is the failure mode
|
|
42
|
+
* `endpoints.json` actually warns about.
|
|
43
|
+
*
|
|
44
|
+
* @module
|
|
45
|
+
*/
|
|
46
|
+
import type { ResolvedConfig } from "./config.ts";
|
|
47
|
+
import { type HttpResponse, type RequestOptions } from "./http.ts";
|
|
48
|
+
import { type RunResult, type WorkflowSummary } from "./types.ts";
|
|
49
|
+
/**
|
|
50
|
+
* The slice of `W6wClient` this namespace needs: the transport, plus the
|
|
51
|
+
* resolved configuration it reads the **default project** out of. Structural
|
|
52
|
+
* rather than a concrete client type, so the namespace stays independently
|
|
53
|
+
* constructible in a test and this module never imports the client back.
|
|
54
|
+
*/
|
|
55
|
+
export interface WorkflowsHost {
|
|
56
|
+
/** The resolved configuration; only `project` is read. */
|
|
57
|
+
readonly config: ResolvedConfig;
|
|
58
|
+
/** Perform one request. */
|
|
59
|
+
request<T>(options: RequestOptions): Promise<HttpResponse<T>>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Per-call options for `workflows.list`.
|
|
63
|
+
*
|
|
64
|
+
* A named interface rather than a bare `project?: string` parameter, so the
|
|
65
|
+
* operation can accept a further argument later without changing its arity.
|
|
66
|
+
*/
|
|
67
|
+
export interface WorkflowListOptions {
|
|
68
|
+
/** Project id to scope this call to; overrides the client's default. */
|
|
69
|
+
project?: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Per-call options for `workflows.run`.
|
|
73
|
+
*
|
|
74
|
+
* **No `project` here, on purpose.** A `wf_…` id is unambiguous on its own, and
|
|
75
|
+
* `endpoints.json` gives this operation exactly four parameters — `id`, `wait`,
|
|
76
|
+
* `variables`, `trigger`. Sending a `?project=` the route does not read would be
|
|
77
|
+
* inventing a parameter.
|
|
78
|
+
*/
|
|
79
|
+
export interface WorkflowRunOptions {
|
|
80
|
+
/**
|
|
81
|
+
* Wait for the run to reach a terminal state before answering.
|
|
82
|
+
*
|
|
83
|
+
* Sent as `?wait=true` **only when `true`**: the server compares the raw query
|
|
84
|
+
* value to the string `"true"`, so `?wait=false` would mean the same thing as
|
|
85
|
+
* omitting it while looking like it meant something else.
|
|
86
|
+
*
|
|
87
|
+
* The wait happens **server-side**, bounded by the server's own timeout. On a
|
|
88
|
+
* timeout the answer is a `202` carrying the current status, which is a normal
|
|
89
|
+
* outcome — see {@linkcode WorkflowRunResult.terminal}.
|
|
90
|
+
*/
|
|
91
|
+
wait?: boolean;
|
|
92
|
+
/** Variables handed to the run, merged into its scope by the engine. Opaque pass-through. */
|
|
93
|
+
variables?: Record<string, unknown>;
|
|
94
|
+
/**
|
|
95
|
+
* What triggered the run; defaults to `"manual"` server-side.
|
|
96
|
+
*
|
|
97
|
+
* Typed as a plain `string` rather than a closed union: the value is a
|
|
98
|
+
* server-owned enum (`"manual" | "schedule" | "webhook" | "event" | "replay"`
|
|
99
|
+
* today) that the server may extend, and an SDK that froze the set would
|
|
100
|
+
* reject a value a newer server accepts.
|
|
101
|
+
*/
|
|
102
|
+
trigger?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* What `workflows.run` returns: the server's flat body, plus two signals derived
|
|
106
|
+
* locally.
|
|
107
|
+
*
|
|
108
|
+
* It **is** a `RunResult` — the wire fields are present under their wire names,
|
|
109
|
+
* unwrapped from nothing (this route has no envelope). The two extra fields
|
|
110
|
+
* exist because a caller otherwise cannot tell a queued run from a finished one
|
|
111
|
+
* without re-deriving the rule:
|
|
112
|
+
*
|
|
113
|
+
* - {@linkcode terminal} answers "has this run finished?" from the **run's own
|
|
114
|
+
* status**, which is the question a caller actually has.
|
|
115
|
+
* - {@linkcode httpStatus} is the transport's own answer (`200` finished in
|
|
116
|
+
* time, `202` still going), kept because it is the distinction the server
|
|
117
|
+
* makes and dropping it would leave a caller unable to tell a `?wait=` timeout
|
|
118
|
+
* from a run that was never waited on.
|
|
119
|
+
*/
|
|
120
|
+
export interface WorkflowRunResult extends RunResult {
|
|
121
|
+
/** `true` when `status` is `succeeded`, `failed` or `canceled`. */
|
|
122
|
+
terminal: boolean;
|
|
123
|
+
/** The HTTP status that carried this body: `200` terminal, `202` queued or still running. */
|
|
124
|
+
httpStatus: number;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The `workflows` namespace on a `W6wClient`.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* const active = (await client.workflows.list()).filter((w) => w.status === "active");
|
|
132
|
+
*
|
|
133
|
+
* const run = await client.workflows.run(active[0].id, { wait: true });
|
|
134
|
+
* if (run.status === "failed") console.error(run.error); // data, not an exception
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
export declare class WorkflowsApi {
|
|
138
|
+
#private;
|
|
139
|
+
/**
|
|
140
|
+
* @param host - The client this namespace issues requests through.
|
|
141
|
+
*/
|
|
142
|
+
constructor(host: WorkflowsHost);
|
|
143
|
+
/**
|
|
144
|
+
* List the caller's workflow definitions.
|
|
145
|
+
*
|
|
146
|
+
* The project this call is scoped to is the per-call argument first, then the
|
|
147
|
+
* client's default, then nothing at all — an absent value means "no
|
|
148
|
+
* `?project=`", which is how the caller asks for every project the credential
|
|
149
|
+
* can see.
|
|
150
|
+
*
|
|
151
|
+
* @param options - Optional per-call project scope.
|
|
152
|
+
* @returns The workflows, unwrapped from the `workflows` envelope.
|
|
153
|
+
* @throws {ApiError} On any non-2xx.
|
|
154
|
+
*/
|
|
155
|
+
list(options?: WorkflowListOptions): Promise<WorkflowSummary[]>;
|
|
156
|
+
/**
|
|
157
|
+
* Start a run of one workflow, optionally waiting for it to finish.
|
|
158
|
+
*
|
|
159
|
+
* Returns on **both** success statuses this route uses:
|
|
160
|
+
*
|
|
161
|
+
* | Call | HTTP | Body | `terminal` |
|
|
162
|
+
* |---|---|---|---|
|
|
163
|
+
* | no `wait` | `202` | `{runId, status:"queued"}` | `false` |
|
|
164
|
+
* | `wait: true`, finished in time | `200` | `{runId, status, output, error, steps}` | `true` |
|
|
165
|
+
* | `wait: true`, timed out | `202` | `{runId, status}` | `false` |
|
|
166
|
+
*
|
|
167
|
+
* **A run that failed is the second row, not an error**: `200` with
|
|
168
|
+
* `status: "failed"` and the failure in `error`. This method returns it. It
|
|
169
|
+
* raises only when the *request* failed — `404 unknown_workflow`, a rejected
|
|
170
|
+
* token, a transport failure.
|
|
171
|
+
*
|
|
172
|
+
* @param id - The `wf_…` id, percent-encoded into the path.
|
|
173
|
+
* @param options - `wait`, plus the `variables` and `trigger` that go in the body.
|
|
174
|
+
* @returns The run handle, its status, and the result when the run has one.
|
|
175
|
+
* @throws {ApiError} `404 unknown_workflow` when there is no such workflow.
|
|
176
|
+
* @throws {ApiError} `bad_response` when a success body is not a run object.
|
|
177
|
+
*/
|
|
178
|
+
run(id: string, options?: WorkflowRunOptions): Promise<WorkflowRunResult>;
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=workflows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../src/workflows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,KAAK,YAAY,EAAQ,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,EAEL,KAAK,SAAS,EAGd,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,2BAA2B;IAC3B,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/D;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6FAA6F;IAC7F,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,mEAAmE;IACnE,QAAQ,EAAE,OAAO,CAAC;IAClB,6FAA6F;IAC7F,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,YAAY;;IAGvB;;OAEG;gBACS,IAAI,EAAE,aAAa;IAI/B;;;;;;;;;;;OAWG;IACG,IAAI,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IASrE;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAyDhF"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.workflows.*` — discovery and the typed run.
|
|
3
|
+
*
|
|
4
|
+
* Two operations: `list` (T2.1.4) and `run` (T2.1.5). `list` earns its place in
|
|
5
|
+
* a minimal surface for the same reason `connections.list` does (D4): it is how
|
|
6
|
+
* a caller discovers a `wf_…` id to pass to `run`.
|
|
7
|
+
*
|
|
8
|
+
* ── `run`, and the three things this API gets called wrong ──
|
|
9
|
+
* 1. **`202` is success.** No `wait` → the run is queued and the server answers
|
|
10
|
+
* `202 {runId, status:"queued"}`. With `?wait=true` and a timeout → `202`
|
|
11
|
+
* again, with the current status. Neither raises.
|
|
12
|
+
* 2. **A failed run is data.** `?wait=true` on a run that failed is a plain
|
|
13
|
+
* `200` carrying `status: "failed"` and an `error`. This module returns it
|
|
14
|
+
* like any other result. Mapping it to an exit code is the CLI's job
|
|
15
|
+
* (`cli.exitCodes` in `endpoints.json`), not the SDK's.
|
|
16
|
+
* 3. **No client-side polling.** The server already polls internally for
|
|
17
|
+
* `?wait=true`, up to its own `RUN_WAIT_TIMEOUT_SEC`. The studio's 600 × 500 ms
|
|
18
|
+
* browser loop predates that and is deliberately **not** transcribed
|
|
19
|
+
* (`docs/implementation.md` §4): three wrappers each re-implementing a poll
|
|
20
|
+
* would be three timeout policies and three retry-storm bugs to keep in sync.
|
|
21
|
+
* There is no timer, no delay and no retry anywhere in this package — a `202`
|
|
22
|
+
* hands the caller `runId` and lets them decide.
|
|
23
|
+
*
|
|
24
|
+
* Workflows are **project-scoped**, like documents and unlike vars: the route
|
|
25
|
+
* accepts an optional `?project=`, resolved per call, then from the client's
|
|
26
|
+
* default, and otherwise left to the server. This host therefore sees the
|
|
27
|
+
* client's resolved configuration, which `connections` and `vars` deliberately
|
|
28
|
+
* do not.
|
|
29
|
+
*
|
|
30
|
+
* ── Pagination ──
|
|
31
|
+
* The route is **not paginated today** and this module does not pretend
|
|
32
|
+
* otherwise: there is no `cursor` argument, no `cursor` field, and no
|
|
33
|
+
* client-side paging loop. `list` returns the unwrapped array, exactly as
|
|
34
|
+
* `docs/implementation.md` §6 pins it.
|
|
35
|
+
*
|
|
36
|
+
* That is not a corner this signature is painted into. A JavaScript array is an
|
|
37
|
+
* object, so the day the server grows a cursor the wrapper can return an array
|
|
38
|
+
* that carries it (`WorkflowSummary[] & {cursor?: string}`) and widen this
|
|
39
|
+
* return type to match — every existing caller, which only ever reads the list,
|
|
40
|
+
* keeps compiling and keeps working. Inventing the field now would put a key on
|
|
41
|
+
* the type that no server has ever sent, which is the failure mode
|
|
42
|
+
* `endpoints.json` actually warns about.
|
|
43
|
+
*
|
|
44
|
+
* @module
|
|
45
|
+
*/
|
|
46
|
+
import { ApiError } from "./errors.js";
|
|
47
|
+
import { path } from "./http.js";
|
|
48
|
+
import { isTerminalRunStatus, unwrap, } from "./types.js";
|
|
49
|
+
/**
|
|
50
|
+
* The `workflows` namespace on a `W6wClient`.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* const active = (await client.workflows.list()).filter((w) => w.status === "active");
|
|
55
|
+
*
|
|
56
|
+
* const run = await client.workflows.run(active[0].id, { wait: true });
|
|
57
|
+
* if (run.status === "failed") console.error(run.error); // data, not an exception
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export class WorkflowsApi {
|
|
61
|
+
#host;
|
|
62
|
+
/**
|
|
63
|
+
* @param host - The client this namespace issues requests through.
|
|
64
|
+
*/
|
|
65
|
+
constructor(host) {
|
|
66
|
+
this.#host = host;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* List the caller's workflow definitions.
|
|
70
|
+
*
|
|
71
|
+
* The project this call is scoped to is the per-call argument first, then the
|
|
72
|
+
* client's default, then nothing at all — an absent value means "no
|
|
73
|
+
* `?project=`", which is how the caller asks for every project the credential
|
|
74
|
+
* can see.
|
|
75
|
+
*
|
|
76
|
+
* @param options - Optional per-call project scope.
|
|
77
|
+
* @returns The workflows, unwrapped from the `workflows` envelope.
|
|
78
|
+
* @throws {ApiError} On any non-2xx.
|
|
79
|
+
*/
|
|
80
|
+
async list(options) {
|
|
81
|
+
const res = await this.#host.request({
|
|
82
|
+
method: "GET",
|
|
83
|
+
path: "/workflows",
|
|
84
|
+
query: { project: options?.project ?? this.#host.config.project ?? undefined },
|
|
85
|
+
});
|
|
86
|
+
return unwrap(res, "workflows");
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Start a run of one workflow, optionally waiting for it to finish.
|
|
90
|
+
*
|
|
91
|
+
* Returns on **both** success statuses this route uses:
|
|
92
|
+
*
|
|
93
|
+
* | Call | HTTP | Body | `terminal` |
|
|
94
|
+
* |---|---|---|---|
|
|
95
|
+
* | no `wait` | `202` | `{runId, status:"queued"}` | `false` |
|
|
96
|
+
* | `wait: true`, finished in time | `200` | `{runId, status, output, error, steps}` | `true` |
|
|
97
|
+
* | `wait: true`, timed out | `202` | `{runId, status}` | `false` |
|
|
98
|
+
*
|
|
99
|
+
* **A run that failed is the second row, not an error**: `200` with
|
|
100
|
+
* `status: "failed"` and the failure in `error`. This method returns it. It
|
|
101
|
+
* raises only when the *request* failed — `404 unknown_workflow`, a rejected
|
|
102
|
+
* token, a transport failure.
|
|
103
|
+
*
|
|
104
|
+
* @param id - The `wf_…` id, percent-encoded into the path.
|
|
105
|
+
* @param options - `wait`, plus the `variables` and `trigger` that go in the body.
|
|
106
|
+
* @returns The run handle, its status, and the result when the run has one.
|
|
107
|
+
* @throws {ApiError} `404 unknown_workflow` when there is no such workflow.
|
|
108
|
+
* @throws {ApiError} `bad_response` when a success body is not a run object.
|
|
109
|
+
*/
|
|
110
|
+
async run(id, options) {
|
|
111
|
+
const res = await this.#host.request({
|
|
112
|
+
method: "POST",
|
|
113
|
+
path: path `/workflows/${id}/run`,
|
|
114
|
+
// `?wait=true` or no `wait` at all — never `?wait=false`, which the server
|
|
115
|
+
// reads as "no wait" anyway and which would misrepresent the request in a
|
|
116
|
+
// log or a proxy.
|
|
117
|
+
query: { wait: options?.wait ? true : undefined },
|
|
118
|
+
// Always a body, even when empty: the route parses one when the text is
|
|
119
|
+
// non-empty and defaults to `{}` otherwise, so `{}` and no body are the
|
|
120
|
+
// same request — and sending the object keeps the two optional fields at
|
|
121
|
+
// one place instead of behind a conditional.
|
|
122
|
+
body: { variables: options?.variables, trigger: options?.trigger },
|
|
123
|
+
});
|
|
124
|
+
const body = res.body;
|
|
125
|
+
// The `runId` and `status` checks are the guard, not decoration. An
|
|
126
|
+
// object-only check let `{}`, `[]`, `[{…}]` and `{"ok":true}` through and
|
|
127
|
+
// returned a `WorkflowRunResult` whose `runId: string` and `status:
|
|
128
|
+
// RunStatus` were **`undefined` at runtime** (measured) — a lie the compiler
|
|
129
|
+
// cannot catch, which becomes a `TypeError` somewhere in the caller minutes
|
|
130
|
+
// later. That is the failure this package's own `unwrap` exists to prevent.
|
|
131
|
+
//
|
|
132
|
+
// Requiring the two fields also subsumes the array case (`[].runId` is
|
|
133
|
+
// `undefined`), and makes this guard exactly as strict as its sibling in
|
|
134
|
+
// `src/run.ts`, which requires a string `kind`: two operations in one
|
|
135
|
+
// package must not disagree about what a malformed success body is. It
|
|
136
|
+
// keeps the lanes in step too — python's idiomatic `isinstance(body, dict)`
|
|
137
|
+
// rejects `[]` where `typeof [] === "object"` accepts it.
|
|
138
|
+
if (typeof body !== "object" || body === null ||
|
|
139
|
+
typeof body.runId !== "string" ||
|
|
140
|
+
typeof body.status !== "string") {
|
|
141
|
+
throw new ApiError(res.status, "bad_response", `Server returned a ${res.status} whose body is not a run object.`, body);
|
|
142
|
+
}
|
|
143
|
+
const run = body;
|
|
144
|
+
const status = run.status;
|
|
145
|
+
return {
|
|
146
|
+
// Spread first so any field a newer server adds survives; the normalised
|
|
147
|
+
// ones below then take their pinned shape.
|
|
148
|
+
...run,
|
|
149
|
+
runId: run.runId,
|
|
150
|
+
status,
|
|
151
|
+
// A `202` carries no `steps`. Normalised to `{}` rather than left absent,
|
|
152
|
+
// so a caller iterating a run's steps never has to branch on which status
|
|
153
|
+
// carried it — the same reason an empty list is `[]` and not `null`.
|
|
154
|
+
steps: run.steps ?? {},
|
|
155
|
+
terminal: isTerminalRunStatus(status),
|
|
156
|
+
httpStatus: res.status,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=workflows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflows.js","sourceRoot":"","sources":["../../src/workflows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAqB,IAAI,EAAuB,MAAM,WAAW,CAAC;AACzE,OAAO,EACL,mBAAmB,EAGnB,MAAM,GAEP,MAAM,YAAY,CAAC;AAmFpB;;;;;;;;;;GAUG;AACH,MAAM,OAAO,YAAY;IACd,KAAK,CAAgB;IAE9B;;OAEG;IACH,YAAY,IAAmB;QAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,IAAI,CAAC,OAA6B;QACtC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAC5C,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,SAAS,EAAE;SAC/E,CAAC,CAAC;QACH,OAAO,MAAM,CAAoB,GAAG,EAAE,WAAW,CAAC,CAAC;IACrD,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,GAAG,CAAC,EAAU,EAAE,OAA4B;QAChD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAC5C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAA,cAAc,EAAE,MAAM;YAChC,2EAA2E;YAC3E,0EAA0E;YAC1E,kBAAkB;YAClB,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE;YACjD,wEAAwE;YACxE,wEAAwE;YACxE,yEAAyE;YACzE,6CAA6C;YAC7C,IAAI,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;SACnE,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,oEAAoE;QACpE,0EAA0E;QAC1E,oEAAoE;QACpE,6EAA6E;QAC7E,4EAA4E;QAC5E,4EAA4E;QAC5E,EAAE;QACF,uEAAuE;QACvE,yEAAyE;QACzE,sEAAsE;QACtE,uEAAuE;QACvE,4EAA4E;QAC5E,0DAA0D;QAC1D,IACE,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;YACzC,OAAQ,IAA4B,CAAC,KAAK,KAAK,QAAQ;YACvD,OAAQ,IAA6B,CAAC,MAAM,KAAK,QAAQ,EACzD,CAAC;YACD,MAAM,IAAI,QAAQ,CAChB,GAAG,CAAC,MAAM,EACV,cAAc,EACd,qBAAqB,GAAG,CAAC,MAAM,kCAAkC,EACjE,IAAI,CACL,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,GAAG,IAA0B,CAAC;QACvC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAmB,CAAC;QACvC,OAAO;YACL,yEAAyE;YACzE,2CAA2C;YAC3C,GAAG,GAAG;YACN,KAAK,EAAE,GAAG,CAAC,KAAe;YAC1B,MAAM;YACN,0EAA0E;YAC1E,0EAA0E;YAC1E,qEAAqE;YACrE,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE;YACtB,QAAQ,EAAE,mBAAmB,CAAC,MAAM,CAAC;YACrC,UAAU,EAAE,GAAG,CAAC,MAAM;SACvB,CAAC;IACJ,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@w6w/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Typed client for the w6w HTTP API. Thin transport, auth and error mapping — nothing else.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/w6w-io/w6w-node.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/w6w-io/w6w-node#readme",
|
|
11
|
+
"bugs": "https://github.com/w6w-io/w6w-node/issues",
|
|
12
|
+
"keywords": ["w6w", "workflow", "sdk", "client", "api"],
|
|
13
|
+
"type": "module",
|
|
14
|
+
"types": "./dist/mod.d.ts",
|
|
15
|
+
"main": "./dist/mod.js",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/mod.d.ts",
|
|
19
|
+
"import": "./dist/mod.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": ["dist"],
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc -p tsconfig.build.json"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"typescript": "^5.7.2"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
}
|
|
36
|
+
}
|