@nodetool-ai/node-sdk 0.7.0-rc.23 → 0.8.2
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 +34 -0
- package/dist/.nodetool-build-stamp +1 -0
- package/dist/base-node.d.ts +285 -14
- package/dist/base-node.d.ts.map +1 -1
- package/dist/base-node.js +359 -49
- package/dist/base-node.js.map +1 -1
- package/dist/class-name-to-title.d.ts +26 -0
- package/dist/class-name-to-title.d.ts.map +1 -0
- package/dist/class-name-to-title.js +59 -0
- package/dist/class-name-to-title.js.map +1 -0
- package/dist/code-analysis.d.ts +234 -0
- package/dist/code-analysis.d.ts.map +1 -0
- package/dist/code-analysis.js +919 -0
- package/dist/code-analysis.js.map +1 -0
- package/dist/code-body.d.ts +61 -0
- package/dist/code-body.d.ts.map +1 -0
- package/dist/code-body.js +288 -0
- package/dist/code-body.js.map +1 -0
- package/dist/code-node-validation.d.ts +67 -0
- package/dist/code-node-validation.d.ts.map +1 -0
- package/dist/code-node-validation.js +540 -0
- package/dist/code-node-validation.js.map +1 -0
- package/dist/content-card.d.ts +30 -0
- package/dist/content-card.d.ts.map +1 -0
- package/dist/content-card.js +68 -0
- package/dist/content-card.js.map +1 -0
- package/dist/correlation-validation.d.ts +19 -0
- package/dist/correlation-validation.d.ts.map +1 -0
- package/dist/correlation-validation.js +101 -0
- package/dist/correlation-validation.js.map +1 -0
- package/dist/cost-estimate.d.ts +244 -0
- package/dist/cost-estimate.d.ts.map +1 -0
- package/dist/cost-estimate.js +637 -0
- package/dist/cost-estimate.js.map +1 -0
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +4 -1
- package/dist/decorators.js.map +1 -1
- package/dist/docs/nodes.d.ts.map +1 -1
- package/dist/docs/nodes.js +3 -2
- package/dist/docs/nodes.js.map +1 -1
- package/dist/docs/overview.d.ts.map +1 -1
- package/dist/docs/overview.js +4 -3
- package/dist/docs/overview.js.map +1 -1
- package/dist/docs/workflows.d.ts.map +1 -1
- package/dist/docs/workflows.js +10 -9
- package/dist/docs/workflows.js.map +1 -1
- package/dist/field-classification.d.ts +31 -0
- package/dist/field-classification.d.ts.map +1 -0
- package/dist/field-classification.js +58 -0
- package/dist/field-classification.js.map +1 -0
- package/dist/graph-validation.d.ts +239 -0
- package/dist/graph-validation.d.ts.map +1 -0
- package/dist/graph-validation.js +1174 -0
- package/dist/graph-validation.js.map +1 -0
- package/dist/index.d.ts +27 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -1
- package/dist/index.js.map +1 -1
- package/dist/js-script-link.d.ts +53 -0
- package/dist/js-script-link.d.ts.map +1 -0
- package/dist/js-script-link.js +58 -0
- package/dist/js-script-link.js.map +1 -0
- package/dist/js-script-materialize.d.ts +52 -0
- package/dist/js-script-materialize.d.ts.map +1 -0
- package/dist/js-script-materialize.js +24 -0
- package/dist/js-script-materialize.js.map +1 -0
- package/dist/manifest-node-values.d.ts +106 -0
- package/dist/manifest-node-values.d.ts.map +1 -0
- package/dist/manifest-node-values.js +195 -0
- package/dist/manifest-node-values.js.map +1 -0
- package/dist/metadata.d.ts +75 -3
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +132 -49
- package/dist/metadata.js.map +1 -1
- package/dist/node-metadata.d.ts.map +1 -1
- package/dist/node-metadata.js +61 -56
- package/dist/node-metadata.js.map +1 -1
- package/dist/node-type-inventory.d.ts +51 -0
- package/dist/node-type-inventory.d.ts.map +1 -0
- package/dist/node-type-inventory.js +121 -0
- package/dist/node-type-inventory.js.map +1 -0
- package/dist/nodes/test-nodes.d.ts +77 -30
- package/dist/nodes/test-nodes.d.ts.map +1 -1
- package/dist/nodes/test-nodes.js +2 -34
- package/dist/nodes/test-nodes.js.map +1 -1
- package/dist/pack-loader.d.ts +202 -0
- package/dist/pack-loader.d.ts.map +1 -0
- package/dist/pack-loader.js +529 -0
- package/dist/pack-loader.js.map +1 -0
- package/dist/port-types.d.ts +15 -0
- package/dist/port-types.d.ts.map +1 -0
- package/dist/port-types.js +72 -0
- package/dist/port-types.js.map +1 -0
- package/dist/pricing-bundle.d.ts +83 -0
- package/dist/pricing-bundle.d.ts.map +1 -0
- package/dist/pricing-bundle.js +82 -0
- package/dist/pricing-bundle.js.map +1 -0
- package/dist/pricing-params.d.ts +59 -0
- package/dist/pricing-params.d.ts.map +1 -0
- package/dist/pricing-params.js +282 -0
- package/dist/pricing-params.js.map +1 -0
- package/dist/python-package-scan.d.ts +8 -0
- package/dist/python-package-scan.d.ts.map +1 -1
- package/dist/python-package-scan.js +21 -8
- package/dist/python-package-scan.js.map +1 -1
- package/dist/registry.d.ts +105 -2
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +403 -30
- package/dist/registry.js.map +1 -1
- package/dist/sandbox-bridge-packs.d.ts +39 -0
- package/dist/sandbox-bridge-packs.d.ts.map +1 -0
- package/dist/sandbox-bridge-packs.js +249 -0
- package/dist/sandbox-bridge-packs.js.map +1 -0
- package/dist/sandbox-catalog-host.d.ts +31 -0
- package/dist/sandbox-catalog-host.d.ts.map +1 -0
- package/dist/sandbox-catalog-host.js +78 -0
- package/dist/sandbox-catalog-host.js.map +1 -0
- package/dist/sandbox-module-catalog.d.ts +14 -0
- package/dist/sandbox-module-catalog.d.ts.map +1 -0
- package/dist/sandbox-module-catalog.js +402 -0
- package/dist/sandbox-module-catalog.js.map +1 -0
- package/dist/sandbox-npm-artifacts.d.ts +56 -0
- package/dist/sandbox-npm-artifacts.d.ts.map +1 -0
- package/dist/sandbox-npm-artifacts.js +17 -0
- package/dist/sandbox-npm-artifacts.js.map +1 -0
- package/dist/sandbox-pack-discovery.d.ts +93 -0
- package/dist/sandbox-pack-discovery.d.ts.map +1 -0
- package/dist/sandbox-pack-discovery.js +807 -0
- package/dist/sandbox-pack-discovery.js.map +1 -0
- package/dist/search.d.ts +29 -1
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +136 -9
- package/dist/search.js.map +1 -1
- package/dist/type-compat.d.ts +36 -0
- package/dist/type-compat.d.ts.map +1 -0
- package/dist/type-compat.js +98 -0
- package/dist/type-compat.js.map +1 -0
- package/dist/type-predicates.d.ts +25 -0
- package/dist/type-predicates.d.ts.map +1 -0
- package/dist/type-predicates.js +31 -0
- package/dist/type-predicates.js.map +1 -0
- package/dist/validation.d.ts +18 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +70 -11
- package/dist/validation.js.map +1 -1
- package/dist/workflow-document-tools.d.ts +35 -0
- package/dist/workflow-document-tools.d.ts.map +1 -0
- package/dist/workflow-document-tools.js +402 -0
- package/dist/workflow-document-tools.js.map +1 -0
- package/dist/workflow-interface.d.ts +62 -0
- package/dist/workflow-interface.d.ts.map +1 -0
- package/dist/workflow-interface.js +351 -0
- package/dist/workflow-interface.js.map +1 -0
- package/package.json +67 -10
- package/dist/package-registry-client.d.ts +0 -12
- package/dist/package-registry-client.d.ts.map +0 -1
- package/dist/package-registry-client.js +0 -40
- package/dist/package-registry-client.js.map +0 -1
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static checks for a Code node (`nodetool.code.Code`) inside a workflow graph.
|
|
3
|
+
*
|
|
4
|
+
* The node's `code` property is the body of one async function that reads the
|
|
5
|
+
* node's dynamic inputs off an `inputs` object and sends its outputs through
|
|
6
|
+
* `emit`/`output` calls — or, when it calls neither, through the legacy
|
|
7
|
+
* returned object's keys. Nothing about that contract is enforced until the node runs, so a
|
|
8
|
+
* body that does not parse, reads an input the node does not have, or forgets
|
|
9
|
+
* an output handle that downstream nodes are wired to costs a whole run to
|
|
10
|
+
* discover. Everything here is decidable from the graph alone.
|
|
11
|
+
*
|
|
12
|
+
* Pure functions, no I/O — {@link validateCodeNodeBody} is called by
|
|
13
|
+
* `validateGraph` and unit-tested directly.
|
|
14
|
+
*/
|
|
15
|
+
import { SANDBOX_CAPABILITY_PACK } from "@nodetool-ai/protocol";
|
|
16
|
+
import { analyzeCodeBody, CODE_INPUTS_GLOBAL, dynamicModuleAccess, freeIdentifiers, inputsMemberReads, moduleDeclarationKinds, outputCallNames, parseCodeBody, returnShapes, staticImportSpecifiers, streamCallNames, typeofGuardedNames } from "./code-analysis.js";
|
|
17
|
+
import { usesEmitOutputContract, usesStreamInputContract } from "./code-body.js";
|
|
18
|
+
import { installHintFor } from "./sandbox-bridge-packs.js";
|
|
19
|
+
import { isString } from "./type-predicates.js";
|
|
20
|
+
/** Node types whose `code` property is a JavaScript sandbox body. */
|
|
21
|
+
export const JS_CODE_NODE_TYPES = new Set([
|
|
22
|
+
"nodetool.code.Code"
|
|
23
|
+
]);
|
|
24
|
+
export function isJsCodeNodeType(nodeType) {
|
|
25
|
+
return JS_CODE_NODE_TYPES.has(nodeType);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Names the QuickJS sandbox and the Code node itself put in scope.
|
|
29
|
+
*
|
|
30
|
+
* Mirrors the sandbox manifest in `@nodetool-ai/agents`
|
|
31
|
+
* (`src/code-gen/sandbox-manifest.ts`), which this package cannot import — the
|
|
32
|
+
* dependency runs the other way, and the manifest pulls in the QuickJS WASM
|
|
33
|
+
* runtime. A name missing here turns a legitimate bridge call into a bogus
|
|
34
|
+
* "not defined" error; a name that is not really in the sandbox hides a real
|
|
35
|
+
* one. The pinning test lives in
|
|
36
|
+
* `packages/agents/tests/sandbox-manifest-drift.test.ts`.
|
|
37
|
+
*/
|
|
38
|
+
export const SANDBOX_GLOBALS = new Set([
|
|
39
|
+
// Guest globals, as observed in the running QuickJS sandbox
|
|
40
|
+
"AggregateError", "Array", "ArrayBuffer", "BigInt", "BigInt64Array",
|
|
41
|
+
"BigUint64Array", "Boolean", "DataView", "Date", "Error",
|
|
42
|
+
"EvalError", "FinalizationRegistry", "Float32Array", "Float64Array",
|
|
43
|
+
"Infinity", "Int16Array", "Int32Array", "Int8Array",
|
|
44
|
+
"InternalError", "JSON", "Map", "Math", "NaN", "Number", "Object",
|
|
45
|
+
"Promise", "Proxy", "RangeError", "ReferenceError", "Reflect", "RegExp",
|
|
46
|
+
"Set", "SharedArrayBuffer", "String", "Symbol",
|
|
47
|
+
"SyntaxError", "TextDecoder", "TextEncoder", "TypeError", "URIError",
|
|
48
|
+
"URL", "URLSearchParams", "Uint16Array", "Uint32Array", "Uint8Array",
|
|
49
|
+
"Uint8ClampedArray", "WeakMap", "WeakRef", "WeakSet", "decodeURI",
|
|
50
|
+
"decodeURIComponent", "encodeURI", "encodeURIComponent", "escape",
|
|
51
|
+
"globalThis", "isFinite", "isNaN", "parseFloat", "parseInt",
|
|
52
|
+
"queueMicrotask", "undefined", "unescape",
|
|
53
|
+
// Host bridges
|
|
54
|
+
"console", "fetch", "crypto", "sleep", "getSecret", "workspace",
|
|
55
|
+
"assetToSandbox", "sandboxToAsset", "progress", "emit", "output", "format",
|
|
56
|
+
"image", "audio", "video", "canvas", "media", "stream",
|
|
57
|
+
// Pure guest helpers defined by the sandbox prelude
|
|
58
|
+
"toBase64", "fromBase64", "toHex", "fromHex",
|
|
59
|
+
"parallelMap", "createCanvas",
|
|
60
|
+
// The `nodetool` object model, plus the retired `tools` global — still
|
|
61
|
+
// defined, as a thrower that names the import replacing it, so a body that
|
|
62
|
+
// reads it gets that message at run time instead of a ReferenceError here.
|
|
63
|
+
"tools", "nodetool",
|
|
64
|
+
// Absent from this guest, but not user inputs either
|
|
65
|
+
"setTimeout", "clearTimeout", "setInterval", "clearInterval",
|
|
66
|
+
"setImmediate", "clearImmediate", "eval", "Function",
|
|
67
|
+
"btoa", "atob", "structuredClone", "Intl", "AbortController", "Blob",
|
|
68
|
+
"FormData", "Buffer", "Headers", "Request", "Response", "env", "process",
|
|
69
|
+
"performance", "uuid", "utf8Encode", "utf8Decode",
|
|
70
|
+
// JS literals that acorn parses as Identifier nodes
|
|
71
|
+
"true", "false", "null",
|
|
72
|
+
"this", "arguments", "self", "window", "document",
|
|
73
|
+
// Code node reserved props and the object its declared inputs arrive on
|
|
74
|
+
"code", "timeout", "state", "inputs",
|
|
75
|
+
// Sandbox internals
|
|
76
|
+
"__maxIter", "__secretScope"
|
|
77
|
+
]);
|
|
78
|
+
/**
|
|
79
|
+
* The subset of `SANDBOX_GLOBALS` the guest does not actually have. They stay
|
|
80
|
+
* in that set so neither the graph validator nor the editor's input inference
|
|
81
|
+
* turns one into a dynamic input handle, but a body that reads one gets told
|
|
82
|
+
* what to use instead.
|
|
83
|
+
*/
|
|
84
|
+
const ABSENT_GLOBALS = new Set([
|
|
85
|
+
"setTimeout", "clearTimeout", "setInterval", "clearInterval",
|
|
86
|
+
"setImmediate", "clearImmediate", "eval", "Function",
|
|
87
|
+
"btoa", "atob", "structuredClone", "Intl", "AbortController", "Blob",
|
|
88
|
+
"FormData",
|
|
89
|
+
// Removed guest names: deleted quickjs stubs and retired prelude aliases
|
|
90
|
+
"Buffer", "Headers", "Request", "Response", "env", "process",
|
|
91
|
+
"performance", "uuid", "utf8Encode", "utf8Decode"
|
|
92
|
+
]);
|
|
93
|
+
function formatNames(names) {
|
|
94
|
+
return names.map((name) => `"${name}"`).join(", ");
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Node builtins. The guest is QuickJS, not Node, and no pack is named after
|
|
98
|
+
* one — so an import of any of these resolves nowhere, whether or not the host
|
|
99
|
+
* running this check has a catalog to say so.
|
|
100
|
+
*/
|
|
101
|
+
const NODE_BUILTINS = new Set([
|
|
102
|
+
"assert", "buffer", "child_process", "cluster", "crypto", "dgram", "dns",
|
|
103
|
+
"events", "fs", "http", "http2", "https", "module", "net", "os", "path",
|
|
104
|
+
"perf_hooks", "process", "querystring", "readline", "stream", "string_decoder",
|
|
105
|
+
"timers", "tls", "tty", "url", "util", "v8", "vm", "worker_threads", "zlib"
|
|
106
|
+
]);
|
|
107
|
+
function isNodeBuiltin(specifier) {
|
|
108
|
+
return (specifier.startsWith("node:") ||
|
|
109
|
+
NODE_BUILTINS.has(specifier.split("/")[0] ?? ""));
|
|
110
|
+
}
|
|
111
|
+
/** NodeTool's own guest modules — not pack declarations. */
|
|
112
|
+
function isCapabilitySpecifier(specifier) {
|
|
113
|
+
return (specifier === SANDBOX_CAPABILITY_PACK ||
|
|
114
|
+
specifier.startsWith(`${SANDBOX_CAPABILITY_PACK}/`));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Check one Code node's body against the handles the graph gives it.
|
|
118
|
+
*
|
|
119
|
+
* A syntax error stops the analysis — every later check reads the AST, and
|
|
120
|
+
* reporting invented output problems on top of "line 3 is not valid JavaScript"
|
|
121
|
+
* only buries the one issue that matters.
|
|
122
|
+
*/
|
|
123
|
+
export function validateCodeNodeBody(input) {
|
|
124
|
+
const code = isString(input.code) ? input.code : "";
|
|
125
|
+
const declared = [...new Set(input.declaredOutputs)];
|
|
126
|
+
const connected = [...new Set(input.connectedOutputs ?? [])];
|
|
127
|
+
if (code.trim() === "") {
|
|
128
|
+
return declared.length > 0 || connected.length > 0
|
|
129
|
+
? [
|
|
130
|
+
{
|
|
131
|
+
severity: "error",
|
|
132
|
+
code: "code_no_return",
|
|
133
|
+
message: `The code is empty, so the output handle${declared.length + connected.length > 1 ? "s" : ""} ${formatNames(declared.length > 0 ? declared : connected)} never receive a value.`
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
: [];
|
|
137
|
+
}
|
|
138
|
+
const parsed = parseCodeBody(code);
|
|
139
|
+
if ("error" in parsed) {
|
|
140
|
+
const where = parsed.line === undefined ? "" : ` (line ${parsed.line})`;
|
|
141
|
+
return [
|
|
142
|
+
{
|
|
143
|
+
severity: "error",
|
|
144
|
+
code: "code_syntax",
|
|
145
|
+
message: `The code does not parse as JavaScript${where}: ${parsed.error}`
|
|
146
|
+
}
|
|
147
|
+
];
|
|
148
|
+
}
|
|
149
|
+
const issues = [];
|
|
150
|
+
if (moduleDeclarationKinds(parsed.statements).includes("export")) {
|
|
151
|
+
issues.push({
|
|
152
|
+
severity: "error",
|
|
153
|
+
code: "code_module",
|
|
154
|
+
message: "The code uses `export` at the top level. The body runs inside an async " +
|
|
155
|
+
"function, which cannot contain an export declaration. Write top-level " +
|
|
156
|
+
"statements only — do not wrap the body in `export async function run`."
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
const imported = staticImportSpecifiers(parsed.statements);
|
|
160
|
+
const builtins = [
|
|
161
|
+
...new Set(imported.filter(isNodeBuiltin))
|
|
162
|
+
].sort();
|
|
163
|
+
if (builtins.length > 0) {
|
|
164
|
+
issues.push({
|
|
165
|
+
severity: "error",
|
|
166
|
+
code: "code_module",
|
|
167
|
+
message: `The code imports ${formatNames(builtins)}. The sandbox is QuickJS, not Node — ` +
|
|
168
|
+
"it has no builtin modules. Use the sandbox API (fetch, workspace, crypto, " +
|
|
169
|
+
"media) or a sandbox pack instead."
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
// The `nodetool:` specifiers are the private host bridges behind a generated
|
|
173
|
+
// facade. The guest loader serves them to a facade and to nothing else, so a
|
|
174
|
+
// body importing one directly fails at run time.
|
|
175
|
+
const privateBridges = [
|
|
176
|
+
...new Set(imported.filter((specifier) => specifier.startsWith("nodetool:")))
|
|
177
|
+
].sort();
|
|
178
|
+
if (privateBridges.length > 0) {
|
|
179
|
+
issues.push({
|
|
180
|
+
severity: "error",
|
|
181
|
+
code: "code_module",
|
|
182
|
+
message: `The code imports ${formatNames(privateBridges)}, which the sandbox serves only ` +
|
|
183
|
+
"to a generated module facade. Import the pack whose facade uses it."
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const dynamic = dynamicModuleAccess(parsed.statements);
|
|
187
|
+
if (dynamic.dynamicImport || dynamic.require) {
|
|
188
|
+
const used = [
|
|
189
|
+
...(dynamic.dynamicImport ? ["import()"] : []),
|
|
190
|
+
...(dynamic.require ? ["require()"] : [])
|
|
191
|
+
];
|
|
192
|
+
issues.push({
|
|
193
|
+
severity: "error",
|
|
194
|
+
code: "code_module",
|
|
195
|
+
message: `The code uses \`${used.join("` and `")}\`, which the sandbox does not support — ` +
|
|
196
|
+
"the loader denies every dynamic resolution. Import the module with a static " +
|
|
197
|
+
"`import` at the top of the code."
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
issues.push(...catalogIssues(input.sandboxModuleCatalog, [
|
|
201
|
+
...new Set(imported.filter((specifier) => !isCapabilitySpecifier(specifier) &&
|
|
202
|
+
!specifier.startsWith("nodetool:") &&
|
|
203
|
+
!isNodeBuiltin(specifier)))
|
|
204
|
+
]
|
|
205
|
+
.sort()
|
|
206
|
+
.map((specifier) => ({ specifier }))));
|
|
207
|
+
// ── Names the body reads but nothing puts in scope ───────────────────────
|
|
208
|
+
// Declared inputs are deliberately NOT bare-name scope: they arrive on the
|
|
209
|
+
// `inputs` object, so reading one as a bare name is the ReferenceError the
|
|
210
|
+
// split below reports with the rewrite.
|
|
211
|
+
const inScope = new Set(input.availableInputs);
|
|
212
|
+
const free = freeIdentifiers(parsed.statements);
|
|
213
|
+
const guarded = typeofGuardedNames(parsed.statements);
|
|
214
|
+
const unbound = free.filter((name) => !guarded.has(name));
|
|
215
|
+
const absentNames = [
|
|
216
|
+
...new Set(unbound.filter((name) => ABSENT_GLOBALS.has(name)))
|
|
217
|
+
];
|
|
218
|
+
if (absentNames.length > 0) {
|
|
219
|
+
issues.push({
|
|
220
|
+
severity: "error",
|
|
221
|
+
code: "code_undefined_name",
|
|
222
|
+
message: `The code reads ${formatNames(absentNames.sort())}, which other JavaScript runtimes ` +
|
|
223
|
+
`have but this sandbox does not — ${absentNames.length > 1 ? "they throw" : "it throws"} ReferenceError. ` +
|
|
224
|
+
"Use the sandbox equivalent: toBase64/fromBase64 for base64, format.* for Intl, " +
|
|
225
|
+
"sleep for timers, JSON round-trip for a deep copy, crypto.randomUUID() for uuid, " +
|
|
226
|
+
"new TextEncoder()/new TextDecoder() for utf8Encode/utf8Decode, and plain " +
|
|
227
|
+
"fetch() objects instead of Headers/Request/Response."
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
// `require` already has its own issue above; reporting it again as an
|
|
231
|
+
// invented name would say the same thing twice with worse advice.
|
|
232
|
+
const undefinedNames = unbound.filter((name) => !SANDBOX_GLOBALS.has(name) &&
|
|
233
|
+
!ABSENT_GLOBALS.has(name) &&
|
|
234
|
+
!(name === "require" && dynamic.require));
|
|
235
|
+
// A declared input read as a bare name: the pre-`inputs` form. It is a
|
|
236
|
+
// reference to that input, so the unused check below must not also complain.
|
|
237
|
+
const bareInputReads = undefinedNames.filter((name) => inScope.has(name));
|
|
238
|
+
if (undefinedNames.length > 0) {
|
|
239
|
+
const asInputs = [...new Set(bareInputReads)].sort();
|
|
240
|
+
// An input name reads as a bare identifier only in the pre-`inputs` form,
|
|
241
|
+
// which is now a ReferenceError. Naming the rewrite beats "fix the name"
|
|
242
|
+
// for the one mistake every migrated body makes.
|
|
243
|
+
const rest = undefinedNames.filter((name) => !inScope.has(name)).sort();
|
|
244
|
+
if (asInputs.length > 0) {
|
|
245
|
+
issues.push({
|
|
246
|
+
severity: "error",
|
|
247
|
+
code: "code_undefined_name",
|
|
248
|
+
message: `The code reads ${formatNames(asInputs)} as ${asInputs.length > 1 ? "bare names" : "a bare name"}, but ` +
|
|
249
|
+
`${asInputs.length > 1 ? "they are inputs" : "it is an input"} of this node — inputs arrive on the \`${CODE_INPUTS_GLOBAL}\` ` +
|
|
250
|
+
`object. Use ${asInputs.map((n) => `\`${CODE_INPUTS_GLOBAL}.${n}\``).join(", ")}.`
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (rest.length > 0) {
|
|
254
|
+
issues.push({
|
|
255
|
+
severity: "error",
|
|
256
|
+
code: "code_undefined_name",
|
|
257
|
+
message: `The code reads ${formatNames(rest)}, which ${rest.length > 1 ? "are" : "is"} neither a sandbox API ` +
|
|
258
|
+
`nor an input of this node — the sandbox throws ReferenceError. Declare ` +
|
|
259
|
+
`${rest.length > 1 ? "them" : "it"} as ${rest.length > 1 ? "dynamic inputs and read them" : "a dynamic input and read it"} off ` +
|
|
260
|
+
`\`${CODE_INPUTS_GLOBAL}\`, or fix the name.`
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const { names: inputsRead, opaque: inputsOpaque } = inputsMemberReads(parsed.statements);
|
|
265
|
+
const unknownInputs = [
|
|
266
|
+
...new Set(inputsRead.filter((name) => !inScope.has(name)))
|
|
267
|
+
].sort();
|
|
268
|
+
if (unknownInputs.length > 0) {
|
|
269
|
+
issues.push({
|
|
270
|
+
severity: "error",
|
|
271
|
+
code: "code_undefined_input",
|
|
272
|
+
message: `The code reads ${unknownInputs.map((n) => `\`${CODE_INPUTS_GLOBAL}.${n}\``).join(", ")}, which ` +
|
|
273
|
+
`${unknownInputs.length > 1 ? "are not inputs" : "is not an input"} of this node — the value is undefined at run time. ` +
|
|
274
|
+
`Declare ${unknownInputs.length > 1 ? "them" : "it"} as ${unknownInputs.length > 1 ? "dynamic inputs" : "a dynamic input"}, or fix the name.`
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
// ── Input streams ────────────────────────────────────────────────────────
|
|
278
|
+
// A body that calls `stream` runs once and drains its inbox itself. Its
|
|
279
|
+
// handles are named the same way its outputs are, so they are checkable the
|
|
280
|
+
// same way — and the split between configured values (`inputs`) and edge data
|
|
281
|
+
// (`stream`) is the one footgun the contract creates, closed here.
|
|
282
|
+
const streaming = usesStreamInputContract(code);
|
|
283
|
+
const streams = streamCallNames(parsed.statements);
|
|
284
|
+
const connectedInputs = new Set(input.connectedInputs ?? []);
|
|
285
|
+
if (streaming) {
|
|
286
|
+
const unknownStreams = [
|
|
287
|
+
...new Set(streams.names.filter((name) => !inScope.has(name)))
|
|
288
|
+
].sort();
|
|
289
|
+
if (unknownStreams.length > 0) {
|
|
290
|
+
issues.push({
|
|
291
|
+
severity: "error",
|
|
292
|
+
code: "code_undefined_stream",
|
|
293
|
+
message: `The code takes from ${formatNames(unknownStreams)}, which ` +
|
|
294
|
+
`${unknownStreams.length > 1 ? "are not inputs" : "is not an input"} of this node — the stream never yields. ` +
|
|
295
|
+
`Declare ${unknownStreams.length > 1 ? "them" : "it"} as ${unknownStreams.length > 1 ? "dynamic inputs" : "a dynamic input"}, or fix the name.`
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
if (streams.nonLiteral) {
|
|
299
|
+
issues.push({
|
|
300
|
+
severity: "warning",
|
|
301
|
+
code: "code_stream_dynamic_name",
|
|
302
|
+
message: "The code calls `stream` with a handle name that is not a string literal, " +
|
|
303
|
+
"so the stream names cannot be checked statically. Pass a literal name to " +
|
|
304
|
+
"have them checked."
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
const unconnectedStreams = [
|
|
308
|
+
...new Set(streams.names.filter((name) => inScope.has(name) && !connectedInputs.has(name)))
|
|
309
|
+
].sort();
|
|
310
|
+
if (unconnectedStreams.length > 0) {
|
|
311
|
+
issues.push({
|
|
312
|
+
severity: "warning",
|
|
313
|
+
code: "code_unconnected_stream",
|
|
314
|
+
message: `The code takes from ${formatNames(unconnectedStreams)}, which no incoming edge feeds — ` +
|
|
315
|
+
`the stream completes immediately and yields nothing. Connect an upstream node, ` +
|
|
316
|
+
`or read the node's configured value with ${unconnectedStreams.map((n) => `\`${CODE_INPUTS_GLOBAL}.${n}\``).join(", ")}.`
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
const streamedThroughInputs = [
|
|
320
|
+
...new Set(inputsRead.filter((name) => connectedInputs.has(name)))
|
|
321
|
+
].sort();
|
|
322
|
+
if (streamedThroughInputs.length > 0) {
|
|
323
|
+
issues.push({
|
|
324
|
+
severity: "error",
|
|
325
|
+
code: "code_stream_input_read",
|
|
326
|
+
message: `The code reads ${streamedThroughInputs.map((n) => `\`${CODE_INPUTS_GLOBAL}.${n}\``).join(", ")}, which ` +
|
|
327
|
+
`${streamedThroughInputs.length > 1 ? "incoming edges feed" : "an incoming edge feeds"} — in a streaming body ` +
|
|
328
|
+
`\`${CODE_INPUTS_GLOBAL}\` carries only the node's configured values, never edge data. Use ` +
|
|
329
|
+
`${streamedThroughInputs.map((n) => `\`stream("${n}")\``).join(", ")}.`
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
// An unresolvable read (`inputs[key]`, a spread) could touch any slot, so
|
|
334
|
+
// nothing is provably unused. A streaming body reads its connected handles
|
|
335
|
+
// through `stream`, and `stream.any()` reads every one of them.
|
|
336
|
+
const read = new Set([
|
|
337
|
+
...inputsRead,
|
|
338
|
+
...bareInputReads,
|
|
339
|
+
...(streaming ? streams.names : []),
|
|
340
|
+
...(streaming && streams.usesAny ? connectedInputs : [])
|
|
341
|
+
]);
|
|
342
|
+
const declaredInputsUnused = inputsOpaque || (streaming && streams.nonLiteral)
|
|
343
|
+
? []
|
|
344
|
+
: [...new Set(input.availableInputs.filter((name) => !read.has(name)))];
|
|
345
|
+
// ── Outputs ──────────────────────────────────────────────────────────────
|
|
346
|
+
// Two contracts, one probe — three states with streaming. A streaming body
|
|
347
|
+
// runs once, so the legacy return contract cannot apply to it whatever the
|
|
348
|
+
// emit probe says: its outputs go through `emit`/`output` or nowhere.
|
|
349
|
+
if (streaming && !usesEmitOutputContract(code)) {
|
|
350
|
+
issues.push({
|
|
351
|
+
severity: "error",
|
|
352
|
+
code: "code_stream_return_contract",
|
|
353
|
+
message: "The code calls `stream`, so it runs once and its return value is control " +
|
|
354
|
+
"flow, not outputs. Send every output through `output(name, value)` for a " +
|
|
355
|
+
"final value, or `emit(name, value)` to stream values as they are produced."
|
|
356
|
+
});
|
|
357
|
+
return withUnusedInputs(issues, declaredInputsUnused);
|
|
358
|
+
}
|
|
359
|
+
// A body that calls `emit`/`output` names its handles, so the return-path
|
|
360
|
+
// analysis below does not apply to it at all — its returns are control flow
|
|
361
|
+
// and carry nothing.
|
|
362
|
+
if (usesEmitOutputContract(code)) {
|
|
363
|
+
issues.push(...emitContractIssues(parsed.statements, declared, connected));
|
|
364
|
+
return withUnusedInputs(issues, declaredInputsUnused);
|
|
365
|
+
}
|
|
366
|
+
// ── Legacy contract: outputs, against every return path the parser can see ─
|
|
367
|
+
const { returns, fallsThrough } = analyzeCodeBody(parsed.statements);
|
|
368
|
+
const expected = declared.length > 0 ? declared : connected;
|
|
369
|
+
if (returns.length === 0) {
|
|
370
|
+
if (expected.length > 0) {
|
|
371
|
+
issues.push({
|
|
372
|
+
severity: "error",
|
|
373
|
+
code: "code_no_return",
|
|
374
|
+
message: `The code never returns, so the output${expected.length > 1 ? "s" : ""} ${formatNames(expected)} stay${expected.length > 1 ? "" : "s"} empty. End it with \`return { ${expected.join(", ")} };\`.`
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
issues.push({
|
|
379
|
+
severity: "warning",
|
|
380
|
+
code: "code_no_return",
|
|
381
|
+
message: "The code never returns, so the node produces no output. Return an " +
|
|
382
|
+
"object — its keys become the node's output handles."
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
return withUnusedInputs(issues, declaredInputsUnused);
|
|
386
|
+
}
|
|
387
|
+
if (fallsThrough && expected.length > 0) {
|
|
388
|
+
issues.push({
|
|
389
|
+
severity: "warning",
|
|
390
|
+
code: "code_no_return",
|
|
391
|
+
message: `Execution can reach the end of the code without returning, so the output${expected.length > 1 ? "s" : ""} ${formatNames(expected)} would be empty on that path.`
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
const missingSeen = new Set();
|
|
395
|
+
const undeclaredSeen = new Set();
|
|
396
|
+
let reportedNonObject = false;
|
|
397
|
+
for (const statement of returns) {
|
|
398
|
+
for (const shape of returnShapes(statement.argument)) {
|
|
399
|
+
if (shape.notAnObject) {
|
|
400
|
+
if (expected.length > 0 && !reportedNonObject) {
|
|
401
|
+
reportedNonObject = true;
|
|
402
|
+
issues.push({
|
|
403
|
+
severity: "error",
|
|
404
|
+
code: "code_return_shape",
|
|
405
|
+
message: `A return path returns something that is not an object of outputs, so the declared output${expected.length > 1 ? "s" : ""} ${formatNames(expected)} ${expected.length > 1 ? "are" : "is"} never set. Every return must be an object carrying them.`
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
if (shape.opaque)
|
|
411
|
+
continue;
|
|
412
|
+
for (const name of expected) {
|
|
413
|
+
if (!shape.keys.has(name))
|
|
414
|
+
missingSeen.add(name);
|
|
415
|
+
}
|
|
416
|
+
for (const key of shape.keys) {
|
|
417
|
+
if (!declared.includes(key))
|
|
418
|
+
undeclaredSeen.add(key);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (missingSeen.size > 0) {
|
|
423
|
+
const missing = [...missingSeen].sort();
|
|
424
|
+
issues.push({
|
|
425
|
+
severity: "warning",
|
|
426
|
+
code: "code_missing_output",
|
|
427
|
+
message: `A return path omits the output${missing.length > 1 ? "s" : ""} ${formatNames(missing)}, which downstream nodes read as empty. Emit every output on every return path and branch with nodetool.control.If or nodetool.control.Switch instead.`
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
if (undeclaredSeen.size > 0) {
|
|
431
|
+
const undeclared = [...undeclaredSeen].sort();
|
|
432
|
+
issues.push({
|
|
433
|
+
severity: "warning",
|
|
434
|
+
code: "code_undeclared_output",
|
|
435
|
+
message: `The code returns ${formatNames(undeclared)}, which ${undeclared.length > 1 ? "are" : "is"} not declared as an output handle, so nothing downstream can read ${undeclared.length > 1 ? "them" : "it"}.`
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
return withUnusedInputs(issues, declaredInputsUnused);
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Check a body that uses the `emit`/`output` contract.
|
|
442
|
+
*
|
|
443
|
+
* The rule is per-handle existence, not per-path coverage: a declared output
|
|
444
|
+
* needs one call naming it somewhere in the body, and branching freely is fine.
|
|
445
|
+
* A call whose handle is computed makes every name unknowable, so it downgrades
|
|
446
|
+
* the body to a warning instead of failing it on names this reader cannot see.
|
|
447
|
+
*/
|
|
448
|
+
function emitContractIssues(statements, declared, connected) {
|
|
449
|
+
const issues = [];
|
|
450
|
+
const { names, nonLiteral } = outputCallNames(statements);
|
|
451
|
+
const expected = declared.length > 0 ? declared : connected;
|
|
452
|
+
// A wired handle is a real handle even when the node forgot to declare it —
|
|
453
|
+
// the declared/connected split is the missing-output check's business.
|
|
454
|
+
const known = new Set([...declared, ...connected]);
|
|
455
|
+
const undeclared = [...new Set(names.filter((name) => !known.has(name)))].sort();
|
|
456
|
+
if (undeclared.length > 0) {
|
|
457
|
+
issues.push({
|
|
458
|
+
severity: "error",
|
|
459
|
+
code: "code_undeclared_output",
|
|
460
|
+
message: `The code sends to ${formatNames(undeclared)}, which ` +
|
|
461
|
+
`${undeclared.length > 1 ? "are not outputs" : "is not an output"} of this node — the call throws at run time. ` +
|
|
462
|
+
`Declare ${undeclared.length > 1 ? "them" : "it"} as ${undeclared.length > 1 ? "dynamic outputs" : "a dynamic output"}, or fix the name.`
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
if (nonLiteral) {
|
|
466
|
+
issues.push({
|
|
467
|
+
severity: "warning",
|
|
468
|
+
code: "code_output_dynamic_name",
|
|
469
|
+
message: "The code calls `emit` or `output` with a handle name that is not a string " +
|
|
470
|
+
"literal, so the output names cannot be checked statically. Pass a literal " +
|
|
471
|
+
"name to have them checked."
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
const missing = expected.filter((name) => !names.includes(name));
|
|
476
|
+
if (missing.length > 0) {
|
|
477
|
+
issues.push({
|
|
478
|
+
severity: "error",
|
|
479
|
+
code: "code_missing_output",
|
|
480
|
+
message: `The code never sends to the output${missing.length > 1 ? "s" : ""} ${formatNames(missing)}, so ` +
|
|
481
|
+
`${missing.length > 1 ? "they stay" : "it stays"} empty. Call ` +
|
|
482
|
+
`${missing.map((n) => `\`await output("${n}", value)\``).join(", ")} for a final value, ` +
|
|
483
|
+
"or `emit` to stream values as they are produced."
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
const valuedReturns = analyzeCodeBody(statements).returns.filter((statement) => statement.argument != null &&
|
|
488
|
+
!(statement.argument.type === "Identifier" &&
|
|
489
|
+
statement.argument.name === "undefined"));
|
|
490
|
+
if (valuedReturns.length > 0) {
|
|
491
|
+
issues.push({
|
|
492
|
+
severity: "warning",
|
|
493
|
+
code: "code_return_ignored",
|
|
494
|
+
message: "The code returns a value, but return values carry no outputs — use " +
|
|
495
|
+
"`output(name, value)` for a final value or `emit(name, value)` to stream. " +
|
|
496
|
+
"`return` here only exits the body early."
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
return issues;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Resolve the declarations against the installed catalog, offline.
|
|
503
|
+
*
|
|
504
|
+
* The catalog reports what only an installed host knows: a specifier no pack
|
|
505
|
+
* offers (error, naming the pack the specifier claims), and a pack version or
|
|
506
|
+
* content digest that moved since the workflow was saved (warning — resolution
|
|
507
|
+
* always uses what is installed).
|
|
508
|
+
*
|
|
509
|
+
* When the missing specifier is one NodeTool ships, the error also says which
|
|
510
|
+
* package to install. Every other unknown specifier gets no hint: guessing a
|
|
511
|
+
* package name for a workflow author is worse than saying nothing.
|
|
512
|
+
*/
|
|
513
|
+
function catalogIssues(catalog, declarations) {
|
|
514
|
+
if (!catalog || declarations.length === 0)
|
|
515
|
+
return [];
|
|
516
|
+
const { statuses } = catalog.resolveForExecution(declarations);
|
|
517
|
+
return statuses
|
|
518
|
+
.filter((status) => status.status === "error" || status.status === "warning")
|
|
519
|
+
.map((status) => {
|
|
520
|
+
const hint = status.code === "module-not-found" ? installHintFor(status.specifier ?? "") : undefined;
|
|
521
|
+
return {
|
|
522
|
+
severity: status.status === "error" ? "error" : "warning",
|
|
523
|
+
code: status.status === "error"
|
|
524
|
+
? "code_package_unavailable"
|
|
525
|
+
: "code_package_mismatch",
|
|
526
|
+
message: `${status.message} (pack "${status.packName}")${hint === undefined ? "" : ` ${hint}`}`
|
|
527
|
+
};
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
function withUnusedInputs(issues, unused) {
|
|
531
|
+
if (unused.length > 0) {
|
|
532
|
+
issues.push({
|
|
533
|
+
severity: "warning",
|
|
534
|
+
code: "code_unused_input",
|
|
535
|
+
message: `Input${unused.length > 1 ? "s" : ""} ${formatNames([...unused].sort())} ${unused.length > 1 ? "are" : "is"} never read by the code.`
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
return issues;
|
|
539
|
+
}
|
|
540
|
+
//# sourceMappingURL=code-node-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-node-validation.js","sourceRoot":"","sources":["../src/code-node-validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DeclaredOutputTypes } from "./base-node.js";
|
|
2
|
+
/** The parts of a node class this module reads and writes. */
|
|
3
|
+
interface ContentCardTarget {
|
|
4
|
+
metadataOutputTypes?: DeclaredOutputTypes | undefined;
|
|
5
|
+
outputTypes?: DeclaredOutputTypes;
|
|
6
|
+
body?: string | undefined;
|
|
7
|
+
}
|
|
8
|
+
/** True when a node with this primary output type should render a content card. */
|
|
9
|
+
export declare function isContentCardOutputType(outputType: string | undefined): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Type of the output slot the editor previews — the one `getNodeMetadata`
|
|
12
|
+
* puts at `outputs[0]`, so the resolution order matches it: an explicit
|
|
13
|
+
* `metadataOutputTypes` map wins over `outputTypes`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function primaryDeclaredOutputType(nodeClass: ContentCardTarget): string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Stamp `body = "content_card"` on a generated node class whose primary output
|
|
18
|
+
* is displayable. A class that already declares its own `body` keeps it —
|
|
19
|
+
* per-node overrides win (e.g. the "small" voice-picker bodies).
|
|
20
|
+
*
|
|
21
|
+
* Call after the class's output types are defined.
|
|
22
|
+
*/
|
|
23
|
+
export declare function applyContentCardBody(nodeClass: ContentCardTarget): void;
|
|
24
|
+
/**
|
|
25
|
+
* List form of {@link applyContentCardBody}, for hand-written node packs that
|
|
26
|
+
* export a node array. Returns `classes` so it can wrap the array literal.
|
|
27
|
+
*/
|
|
28
|
+
export declare function tagContentCardBodies<T extends readonly ContentCardTarget[]>(classes: T): T;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=content-card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-card.d.ts","sourceRoot":"","sources":["../src/content-card.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,8DAA8D;AAC9D,UAAU,iBAAiB;IACzB,mBAAmB,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACtD,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,mFAAmF;AACnF,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,OAAO,CAET;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,iBAAiB,GAC3B,MAAM,GAAG,SAAS,CAGpB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAWvE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE,EACzE,OAAO,EAAE,CAAC,GACT,CAAC,CAKH"}
|