@particle-academy/fancy-flow 0.29.1 → 0.30.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/dist/engine.cjs +120 -0
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.cts +4 -2
- package/dist/engine.d.ts +4 -2
- package/dist/engine.js +1 -0
- package/dist/engine.js.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/registry/index.d.cts +4 -46
- package/dist/registry/index.d.ts +4 -46
- package/dist/registry-Dd1Q66uP.d.ts +45 -0
- package/dist/registry-qv4gRiuQ.d.cts +45 -0
- package/dist/{types-BGtR3k9J.d.ts → types-Bj_ZHwqG.d.ts} +96 -2
- package/dist/{types-B_pxRqfw.d.cts → types-DEmDSByY.d.cts} +96 -2
- package/dist/ux.d.cts +1 -2
- package/dist/ux.d.ts +1 -2
- package/package.json +1 -1
- package/dist/pause-9iT4tCEV.d.cts +0 -96
- package/dist/pause-9iT4tCEV.d.ts +0 -96
package/dist/engine.cjs
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
3
3
|
// src/registry/registry.ts
|
|
4
4
|
var kinds = /* @__PURE__ */ new Map();
|
|
5
5
|
var aliases = /* @__PURE__ */ new Map();
|
|
6
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
7
|
+
function registerNodeKind(definition) {
|
|
8
|
+
kinds.set(definition.name, definition);
|
|
9
|
+
for (const alias of definition.aliases ?? []) aliases.set(alias, definition.name);
|
|
10
|
+
notify();
|
|
11
|
+
return () => {
|
|
12
|
+
if (kinds.get(definition.name) === definition) {
|
|
13
|
+
kinds.delete(definition.name);
|
|
14
|
+
for (const alias of definition.aliases ?? []) {
|
|
15
|
+
if (aliases.get(alias) === definition.name) aliases.delete(alias);
|
|
16
|
+
}
|
|
17
|
+
notify();
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
6
21
|
function resolveKindId(id) {
|
|
7
22
|
if (kinds.has(id)) return id;
|
|
8
23
|
const canonical = aliases.get(id);
|
|
@@ -15,6 +30,104 @@ function getNodeKind(name) {
|
|
|
15
30
|
function kindIds(kind) {
|
|
16
31
|
return [kind.name, ...kind.aliases ?? []];
|
|
17
32
|
}
|
|
33
|
+
function listNodeKinds(category) {
|
|
34
|
+
const all = Array.from(kinds.values());
|
|
35
|
+
return category ? all.filter((k) => k.category === category) : all;
|
|
36
|
+
}
|
|
37
|
+
function notify() {
|
|
38
|
+
for (const l of listeners) l();
|
|
39
|
+
}
|
|
40
|
+
function defaultConfigFor(kind) {
|
|
41
|
+
const fromKind = kind.defaultConfig ? { ...kind.defaultConfig } : {};
|
|
42
|
+
for (const field of kind.configSchema ?? []) {
|
|
43
|
+
if (fromKind[field.key] !== void 0) continue;
|
|
44
|
+
if ("default" in field && field.default !== void 0) {
|
|
45
|
+
fromKind[field.key] = field.default;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return fromKind;
|
|
49
|
+
}
|
|
50
|
+
function validateConfig(kind, config) {
|
|
51
|
+
const issues = [];
|
|
52
|
+
for (const field of kind.configSchema ?? []) {
|
|
53
|
+
const value = config[field.key];
|
|
54
|
+
if (field.required && (value === void 0 || value === null || value === "")) {
|
|
55
|
+
issues.push({ key: field.key, message: `${field.label} is required` });
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (value === void 0 || value === null) continue;
|
|
59
|
+
const issue = validateField(field, value);
|
|
60
|
+
if (issue) issues.push({ key: field.key, message: issue });
|
|
61
|
+
}
|
|
62
|
+
return issues;
|
|
63
|
+
}
|
|
64
|
+
function validateField(field, value) {
|
|
65
|
+
switch (field.type) {
|
|
66
|
+
case "text":
|
|
67
|
+
case "textarea":
|
|
68
|
+
case "expression":
|
|
69
|
+
case "credential":
|
|
70
|
+
return typeof value === "string" ? null : `${field.label} must be a string`;
|
|
71
|
+
case "number": {
|
|
72
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return `${field.label} must be a number`;
|
|
73
|
+
if (field.min !== void 0 && value < field.min) return `${field.label} must be >= ${field.min}`;
|
|
74
|
+
if (field.max !== void 0 && value > field.max) return `${field.label} must be <= ${field.max}`;
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
case "switch":
|
|
78
|
+
return typeof value === "boolean" ? null : `${field.label} must be a boolean`;
|
|
79
|
+
case "select": {
|
|
80
|
+
const allowed = field.options.map((o) => o.value);
|
|
81
|
+
return allowed.includes(String(value)) ? null : `${field.label} must be one of ${allowed.join(", ")}`;
|
|
82
|
+
}
|
|
83
|
+
case "json":
|
|
84
|
+
return null;
|
|
85
|
+
// permissive — just JSON-shaped
|
|
86
|
+
case "repeater": {
|
|
87
|
+
if (!Array.isArray(value)) return `${field.label} must be a list`;
|
|
88
|
+
if (field.minItems !== void 0 && value.length < field.minItems) {
|
|
89
|
+
return `${field.label} needs at least ${field.minItems}`;
|
|
90
|
+
}
|
|
91
|
+
if (field.maxItems !== void 0 && value.length > field.maxItems) {
|
|
92
|
+
return `${field.label} allows at most ${field.maxItems}`;
|
|
93
|
+
}
|
|
94
|
+
for (let i = 0; i < value.length; i++) {
|
|
95
|
+
const row = value[i];
|
|
96
|
+
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
97
|
+
return `${field.label} item ${i + 1} must be an object`;
|
|
98
|
+
}
|
|
99
|
+
for (const sub of field.fields) {
|
|
100
|
+
const cell = row[sub.key];
|
|
101
|
+
if (sub.required && (cell === void 0 || cell === null || cell === "")) {
|
|
102
|
+
return `${field.label} item ${i + 1}: ${sub.label} is required`;
|
|
103
|
+
}
|
|
104
|
+
if (cell === void 0 || cell === null) continue;
|
|
105
|
+
const issue = validateField(sub, cell);
|
|
106
|
+
if (issue) return `${field.label} item ${i + 1}: ${issue}`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
case "keyvalue": {
|
|
112
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
113
|
+
return `${field.label} must be a key/value map`;
|
|
114
|
+
}
|
|
115
|
+
const allowed = field.valueOptions?.map((o) => o.value);
|
|
116
|
+
for (const [k, v] of Object.entries(value)) {
|
|
117
|
+
if (typeof v !== "string") return `${field.label}: "${k}" must be a string`;
|
|
118
|
+
if (allowed && !allowed.includes(v)) {
|
|
119
|
+
return `${field.label}: "${k}" must be one of ${allowed.join(", ")}`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
case "document":
|
|
125
|
+
return null;
|
|
126
|
+
// opaque to fancy-flow — the host's editor owns its shape
|
|
127
|
+
default:
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
18
131
|
|
|
19
132
|
// src/registry/ports.ts
|
|
20
133
|
function resolvePortSpec(spec, config) {
|
|
@@ -771,13 +884,20 @@ exports.PAUSE_PREFIX = PAUSE_PREFIX;
|
|
|
771
884
|
exports.checkCapabilities = checkCapabilities;
|
|
772
885
|
exports.checkRuntimeSupport = checkRuntimeSupport;
|
|
773
886
|
exports.decodePause = decodePause;
|
|
887
|
+
exports.defaultConfigFor = defaultConfigFor;
|
|
774
888
|
exports.encodePause = encodePause;
|
|
889
|
+
exports.getNodeKind = getNodeKind;
|
|
775
890
|
exports.isPause = isPause;
|
|
891
|
+
exports.kindIds = kindIds;
|
|
892
|
+
exports.listNodeKinds = listNodeKinds;
|
|
776
893
|
exports.pauseForHuman = pauseForHuman;
|
|
894
|
+
exports.registerNodeKind = registerNodeKind;
|
|
895
|
+
exports.resolveKindId = resolveKindId;
|
|
777
896
|
exports.runCohort = runCohort;
|
|
778
897
|
exports.runFixtures = runFixtures;
|
|
779
898
|
exports.runFlow = runFlow;
|
|
780
899
|
exports.satisfiesRange = satisfiesRange;
|
|
900
|
+
exports.validateConfig = validateConfig;
|
|
781
901
|
exports.validateFixtureFile = validateFixtureFile;
|
|
782
902
|
exports.validateNodeManifest = validateNodeManifest;
|
|
783
903
|
//# sourceMappingURL=engine.cjs.map
|