@field/cascade 0.8.0 → 0.11.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/AGENTS.md +36 -3
- package/CHANGELOG.md +401 -0
- package/DESIGN.md +14 -0
- package/README.md +41 -26
- package/dist/assets/CodeEditor-4O7FQ__R.js +623 -0
- package/dist/assets/CodePanel-BU-autmq.js +2 -0
- package/dist/assets/{CustomNodeDialog-BQbEhIwL.js → CustomNodeDialog-BRpDfOV5.js} +1 -1
- package/dist/assets/OpenGraphDialog-BwbRlC0X.js +1 -0
- package/dist/assets/ProjectSettings-DLOXLxcA.js +2 -0
- package/dist/assets/SettingsDialog-Bz8JxISH.js +1 -0
- package/dist/assets/{VersionHistoryDialog-D6VBzSQ0.js → VersionHistoryDialog-D5Z0nJ5-.js} +2 -2
- package/dist/assets/{core-BInLG4gw.js → core-Yqi0Ni61.js} +8 -8
- package/dist/assets/{cssMode-DfR2qmYG.js → cssMode-CxUzc4vp.js} +1 -1
- package/dist/assets/definitions-GreEMXLV.js +1 -0
- package/dist/assets/{editor.api-Ck8_vgQV.js → editor.api-BNFb25CX.js} +1 -1
- package/dist/assets/{freemarker2-fVn10Wn3.js → freemarker2-0ZDnWxeM.js} +1 -1
- package/dist/assets/geo-u0n_jOsD.js +1 -0
- package/dist/assets/{handlebars-BCSchLT2.js → handlebars-Cy18MoaD.js} +1 -1
- package/dist/assets/{html-CVpSv_k9.js → html-B-2Dx7nq.js} +1 -1
- package/dist/assets/{htmlMode-Da4ESTv0.js → htmlMode-DUAc9B_d.js} +1 -1
- package/dist/assets/{image-BLn--oSF.js → image-cAa-Nu9O.js} +3 -3
- package/dist/assets/index-5ZtDAuy2.js +220 -0
- package/dist/assets/index-7vae6YFC.css +1 -0
- package/dist/assets/index-client-DqYmKstU.js +1 -0
- package/dist/assets/{javascript-BpX0Gvcf.js → javascript-DeQsDqP5.js} +1 -1
- package/dist/assets/{jsonMode-CsLqaou7.js → jsonMode-BiFwJVSk.js} +1 -1
- package/dist/assets/legacy-CTEeXeqF.js +2 -0
- package/dist/assets/{liquid-efUz51Wf.js → liquid-BLoHH68a.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-DCi5-K0n.js → lspLanguageFeatures-CNFgm1Kv.js} +1 -1
- package/dist/assets/math-DioIQOPJ.js +1 -0
- package/dist/assets/{mdx-DP_sjGVy.js → mdx-CFXQVNfs.js} +1 -1
- package/dist/assets/pop-DC_TQG9t.js +1 -0
- package/dist/assets/{python-aAuP3LUi.js → python-Cf7S7p2E.js} +1 -1
- package/dist/assets/{razor-7M6sMmC5.js → razor-CMHBcG-g.js} +1 -1
- package/dist/assets/studioScenes-8sq9FfFg.js +1 -0
- package/dist/assets/{tsMode-Bf4CnoYK.js → tsMode-BEih0GDj.js} +1 -1
- package/dist/assets/{typescript-ddhYBGyT.js → typescript-COEKYD_a.js} +1 -1
- package/dist/assets/{workers-X5la8DDT.js → workers-BNhAhMNn.js} +1 -1
- package/dist/assets/{xml-BzbXa3Ps.js → xml-CPiMpnPl.js} +1 -1
- package/dist/assets/{yaml-CXs-VzxL.js → yaml-Bgp1ITLR.js} +1 -1
- package/dist/cli/Graph-ZJJTRQTM.js +2975 -0
- package/dist/cli/chunk-2KXB47FP.js +115 -0
- package/dist/cli/chunk-35D343DC.js +1447 -0
- package/dist/cli/chunk-36P5K3SD.js +631 -0
- package/dist/cli/chunk-3JTJHF7V.js +267 -0
- package/dist/cli/chunk-4UDFYF5G.js +132 -0
- package/dist/cli/chunk-53NMBJAO.js +35 -0
- package/dist/cli/chunk-A4OAMOZH.js +310 -0
- package/dist/cli/chunk-BIJO5OFS.js +71 -0
- package/dist/cli/chunk-BP7UKF36.js +376 -0
- package/dist/cli/chunk-CKS2FQWR.js +89 -0
- package/dist/cli/chunk-CO22XHNG.js +593 -0
- package/dist/cli/chunk-D6BUOHUG.js +634 -0
- package/dist/cli/chunk-DEQSEFFH.js +153 -0
- package/dist/cli/chunk-DUIUFVU2.js +241 -0
- package/dist/cli/chunk-EUIAC3U3.js +3006 -0
- package/dist/cli/chunk-FCDXJ6EK.js +2208 -0
- package/dist/cli/chunk-GFS6W3C5.js +308 -0
- package/dist/cli/chunk-HFHWYL55.js +139 -0
- package/dist/cli/chunk-HSNOBIVT.js +263 -0
- package/dist/cli/chunk-ICH7N5PN.js +26 -0
- package/dist/cli/chunk-J7VK7MNF.js +418 -0
- package/dist/cli/chunk-KH4MUBKF.js +1551 -0
- package/dist/cli/chunk-MIIEFUGG.js +623 -0
- package/dist/cli/chunk-OWWBYLHC.js +136 -0
- package/dist/cli/chunk-POMMNKZZ.js +672 -0
- package/dist/cli/chunk-QBBKRNGY.js +90 -0
- package/dist/cli/chunk-QQPA2ZHH.js +273 -0
- package/dist/cli/chunk-RLCAJBVR.js +224 -0
- package/dist/cli/chunk-RQZ4SX5R.js +1125 -0
- package/dist/cli/chunk-RUU3YWXU.js +99 -0
- package/dist/cli/chunk-RXDIMXN5.js +98 -0
- package/dist/cli/chunk-SGJAET2L.js +197 -0
- package/dist/cli/chunk-VVGSLVSF.js +151 -0
- package/dist/cli/chunk-WD62JIP6.js +118 -0
- package/dist/cli/chunk-WIH4TEIS.js +104 -0
- package/dist/cli/chunk-WKURDVYP.js +1119 -0
- package/dist/cli/chunk-WPUDGEFY.js +20 -0
- package/dist/cli/chunk-XWDSKG7N.js +1301 -0
- package/dist/cli/chunk-YAT5Y25U.js +121 -0
- package/dist/cli/chunk-ZL4JTG5Y.js +37 -0
- package/dist/cli/cliCommands-UQSFGEHF.js +3464 -0
- package/dist/cli/commands-Q23M26QM.js +1292 -0
- package/dist/cli/definitions-HF2FTHYU.js +32 -0
- package/dist/cli/doctorCommand-B7BPQMN6.js +76 -0
- package/dist/cli/edit-JHCPTQFT.js +28 -0
- package/dist/cli/editorCommands-UIF5YLUZ.js +33 -0
- package/dist/cli/encode-HAUZTYPT.js +17 -0
- package/dist/cli/frames-LSAUBZ7P.js +16 -0
- package/dist/cli/geo-4RNK3QVN.js +43 -0
- package/dist/cli/graphCommands-6BMAKGQE.js +184 -0
- package/dist/cli/graphFile-VPSQ6OF7.js +286 -0
- package/dist/cli/headlessCanvas-5XLDZT7M.js +15 -0
- package/dist/cli/helpCommand-3VRE3KVO.js +155 -0
- package/dist/cli/index.js +106 -14207
- package/dist/cli/math-ZRMLKU2D.js +16 -0
- package/dist/cli/mcp-ZLEEMYGF.js +164 -0
- package/dist/cli/parity-KINARCP2.js +328 -0
- package/dist/cli/pop-USDFXB7H.js +39 -0
- package/dist/cli/project-K3QIPGBB.js +12 -0
- package/dist/cli/projectDefinition-DMTZN2NE.js +27 -0
- package/dist/cli/projectRuntime-Z5PJOH47.js +48 -0
- package/dist/cli/registerStandardNodes-S2VLMF6J.js +3081 -0
- package/dist/cli/render-YURAPPUI.js +436 -0
- package/dist/cli/runCommand-PI764LEG.js +198 -0
- package/dist/cli/runner-RA6UKEPD.js +37 -0
- package/dist/cli/runtime/image.ts +277 -0
- package/dist/cli/runtime/stage.ts +74 -11
- package/dist/cli/stageRunner-KUNIMQKJ.js +10 -0
- package/dist/cli/verbs-RCE3K4VQ.js +19 -0
- package/dist/cli/webBuild-GT4PZT5D.js +37 -0
- package/dist/contracts/bundle.d.ts +75 -0
- package/dist/contracts/bundle.js +112 -0
- package/dist/contracts/definition.d.ts +67 -4
- package/dist/contracts/document.d.ts +29 -0
- package/dist/contracts/documentFormat.d.ts +18 -0
- package/dist/contracts/documentFormat.js +195 -0
- package/dist/contracts/editor.d.ts +189 -0
- package/dist/contracts/editor.js +2 -0
- package/dist/contracts/index.d.ts +3 -0
- package/dist/contracts/index.js +3 -0
- package/dist/contracts/validate.js +59 -3
- package/dist/contracts/values.d.ts +3 -3
- package/dist/contracts/values.js +1 -0
- package/dist/image.d.ts +141 -0
- package/dist/image.js +127 -0
- package/dist/index.html +4 -4
- package/dist/player/app.js +17 -5
- package/dist/player/editor.js +1919 -0
- package/dist/player/editorEngine.js +477 -0
- package/dist/runtime/builtins/core/bundle.d.ts +70 -0
- package/dist/runtime/builtins/core/bundle.js +81 -0
- package/dist/runtime/builtins/core/index.d.ts +3 -2
- package/dist/runtime/builtins/core/index.js +6 -2
- package/dist/runtime/builtins/core/routing.d.ts +27 -0
- package/dist/runtime/builtins/core/routing.js +28 -0
- package/dist/runtime/builtins/headless.d.ts +19 -0
- package/dist/runtime/builtins/headless.js +25 -0
- package/dist/runtime/builtins/image/contactSheet.d.ts +226 -0
- package/dist/runtime/builtins/image/contactSheet.js +199 -0
- package/dist/runtime/builtins/image/index.d.ts +9 -0
- package/dist/runtime/builtins/image/index.js +9 -0
- package/dist/runtime/edit/document.d.ts +94 -0
- package/dist/runtime/edit/document.js +194 -0
- package/dist/runtime/edit/graphEditor.d.ts +223 -0
- package/dist/runtime/edit/graphEditor.js +893 -0
- package/dist/runtime/edit/index.d.ts +12 -0
- package/dist/runtime/edit/index.js +6 -0
- package/dist/runtime/edit/layout.d.ts +50 -0
- package/dist/runtime/edit/layout.js +126 -0
- package/dist/runtime/edit/operations.d.ts +65 -0
- package/dist/runtime/edit/operations.js +57 -0
- package/dist/runtime/edit/parameters.d.ts +75 -0
- package/dist/runtime/edit/parameters.js +284 -0
- package/dist/runtime/edit/read.d.ts +35 -0
- package/dist/runtime/edit/read.js +65 -0
- package/dist/runtime/editor/index.d.ts +104 -0
- package/dist/runtime/editor/index.js +439 -0
- package/dist/runtime/expressions/bundlePaths.d.ts +37 -0
- package/dist/runtime/expressions/bundlePaths.js +55 -0
- package/dist/runtime/expressions/index.d.ts +2 -0
- package/dist/runtime/expressions/index.js +1 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/params/animator.d.ts +5 -0
- package/dist/runtime/params/animator.js +16 -0
- package/dist/runtime/runtime.js +238 -12
- package/dist/runtime/seed.d.ts +29 -0
- package/dist/runtime/seed.js +52 -0
- package/dist/runtime/types.d.ts +12 -0
- package/dist/stage.js +43 -9
- package/dist/studio/panel.d.ts +2 -0
- package/doc/CLI_REFERENCE.md +171 -0
- package/doc/EDITOR_EXPORT.md +235 -0
- package/doc/HEADLESS_GPU.md +27 -0
- package/doc/MCP.md +69 -0
- package/doc/NODE_REFERENCE.md +208 -0
- package/doc/PROJECT_AUTHORING.md +258 -1
- package/package.json +29 -8
- package/dist/assets/CodeEditor-BEk-kIBd.js +0 -623
- package/dist/assets/CodePanel-CeSdjXkg.js +0 -2
- package/dist/assets/ExportDialog-CjTbbTZJ.js +0 -358
- package/dist/assets/ExportDialog-DOq0flMV.css +0 -1
- package/dist/assets/OpenGraphDialog-DCwH9itM.js +0 -1
- package/dist/assets/ProjectSettings-Dg7M5xt9.js +0 -2
- package/dist/assets/SettingsDialog-e7GgsjB9.js +0 -1
- package/dist/assets/definitions-DZpOjWKR.js +0 -1
- package/dist/assets/geo-D2VPjAdt.js +0 -1
- package/dist/assets/index-CMiBdEuT.js +0 -212
- package/dist/assets/index-DMIuml9a.css +0 -1
- package/dist/assets/index-client-BI2H82FJ.js +0 -1
- package/dist/assets/legacy-ZA7textG.js +0 -2
- package/dist/assets/math-B6hpxPJO.js +0 -1
- package/dist/assets/pop-CYUIjT6x.js +0 -1
- package/dist/assets/projectSettingsApi-C1WvIwfP.js +0 -1
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isGeometrySerialized
|
|
3
|
+
} from "./chunk-J7VK7MNF.js";
|
|
4
|
+
import {
|
|
5
|
+
CORE_TYPES
|
|
6
|
+
} from "./chunk-BIJO5OFS.js";
|
|
7
|
+
|
|
8
|
+
// packages/contracts/src/validate.ts
|
|
9
|
+
var IDENTIFIER = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
10
|
+
var NAMESPACED = /^[a-z][a-z0-9-]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/;
|
|
11
|
+
var RESERVED = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
12
|
+
var CORE = new Set(CORE_TYPES);
|
|
13
|
+
var CONTROLS = /* @__PURE__ */ new Set(["number", "slider", "range", "int", "boolean", "text", "textarea", "select", "vector", "matrix", "color", "image", "asset"]);
|
|
14
|
+
var CAPABILITIES_BY_ENVIRONMENT = {
|
|
15
|
+
portable: ["assets", "media", "gpu"],
|
|
16
|
+
browser: ["assets", "media", "gpu"],
|
|
17
|
+
server: ["files", "assets", "media", "python", "shell", "gpu"]
|
|
18
|
+
};
|
|
19
|
+
var ALLOWED = CAPABILITIES_BY_ENVIRONMENT;
|
|
20
|
+
var fields = (names) => new Set(names.split(" "));
|
|
21
|
+
var TOP_FIELDS = fields(
|
|
22
|
+
"apiVersion runsOn container capabilities source label description icon inputs outputs props"
|
|
23
|
+
);
|
|
24
|
+
var DATA_FIELDS = fields(
|
|
25
|
+
"kind type default description variadic min max step accept control options schema fields"
|
|
26
|
+
);
|
|
27
|
+
var OUTPUT_FIELDS = fields("kind type description schema fields");
|
|
28
|
+
var PROP_FIELDS = fields(
|
|
29
|
+
"type default label description min max step accept control options expression action"
|
|
30
|
+
);
|
|
31
|
+
function diagnostic(code, message, path) {
|
|
32
|
+
return { phase: "definition", code: `definition/${code}`, message, path };
|
|
33
|
+
}
|
|
34
|
+
function isRecord(value) {
|
|
35
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36
|
+
}
|
|
37
|
+
function validType(type) {
|
|
38
|
+
return typeof type === "string" && (CORE.has(type) || NAMESPACED.test(type));
|
|
39
|
+
}
|
|
40
|
+
function finiteJson(value) {
|
|
41
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
42
|
+
return true;
|
|
43
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
44
|
+
if (Array.isArray(value)) return value.every(finiteJson);
|
|
45
|
+
return isRecord(value) && Object.values(value).every(finiteJson);
|
|
46
|
+
}
|
|
47
|
+
function unknownFields(value, allowed, path) {
|
|
48
|
+
return Object.keys(value).filter((key) => !allowed.has(key)).map(
|
|
49
|
+
(key) => diagnostic(
|
|
50
|
+
"unknown-field",
|
|
51
|
+
`${path}.${key} is not allowed`,
|
|
52
|
+
`${path}.${key}`
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
function defaultMatches(type, value) {
|
|
57
|
+
if (!finiteJson(value)) return false;
|
|
58
|
+
if (type === "geometry") return isGeometrySerialized(value);
|
|
59
|
+
if (type === "float") return typeof value === "number";
|
|
60
|
+
if (type === "int") return typeof value === "number";
|
|
61
|
+
if (type === "bool") return typeof value === "boolean";
|
|
62
|
+
if (type === "string") return typeof value === "string";
|
|
63
|
+
const lengths = {
|
|
64
|
+
vec2: 2,
|
|
65
|
+
vec3: 3,
|
|
66
|
+
vec4: 4,
|
|
67
|
+
vec2i: 2,
|
|
68
|
+
vec3i: 3,
|
|
69
|
+
vec4i: 4,
|
|
70
|
+
mat2: 4,
|
|
71
|
+
mat3: 9,
|
|
72
|
+
mat4: 16,
|
|
73
|
+
color: 4
|
|
74
|
+
};
|
|
75
|
+
const length = lengths[type];
|
|
76
|
+
return length === void 0 || Array.isArray(value) && value.length === length && value.every(
|
|
77
|
+
(item) => type.endsWith("i") ? Number.isInteger(item) : typeof item === "number"
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
function validateNodeDefinition(value) {
|
|
81
|
+
if (!isRecord(value))
|
|
82
|
+
return [diagnostic("not-object", "Definition must be an object")];
|
|
83
|
+
const result = unknownFields(value, TOP_FIELDS, "definition");
|
|
84
|
+
const add = (code, message, path) => result.push(diagnostic(code, message, path));
|
|
85
|
+
const environment = value.runsOn;
|
|
86
|
+
if (value.apiVersion !== 1)
|
|
87
|
+
add("api-version", "apiVersion must be 1", "apiVersion");
|
|
88
|
+
if (!Object.prototype.hasOwnProperty.call(ALLOWED, String(environment)))
|
|
89
|
+
add("environment", "runsOn must be portable, browser, or server", "runsOn");
|
|
90
|
+
if (value.container !== void 0 && value.container !== "subnet" && value.container !== "feedback")
|
|
91
|
+
add("invalid-container", "container must be subnet or feedback", "container");
|
|
92
|
+
if (value.source !== void 0 && value.source !== "live")
|
|
93
|
+
add("invalid-source", 'source must be "live" when present', "source");
|
|
94
|
+
const allowed = ALLOWED[environment] ?? [];
|
|
95
|
+
if (value.capabilities !== void 0 && !Array.isArray(value.capabilities))
|
|
96
|
+
add(
|
|
97
|
+
"invalid-capabilities",
|
|
98
|
+
"capabilities must be an array",
|
|
99
|
+
"capabilities"
|
|
100
|
+
);
|
|
101
|
+
const seen = /* @__PURE__ */ new Set();
|
|
102
|
+
for (const [index, capability] of (Array.isArray(value.capabilities) ? value.capabilities : []).entries()) {
|
|
103
|
+
const path = `capabilities.${index}`;
|
|
104
|
+
if (!seen.has(capability) && !allowed.includes(capability))
|
|
105
|
+
add(
|
|
106
|
+
"capability-not-allowed",
|
|
107
|
+
`${String(capability)} is not available on ${String(environment)}`,
|
|
108
|
+
path
|
|
109
|
+
);
|
|
110
|
+
if (seen.has(capability))
|
|
111
|
+
add("duplicate-capability", `${String(capability)} is duplicated`, path);
|
|
112
|
+
seen.add(capability);
|
|
113
|
+
}
|
|
114
|
+
const inward = /* @__PURE__ */ new Map();
|
|
115
|
+
const outward = /* @__PURE__ */ new Map();
|
|
116
|
+
for (const section of ["inputs", "outputs", "props"]) {
|
|
117
|
+
const entries = value[section];
|
|
118
|
+
if (entries === void 0) continue;
|
|
119
|
+
if (!isRecord(entries)) {
|
|
120
|
+
add("invalid-section", `${section} must be an object`, section);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
for (const [name, raw] of Object.entries(entries)) {
|
|
124
|
+
const path = `${section}.${name}`;
|
|
125
|
+
if (!IDENTIFIER.test(name))
|
|
126
|
+
add("invalid-name", `${name} is not a valid identifier`, path);
|
|
127
|
+
if (RESERVED.has(name)) add("reserved-name", `${name} is reserved`, path);
|
|
128
|
+
const names = section === "outputs" ? outward : inward;
|
|
129
|
+
const previous = names.get(name);
|
|
130
|
+
if (previous)
|
|
131
|
+
add(
|
|
132
|
+
"name-collision",
|
|
133
|
+
`${name} is declared in ${previous} and ${section}`,
|
|
134
|
+
path
|
|
135
|
+
);
|
|
136
|
+
else names.set(name, section);
|
|
137
|
+
if (!isRecord(raw)) {
|
|
138
|
+
add("invalid-entry", `${path} must be an object`, path);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const fields2 = section === "props" ? PROP_FIELDS : section === "outputs" ? OUTPUT_FIELDS : DATA_FIELDS;
|
|
142
|
+
if (section !== "props" && raw.kind !== "data" && raw.kind !== "trigger") {
|
|
143
|
+
add(
|
|
144
|
+
"invalid-kind",
|
|
145
|
+
`${path}.kind must be data or trigger`,
|
|
146
|
+
`${path}.kind`
|
|
147
|
+
);
|
|
148
|
+
result.push(...unknownFields(raw, fields2, path));
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (section !== "props" && raw.kind === "trigger") {
|
|
152
|
+
if (Object.keys(raw).some(
|
|
153
|
+
(key) => key !== "kind" && key !== "description"
|
|
154
|
+
))
|
|
155
|
+
add(
|
|
156
|
+
"trigger-extra",
|
|
157
|
+
"Trigger ports allow only kind and description",
|
|
158
|
+
path
|
|
159
|
+
);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
result.push(...unknownFields(raw, fields2, path));
|
|
163
|
+
if ("control" in raw && (typeof raw.control !== "string" || !CONTROLS.has(raw.control)))
|
|
164
|
+
add(
|
|
165
|
+
"invalid-control",
|
|
166
|
+
`${String(raw.control)} is not a Cascade control`,
|
|
167
|
+
`${path}.control`
|
|
168
|
+
);
|
|
169
|
+
if ("options" in raw && raw.control !== "select")
|
|
170
|
+
add(
|
|
171
|
+
"options-without-select",
|
|
172
|
+
"options require the select control",
|
|
173
|
+
`${path}.options`
|
|
174
|
+
);
|
|
175
|
+
if (Array.isArray(raw.options))
|
|
176
|
+
for (const [index, option] of raw.options.entries()) {
|
|
177
|
+
if (option === null || typeof option !== "object") continue;
|
|
178
|
+
const entry = option;
|
|
179
|
+
if (!("value" in entry))
|
|
180
|
+
add(
|
|
181
|
+
"invalid-option",
|
|
182
|
+
"a labelled option needs a value",
|
|
183
|
+
`${path}.options[${index}]`
|
|
184
|
+
);
|
|
185
|
+
if (typeof entry.label !== "string" || !entry.label)
|
|
186
|
+
add(
|
|
187
|
+
"invalid-option",
|
|
188
|
+
"a labelled option needs a non-empty label",
|
|
189
|
+
`${path}.options[${index}].label`
|
|
190
|
+
);
|
|
191
|
+
if ("disabled" in entry && typeof entry.disabled !== "boolean")
|
|
192
|
+
add(
|
|
193
|
+
"invalid-option",
|
|
194
|
+
"disabled must be a boolean",
|
|
195
|
+
`${path}.options[${index}].disabled`
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
const type = raw.type;
|
|
199
|
+
if (!validType(type)) {
|
|
200
|
+
add(
|
|
201
|
+
"invalid-type",
|
|
202
|
+
`${String(type)} is not a Cascade type`,
|
|
203
|
+
`${path}.type`
|
|
204
|
+
);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (section !== "props") result.push(...bundleDiagnostics(raw, type, section, path));
|
|
208
|
+
if (type === "texture" && environment !== "browser")
|
|
209
|
+
add("texture-not-portable", "texture is browser-only", `${path}.type`);
|
|
210
|
+
if (type === "texture" && "default" in raw)
|
|
211
|
+
add(
|
|
212
|
+
"texture-default",
|
|
213
|
+
"texture cannot have a default",
|
|
214
|
+
`${path}.default`
|
|
215
|
+
);
|
|
216
|
+
if (section === "props" && !("default" in raw))
|
|
217
|
+
add("missing-default", "Props require defaults", `${path}.default`);
|
|
218
|
+
if ("default" in raw && !finiteJson(raw.default))
|
|
219
|
+
add(
|
|
220
|
+
"invalid-default",
|
|
221
|
+
"Default must be finite JSON",
|
|
222
|
+
`${path}.default`
|
|
223
|
+
);
|
|
224
|
+
else if ("default" in raw && !defaultMatches(type, raw.default))
|
|
225
|
+
add(
|
|
226
|
+
"default-type",
|
|
227
|
+
`Default does not match ${type}`,
|
|
228
|
+
`${path}.default`
|
|
229
|
+
);
|
|
230
|
+
if (type === "int" && "default" in raw && (!Number.isFinite(raw.default) || !Number.isInteger(raw.default)))
|
|
231
|
+
add(
|
|
232
|
+
"non-integer",
|
|
233
|
+
"Integer defaults must be finite integers",
|
|
234
|
+
`${path}.default`
|
|
235
|
+
);
|
|
236
|
+
if ("step" in raw && (typeof raw.step !== "number" || !Number.isFinite(raw.step) || raw.step <= 0))
|
|
237
|
+
add("invalid-step", "step must be greater than zero", `${path}.step`);
|
|
238
|
+
if (section === "props" && "expression" in raw && (typeof raw.expression !== "string" || raw.expression.length === 0))
|
|
239
|
+
add(
|
|
240
|
+
"invalid-expression",
|
|
241
|
+
"expression must be a non-empty string",
|
|
242
|
+
`${path}.expression`
|
|
243
|
+
);
|
|
244
|
+
for (const field of ["min", "max"]) {
|
|
245
|
+
if (field in raw && (typeof raw[field] !== "number" || !Number.isFinite(raw[field])))
|
|
246
|
+
add(
|
|
247
|
+
`invalid-${field}`,
|
|
248
|
+
`${field} must be a finite number`,
|
|
249
|
+
`${path}.${field}`
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
if (typeof raw.min === "number" && typeof raw.max === "number" && raw.min > raw.max)
|
|
253
|
+
add("invalid-range", "min must not exceed max", path);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return result;
|
|
257
|
+
}
|
|
258
|
+
function bundleDiagnostics(raw, type, section, path) {
|
|
259
|
+
const result = [];
|
|
260
|
+
const add = (code, message, at) => result.push(diagnostic(code, message, at));
|
|
261
|
+
for (const key of ["schema", "fields"])
|
|
262
|
+
if (key in raw && type !== "bundle")
|
|
263
|
+
add("bundle-metadata", `${key} is only valid on a bundle port`, `${path}.${key}`);
|
|
264
|
+
if (type !== "bundle") return result;
|
|
265
|
+
if ("schema" in raw && (typeof raw.schema !== "string" || !IDENTIFIER.test(raw.schema)))
|
|
266
|
+
add("invalid-schema", "schema must be an identifier", `${path}.schema`);
|
|
267
|
+
if (!("fields" in raw)) return result;
|
|
268
|
+
const declared = raw.fields;
|
|
269
|
+
if (section === "inputs") {
|
|
270
|
+
if (!Array.isArray(declared)) {
|
|
271
|
+
add("invalid-fields", "an input's fields list the field names it reads", `${path}.fields`);
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
const seen = /* @__PURE__ */ new Set();
|
|
275
|
+
for (const [index, field] of declared.entries()) {
|
|
276
|
+
if (typeof field !== "string" || !IDENTIFIER.test(field))
|
|
277
|
+
add("invalid-field", `${String(field)} is not a valid field name`, `${path}.fields[${index}]`);
|
|
278
|
+
else if (seen.has(field))
|
|
279
|
+
add("duplicate-field", `${field} is listed twice`, `${path}.fields[${index}]`);
|
|
280
|
+
else seen.add(field);
|
|
281
|
+
}
|
|
282
|
+
return result;
|
|
283
|
+
}
|
|
284
|
+
if (!isRecord(declared)) {
|
|
285
|
+
add("invalid-fields", "an output's fields map each field name to its type", `${path}.fields`);
|
|
286
|
+
return result;
|
|
287
|
+
}
|
|
288
|
+
for (const [field, definition] of Object.entries(declared)) {
|
|
289
|
+
const at = `${path}.fields.${field}`;
|
|
290
|
+
if (!IDENTIFIER.test(field) || RESERVED.has(field))
|
|
291
|
+
add("invalid-field", `${field} is not a valid field name`, at);
|
|
292
|
+
const fieldType = typeof definition === "string" ? definition : isRecord(definition) ? definition.type : void 0;
|
|
293
|
+
if (isRecord(definition)) {
|
|
294
|
+
for (const key of Object.keys(definition))
|
|
295
|
+
if (key !== "type" && key !== "description")
|
|
296
|
+
add("unknown-field", `${at}.${key} is not allowed`, `${at}.${key}`);
|
|
297
|
+
}
|
|
298
|
+
if (!validType(fieldType))
|
|
299
|
+
add("invalid-type", `${String(fieldType)} is not a Cascade type`, at);
|
|
300
|
+
else if (fieldType === "texture")
|
|
301
|
+
add("texture-not-portable", "a bundle field cannot hold a texture", at);
|
|
302
|
+
}
|
|
303
|
+
return result;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export {
|
|
307
|
+
CAPABILITIES_BY_ENVIRONMENT,
|
|
308
|
+
validateNodeDefinition
|
|
309
|
+
};
|
|
310
|
+
//# sourceMappingURL=chunk-A4OAMOZH.js.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// packages/contracts/src/values.ts
|
|
2
|
+
var CORE_TYPES = [
|
|
3
|
+
"float",
|
|
4
|
+
"int",
|
|
5
|
+
"bool",
|
|
6
|
+
"string",
|
|
7
|
+
"vec2",
|
|
8
|
+
"vec3",
|
|
9
|
+
"vec4",
|
|
10
|
+
"vec2i",
|
|
11
|
+
"vec3i",
|
|
12
|
+
"vec4i",
|
|
13
|
+
"mat2",
|
|
14
|
+
"mat3",
|
|
15
|
+
"mat4",
|
|
16
|
+
"image",
|
|
17
|
+
"texture",
|
|
18
|
+
"geometry",
|
|
19
|
+
"points",
|
|
20
|
+
"lines",
|
|
21
|
+
"polyline",
|
|
22
|
+
"mesh",
|
|
23
|
+
"rects",
|
|
24
|
+
"color",
|
|
25
|
+
"camera",
|
|
26
|
+
"scene",
|
|
27
|
+
"light",
|
|
28
|
+
"asset",
|
|
29
|
+
"array",
|
|
30
|
+
"object",
|
|
31
|
+
"bundle",
|
|
32
|
+
"any"
|
|
33
|
+
];
|
|
34
|
+
var TYPE_ALIASES = {
|
|
35
|
+
number: "float",
|
|
36
|
+
boolean: "bool",
|
|
37
|
+
curves: "polyline"
|
|
38
|
+
};
|
|
39
|
+
var IMPLICIT_TYPE_CONVERSIONS = {
|
|
40
|
+
int: ["float", "string"],
|
|
41
|
+
float: ["string"],
|
|
42
|
+
bool: ["int", "float", "string"],
|
|
43
|
+
vec2i: ["vec2"],
|
|
44
|
+
vec3i: ["vec3"],
|
|
45
|
+
vec4i: ["vec4"],
|
|
46
|
+
/**
|
|
47
|
+
* A geometry *is* a scene — one with the viewport's own camera and no lights.
|
|
48
|
+
* So the wire is legal and nothing is lost, which is the widening rule this
|
|
49
|
+
* table already follows. Every consumer of a `scene` input reads it through
|
|
50
|
+
* `asScene`, which performs the promotion; see `scene.ts`.
|
|
51
|
+
*/
|
|
52
|
+
geometry: ["scene"],
|
|
53
|
+
vec4: ["color"],
|
|
54
|
+
color: ["vec4"]
|
|
55
|
+
};
|
|
56
|
+
function normalizeCascadeType(type) {
|
|
57
|
+
if (!type) return "any";
|
|
58
|
+
return TYPE_ALIASES[type] ?? type;
|
|
59
|
+
}
|
|
60
|
+
function canConnectTypes(source, target) {
|
|
61
|
+
const from = normalizeCascadeType(source);
|
|
62
|
+
const to = normalizeCascadeType(target);
|
|
63
|
+
return from === to || from === "any" || to === "any" || (IMPLICIT_TYPE_CONVERSIONS[from]?.includes(to) ?? false);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export {
|
|
67
|
+
CORE_TYPES,
|
|
68
|
+
normalizeCascadeType,
|
|
69
|
+
canConnectTypes
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=chunk-BIJO5OFS.js.map
|