@positronic/core 0.0.52 → 0.0.53
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/src/dsl/{loop-messages.js → agent-messages.js} +21 -21
- package/dist/src/dsl/brain-runner.js +6 -6
- package/dist/src/dsl/brain-state-machine.js +2 -2
- package/dist/src/dsl/brain.js +5 -1912
- package/dist/src/dsl/builder/brain.js +944 -0
- package/dist/src/dsl/builder/step.js +75 -0
- package/dist/src/dsl/constants.js +9 -10
- package/dist/src/dsl/create-brain.js +63 -0
- package/dist/src/dsl/definitions/blocks.js +1 -0
- package/dist/src/dsl/definitions/brain-types.js +4 -0
- package/dist/src/dsl/definitions/events.js +2 -0
- package/dist/src/dsl/definitions/run-params.js +1 -0
- package/dist/src/dsl/definitions/steps.js +2 -0
- package/dist/src/dsl/execution/constants.js +14 -0
- package/dist/src/dsl/execution/event-stream.js +1638 -0
- package/dist/src/dsl/execution/retry.js +298 -0
- package/dist/src/dsl/types.js +2 -2
- package/dist/src/index.js +5 -3
- package/dist/src/tools/index.js +181 -0
- package/dist/src/ui/component-utils.js +107 -0
- package/dist/src/ui/generate-page-html.js +36 -0
- package/dist/src/ui/generate-ui.js +601 -0
- package/dist/src/ui/types.js +165 -0
- package/dist/src/ui/validate-form.js +428 -0
- package/dist/src/yaml/data-validator.js +302 -0
- package/dist/src/yaml/index.js +9 -0
- package/dist/src/yaml/parser.js +224 -0
- package/dist/src/yaml/schema-extractor.js +330 -0
- package/dist/src/yaml/type-inference.js +210 -0
- package/dist/src/yaml/types.js +12 -0
- package/dist/types/clients/types.d.ts +42 -0
- package/dist/types/clients/types.d.ts.map +1 -1
- package/dist/types/dsl/agent-messages.d.ts +18 -0
- package/dist/types/dsl/agent-messages.d.ts.map +1 -0
- package/dist/types/dsl/brain-runner.d.ts +2 -2
- package/dist/types/dsl/brain-runner.d.ts.map +1 -1
- package/dist/types/dsl/brain-state-machine.d.ts.map +1 -1
- package/dist/types/dsl/brain.d.ts +7 -273
- package/dist/types/dsl/brain.d.ts.map +1 -1
- package/dist/types/dsl/builder/brain.d.ts +200 -0
- package/dist/types/dsl/builder/brain.d.ts.map +1 -0
- package/dist/types/dsl/builder/step.d.ts +15 -0
- package/dist/types/dsl/builder/step.d.ts.map +1 -0
- package/dist/types/dsl/constants.d.ts +8 -9
- package/dist/types/dsl/constants.d.ts.map +1 -1
- package/dist/types/dsl/create-brain.d.ts +80 -0
- package/dist/types/dsl/create-brain.d.ts.map +1 -0
- package/dist/types/dsl/definitions/blocks.d.ts +62 -0
- package/dist/types/dsl/definitions/blocks.d.ts.map +1 -0
- package/dist/types/dsl/definitions/brain-types.d.ts +33 -0
- package/dist/types/dsl/definitions/brain-types.d.ts.map +1 -0
- package/dist/types/dsl/definitions/events.d.ts +129 -0
- package/dist/types/dsl/definitions/events.d.ts.map +1 -0
- package/dist/types/dsl/definitions/run-params.d.ts +26 -0
- package/dist/types/dsl/definitions/run-params.d.ts.map +1 -0
- package/dist/types/dsl/definitions/steps.d.ts +20 -0
- package/dist/types/dsl/definitions/steps.d.ts.map +1 -0
- package/dist/types/dsl/example-webhook.d.ts +1 -1
- package/dist/types/dsl/example-webhook.d.ts.map +1 -1
- package/dist/types/dsl/execution/constants.d.ts +16 -0
- package/dist/types/dsl/execution/constants.d.ts.map +1 -0
- package/dist/types/dsl/execution/event-stream.d.ts +44 -0
- package/dist/types/dsl/execution/event-stream.d.ts.map +1 -0
- package/dist/types/dsl/execution/retry.d.ts +30 -0
- package/dist/types/dsl/execution/retry.d.ts.map +1 -0
- package/dist/types/dsl/types.d.ts +35 -14
- package/dist/types/dsl/types.d.ts.map +1 -1
- package/dist/types/index.d.ts +9 -7
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/tools/index.d.ts +33 -0
- package/dist/types/tools/index.d.ts.map +1 -0
- package/dist/types/ui/component-utils.d.ts +19 -0
- package/dist/types/ui/component-utils.d.ts.map +1 -0
- package/dist/types/ui/generate-page-html.d.ts +39 -0
- package/dist/types/ui/generate-page-html.d.ts.map +1 -0
- package/dist/types/ui/generate-ui.d.ts +47 -0
- package/dist/types/ui/generate-ui.d.ts.map +1 -0
- package/dist/types/ui/types.d.ts +138 -0
- package/dist/types/ui/types.d.ts.map +1 -0
- package/dist/types/ui/validate-form.d.ts +45 -0
- package/dist/types/ui/validate-form.d.ts.map +1 -0
- package/dist/types/yaml/data-validator.d.ts +35 -0
- package/dist/types/yaml/data-validator.d.ts.map +1 -0
- package/dist/types/yaml/index.d.ts +11 -0
- package/dist/types/yaml/index.d.ts.map +1 -0
- package/dist/types/yaml/parser.d.ts +20 -0
- package/dist/types/yaml/parser.d.ts.map +1 -0
- package/dist/types/yaml/schema-extractor.d.ts +29 -0
- package/dist/types/yaml/schema-extractor.d.ts.map +1 -0
- package/dist/types/yaml/type-inference.d.ts +50 -0
- package/dist/types/yaml/type-inference.d.ts.map +1 -0
- package/dist/types/yaml/types.d.ts +89 -0
- package/dist/types/yaml/types.d.ts.map +1 -0
- package/package.json +4 -2
- package/dist/types/dsl/loop-messages.d.ts +0 -18
- package/dist/types/dsl/loop-messages.d.ts.map +0 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
function _array_like_to_array(arr, len) {
|
|
2
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
3
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4
|
+
return arr2;
|
|
5
|
+
}
|
|
6
|
+
function _array_with_holes(arr) {
|
|
7
|
+
if (Array.isArray(arr)) return arr;
|
|
8
|
+
}
|
|
9
|
+
function _instanceof(left, right) {
|
|
10
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
11
|
+
return !!right[Symbol.hasInstance](left);
|
|
12
|
+
} else {
|
|
13
|
+
return left instanceof right;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function _iterable_to_array_limit(arr, i) {
|
|
17
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
18
|
+
if (_i == null) return;
|
|
19
|
+
var _arr = [];
|
|
20
|
+
var _n = true;
|
|
21
|
+
var _d = false;
|
|
22
|
+
var _s, _e;
|
|
23
|
+
try {
|
|
24
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
25
|
+
_arr.push(_s.value);
|
|
26
|
+
if (i && _arr.length === i) break;
|
|
27
|
+
}
|
|
28
|
+
} catch (err) {
|
|
29
|
+
_d = true;
|
|
30
|
+
_e = err;
|
|
31
|
+
} finally{
|
|
32
|
+
try {
|
|
33
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
34
|
+
} finally{
|
|
35
|
+
if (_d) throw _e;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return _arr;
|
|
39
|
+
}
|
|
40
|
+
function _non_iterable_rest() {
|
|
41
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
42
|
+
}
|
|
43
|
+
function _sliced_to_array(arr, i) {
|
|
44
|
+
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
45
|
+
}
|
|
46
|
+
function _type_of(obj) {
|
|
47
|
+
"@swc/helpers - typeof";
|
|
48
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
49
|
+
}
|
|
50
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
51
|
+
if (!o) return;
|
|
52
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
53
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
54
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
55
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
56
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
57
|
+
}
|
|
58
|
+
import { z } from 'zod';
|
|
59
|
+
/**
|
|
60
|
+
* Infer the DataType from a sample value.
|
|
61
|
+
*/ export function inferDataType(value) {
|
|
62
|
+
if (value === null) {
|
|
63
|
+
return {
|
|
64
|
+
kind: 'primitive',
|
|
65
|
+
type: 'null'
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (typeof value === 'string') {
|
|
69
|
+
return {
|
|
70
|
+
kind: 'primitive',
|
|
71
|
+
type: 'string'
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (typeof value === 'number') {
|
|
75
|
+
return {
|
|
76
|
+
kind: 'primitive',
|
|
77
|
+
type: 'number'
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (typeof value === 'boolean') {
|
|
81
|
+
return {
|
|
82
|
+
kind: 'primitive',
|
|
83
|
+
type: 'boolean'
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (Array.isArray(value)) {
|
|
87
|
+
if (value.length === 0) {
|
|
88
|
+
return {
|
|
89
|
+
kind: 'array',
|
|
90
|
+
elementType: {
|
|
91
|
+
kind: 'unknown'
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// Infer from first element
|
|
96
|
+
return {
|
|
97
|
+
kind: 'array',
|
|
98
|
+
elementType: inferDataType(value[0])
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
if ((typeof value === "undefined" ? "undefined" : _type_of(value)) === 'object') {
|
|
102
|
+
var properties = {};
|
|
103
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
104
|
+
try {
|
|
105
|
+
for(var _iterator = Object.entries(value)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
106
|
+
var _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], val = _step_value[1];
|
|
107
|
+
properties[key] = inferDataType(val);
|
|
108
|
+
}
|
|
109
|
+
} catch (err) {
|
|
110
|
+
_didIteratorError = true;
|
|
111
|
+
_iteratorError = err;
|
|
112
|
+
} finally{
|
|
113
|
+
try {
|
|
114
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
115
|
+
_iterator.return();
|
|
116
|
+
}
|
|
117
|
+
} finally{
|
|
118
|
+
if (_didIteratorError) {
|
|
119
|
+
throw _iteratorError;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
kind: 'object',
|
|
125
|
+
properties: properties
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
kind: 'unknown'
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Type guard to check if a schema is form-compatible at runtime.
|
|
134
|
+
* Used as a backup validation when TypeScript inference isn't sufficient.
|
|
135
|
+
*/ export function isFormSchema(schema) {
|
|
136
|
+
if (!_instanceof(schema, z.ZodObject)) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
var shape = schema.shape;
|
|
140
|
+
for(var key in shape){
|
|
141
|
+
if (!isFormField(shape[key])) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Type guard to check if a Zod schema is a valid form field.
|
|
149
|
+
*/ function isFormField(schema) {
|
|
150
|
+
// Check for optional wrapper
|
|
151
|
+
if (_instanceof(schema, z.ZodOptional)) {
|
|
152
|
+
return isFormPrimitive(schema.unwrap());
|
|
153
|
+
}
|
|
154
|
+
// Check for array wrapper
|
|
155
|
+
if (_instanceof(schema, z.ZodArray)) {
|
|
156
|
+
return isFormPrimitive(schema.element);
|
|
157
|
+
}
|
|
158
|
+
// Check if it's a primitive directly
|
|
159
|
+
return isFormPrimitive(schema);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Type guard to check if a Zod schema is a form primitive.
|
|
163
|
+
*/ function isFormPrimitive(schema) {
|
|
164
|
+
return _instanceof(schema, z.ZodString) || _instanceof(schema, z.ZodNumber) || _instanceof(schema, z.ZodBoolean) || _instanceof(schema, z.ZodEnum);
|
|
165
|
+
}
|
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
function _array_like_to_array(arr, len) {
|
|
2
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
3
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4
|
+
return arr2;
|
|
5
|
+
}
|
|
6
|
+
function _array_with_holes(arr) {
|
|
7
|
+
if (Array.isArray(arr)) return arr;
|
|
8
|
+
}
|
|
9
|
+
function _array_without_holes(arr) {
|
|
10
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
11
|
+
}
|
|
12
|
+
function _instanceof(left, right) {
|
|
13
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
14
|
+
return !!right[Symbol.hasInstance](left);
|
|
15
|
+
} else {
|
|
16
|
+
return left instanceof right;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function _iterable_to_array(iter) {
|
|
20
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
21
|
+
}
|
|
22
|
+
function _iterable_to_array_limit(arr, i) {
|
|
23
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
24
|
+
if (_i == null) return;
|
|
25
|
+
var _arr = [];
|
|
26
|
+
var _n = true;
|
|
27
|
+
var _d = false;
|
|
28
|
+
var _s, _e;
|
|
29
|
+
try {
|
|
30
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
31
|
+
_arr.push(_s.value);
|
|
32
|
+
if (i && _arr.length === i) break;
|
|
33
|
+
}
|
|
34
|
+
} catch (err) {
|
|
35
|
+
_d = true;
|
|
36
|
+
_e = err;
|
|
37
|
+
} finally{
|
|
38
|
+
try {
|
|
39
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
40
|
+
} finally{
|
|
41
|
+
if (_d) throw _e;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return _arr;
|
|
45
|
+
}
|
|
46
|
+
function _non_iterable_rest() {
|
|
47
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
48
|
+
}
|
|
49
|
+
function _non_iterable_spread() {
|
|
50
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
51
|
+
}
|
|
52
|
+
function _sliced_to_array(arr, i) {
|
|
53
|
+
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
54
|
+
}
|
|
55
|
+
function _to_consumable_array(arr) {
|
|
56
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
57
|
+
}
|
|
58
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
59
|
+
if (!o) return;
|
|
60
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
61
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
62
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
63
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
64
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
65
|
+
}
|
|
66
|
+
import { z } from 'zod';
|
|
67
|
+
import { inferDataType } from './types.js';
|
|
68
|
+
// ============================================
|
|
69
|
+
// BINDING UTILITIES
|
|
70
|
+
// ============================================
|
|
71
|
+
/**
|
|
72
|
+
* Check if a value is a binding expression like "{{path}}".
|
|
73
|
+
*/ export function isBinding(value) {
|
|
74
|
+
return typeof value === 'string' && value.startsWith('{{') && value.endsWith('}}');
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Extract the path from a binding expression.
|
|
78
|
+
* "{{email.subject}}" -> "email.subject"
|
|
79
|
+
*/ export function extractBindingPath(binding) {
|
|
80
|
+
return binding.slice(2, -2).trim();
|
|
81
|
+
}
|
|
82
|
+
// ============================================
|
|
83
|
+
// DATA BINDING VALIDATION
|
|
84
|
+
// ============================================
|
|
85
|
+
/**
|
|
86
|
+
* Components that create loop contexts.
|
|
87
|
+
* Children of these components can reference the loop variable.
|
|
88
|
+
*/ var LOOP_COMPONENTS = {
|
|
89
|
+
List: {
|
|
90
|
+
itemsProp: 'items',
|
|
91
|
+
asProp: 'as',
|
|
92
|
+
defaultAs: 'item'
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Resolve a path like "email.subject" against a DataType.
|
|
97
|
+
* Returns the type at that path, or null if invalid.
|
|
98
|
+
*/ function resolvePathType(path, rootType, loopContext) {
|
|
99
|
+
var parts = path.split('.');
|
|
100
|
+
// Check if the first part is a loop variable
|
|
101
|
+
var loopVar = loopContext.get(parts[0]);
|
|
102
|
+
if (loopVar) {
|
|
103
|
+
if (parts.length === 1) {
|
|
104
|
+
return loopVar;
|
|
105
|
+
}
|
|
106
|
+
return resolvePathInType(parts.slice(1), loopVar);
|
|
107
|
+
}
|
|
108
|
+
return resolvePathInType(parts, rootType);
|
|
109
|
+
}
|
|
110
|
+
function resolvePathInType(parts, type) {
|
|
111
|
+
var current = type;
|
|
112
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
113
|
+
try {
|
|
114
|
+
for(var _iterator = parts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
115
|
+
var part = _step.value;
|
|
116
|
+
if (current.kind === 'object') {
|
|
117
|
+
var prop = current.properties[part];
|
|
118
|
+
if (!prop) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
current = prop;
|
|
122
|
+
} else if (current.kind === 'array') {
|
|
123
|
+
// Accessing array by index
|
|
124
|
+
if (/^\d+$/.test(part)) {
|
|
125
|
+
current = current.elementType;
|
|
126
|
+
} else {
|
|
127
|
+
// Trying to access a property on an array - invalid
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
// Trying to access a property on a primitive
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} catch (err) {
|
|
136
|
+
_didIteratorError = true;
|
|
137
|
+
_iteratorError = err;
|
|
138
|
+
} finally{
|
|
139
|
+
try {
|
|
140
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
141
|
+
_iterator.return();
|
|
142
|
+
}
|
|
143
|
+
} finally{
|
|
144
|
+
if (_didIteratorError) {
|
|
145
|
+
throw _iteratorError;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return current;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get the loop context for a placement by walking up the parent chain.
|
|
153
|
+
*/ function getLoopContext(placement, placements, dataType) {
|
|
154
|
+
var context = new Map();
|
|
155
|
+
var current = placement;
|
|
156
|
+
while(current && current.parentId){
|
|
157
|
+
var parent = placements.find(function(p) {
|
|
158
|
+
return p.id === current.parentId;
|
|
159
|
+
});
|
|
160
|
+
if (!parent) break;
|
|
161
|
+
var loopConfig = LOOP_COMPONENTS[parent.component];
|
|
162
|
+
if (loopConfig) {
|
|
163
|
+
var itemsProp = parent.props[loopConfig.itemsProp];
|
|
164
|
+
var asProp = parent.props[loopConfig.asProp];
|
|
165
|
+
if (isBinding(itemsProp)) {
|
|
166
|
+
var itemsPath = extractBindingPath(itemsProp);
|
|
167
|
+
var itemsType = resolvePathType(itemsPath, dataType, context);
|
|
168
|
+
if (itemsType && itemsType.kind === 'array') {
|
|
169
|
+
var loopVarName = typeof asProp === 'string' ? asProp : loopConfig.defaultAs;
|
|
170
|
+
context.set(loopVarName, itemsType.elementType);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
current = parent;
|
|
175
|
+
}
|
|
176
|
+
return context;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Check if a placement is inside a loop component.
|
|
180
|
+
*/ function isInsideLoop(placement, placements) {
|
|
181
|
+
var current = placement;
|
|
182
|
+
while(current && current.parentId){
|
|
183
|
+
var parent = placements.find(function(p) {
|
|
184
|
+
return p.id === current.parentId;
|
|
185
|
+
});
|
|
186
|
+
if (!parent) break;
|
|
187
|
+
if (LOOP_COMPONENTS[parent.component]) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
current = parent;
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Validate all data bindings in placements against the provided data type.
|
|
196
|
+
*/ export function validateDataBindings(placements, data) {
|
|
197
|
+
var dataType = inferDataType(data);
|
|
198
|
+
var errors = [];
|
|
199
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
200
|
+
try {
|
|
201
|
+
for(var _iterator = placements[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
202
|
+
var placement = _step.value;
|
|
203
|
+
var loopContext = getLoopContext(placement, placements, dataType);
|
|
204
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
205
|
+
try {
|
|
206
|
+
for(var _iterator1 = Object.entries(placement.props)[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
207
|
+
var _step_value = _sliced_to_array(_step1.value, 2), propName = _step_value[0], propValue = _step_value[1];
|
|
208
|
+
if (isBinding(propValue)) {
|
|
209
|
+
var path = extractBindingPath(propValue);
|
|
210
|
+
var resolved = resolvePathType(path, dataType, loopContext);
|
|
211
|
+
if (resolved === null) {
|
|
212
|
+
errors.push({
|
|
213
|
+
type: 'invalid-binding',
|
|
214
|
+
message: 'Invalid binding "{{'.concat(path, '}}" - path does not exist in data'),
|
|
215
|
+
path: "".concat(placement.component, ".").concat(propName)
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
} catch (err) {
|
|
221
|
+
_didIteratorError1 = true;
|
|
222
|
+
_iteratorError1 = err;
|
|
223
|
+
} finally{
|
|
224
|
+
try {
|
|
225
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
226
|
+
_iterator1.return();
|
|
227
|
+
}
|
|
228
|
+
} finally{
|
|
229
|
+
if (_didIteratorError1) {
|
|
230
|
+
throw _iteratorError1;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
} catch (err) {
|
|
236
|
+
_didIteratorError = true;
|
|
237
|
+
_iteratorError = err;
|
|
238
|
+
} finally{
|
|
239
|
+
try {
|
|
240
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
241
|
+
_iterator.return();
|
|
242
|
+
}
|
|
243
|
+
} finally{
|
|
244
|
+
if (_didIteratorError) {
|
|
245
|
+
throw _iteratorError;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
valid: errors.length === 0,
|
|
251
|
+
errors: errors
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
// ============================================
|
|
255
|
+
// FORM SCHEMA EXTRACTION
|
|
256
|
+
// ============================================
|
|
257
|
+
/**
|
|
258
|
+
* Components that contribute form fields.
|
|
259
|
+
* Maps component name -> how to extract field info.
|
|
260
|
+
*/ var FORM_COMPONENTS = {
|
|
261
|
+
Input: {
|
|
262
|
+
nameProp: 'name',
|
|
263
|
+
fieldType: 'string'
|
|
264
|
+
},
|
|
265
|
+
TextArea: {
|
|
266
|
+
nameProp: 'name',
|
|
267
|
+
fieldType: 'string'
|
|
268
|
+
},
|
|
269
|
+
Checkbox: {
|
|
270
|
+
nameProp: 'name',
|
|
271
|
+
fieldType: 'boolean'
|
|
272
|
+
},
|
|
273
|
+
Select: {
|
|
274
|
+
nameProp: 'name',
|
|
275
|
+
fieldType: 'string'
|
|
276
|
+
},
|
|
277
|
+
MultiTextInput: {
|
|
278
|
+
nameProp: 'name',
|
|
279
|
+
fieldType: 'string[]'
|
|
280
|
+
},
|
|
281
|
+
HiddenInput: {
|
|
282
|
+
nameProp: 'name',
|
|
283
|
+
fieldType: 'string'
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Extract form schema from placements.
|
|
288
|
+
* Finds all form input components and extracts their field info.
|
|
289
|
+
*/ export function extractFormSchema(placements) {
|
|
290
|
+
var fields = [];
|
|
291
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
292
|
+
try {
|
|
293
|
+
var _loop = function() {
|
|
294
|
+
var placement = _step.value;
|
|
295
|
+
var formComponent = FORM_COMPONENTS[placement.component];
|
|
296
|
+
if (formComponent) {
|
|
297
|
+
var nameProp = placement.props[formComponent.nameProp];
|
|
298
|
+
if (typeof nameProp === 'string') {
|
|
299
|
+
var fieldType = formComponent.fieldType;
|
|
300
|
+
// Special handling for Checkbox: if it has a value prop, it returns that string value
|
|
301
|
+
if (placement.component === 'Checkbox' && placement.props.value !== undefined) {
|
|
302
|
+
fieldType = 'string';
|
|
303
|
+
}
|
|
304
|
+
var insideLoop = isInsideLoop(placement, placements);
|
|
305
|
+
// If inside a loop and it's a single value type, it becomes an array
|
|
306
|
+
if (insideLoop && !fieldType.endsWith('[]')) {
|
|
307
|
+
fieldType = "".concat(fieldType, "[]");
|
|
308
|
+
}
|
|
309
|
+
// Check if we already have this field (e.g., multiple checkboxes with same name)
|
|
310
|
+
var existing = fields.find(function(f) {
|
|
311
|
+
return f.name === nameProp;
|
|
312
|
+
});
|
|
313
|
+
if (existing) {
|
|
314
|
+
// Multiple fields with same name = array
|
|
315
|
+
if (!existing.type.endsWith('[]')) {
|
|
316
|
+
existing.type = "".concat(existing.type, "[]");
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
fields.push({
|
|
320
|
+
name: nameProp,
|
|
321
|
+
type: fieldType,
|
|
322
|
+
insideLoop: insideLoop
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
for(var _iterator = placements[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_loop();
|
|
329
|
+
} catch (err) {
|
|
330
|
+
_didIteratorError = true;
|
|
331
|
+
_iteratorError = err;
|
|
332
|
+
} finally{
|
|
333
|
+
try {
|
|
334
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
335
|
+
_iterator.return();
|
|
336
|
+
}
|
|
337
|
+
} finally{
|
|
338
|
+
if (_didIteratorError) {
|
|
339
|
+
throw _iteratorError;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return {
|
|
344
|
+
fields: fields
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Validate extracted form schema against a Zod schema.
|
|
349
|
+
*/ export function validateAgainstZod(extracted, zodSchema) {
|
|
350
|
+
var errors = [];
|
|
351
|
+
// Get the shape from the Zod schema
|
|
352
|
+
var shape = zodSchema.shape;
|
|
353
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
354
|
+
try {
|
|
355
|
+
var _loop = function() {
|
|
356
|
+
var _step_value = _sliced_to_array(_step.value, 2), fieldName = _step_value[0], fieldSchema = _step_value[1];
|
|
357
|
+
var isOptional = _instanceof(fieldSchema, z.ZodOptional);
|
|
358
|
+
var extractedField = extracted.fields.find(function(f) {
|
|
359
|
+
return f.name === fieldName;
|
|
360
|
+
});
|
|
361
|
+
if (!isOptional && !extractedField) {
|
|
362
|
+
errors.push({
|
|
363
|
+
type: 'form-schema-mismatch',
|
|
364
|
+
message: "Missing required field: ".concat(fieldName),
|
|
365
|
+
path: fieldName
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
// Check each schema field has a matching form field
|
|
370
|
+
for(var _iterator = Object.entries(shape)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_loop();
|
|
371
|
+
} catch (err) {
|
|
372
|
+
_didIteratorError = true;
|
|
373
|
+
_iteratorError = err;
|
|
374
|
+
} finally{
|
|
375
|
+
try {
|
|
376
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
377
|
+
_iterator.return();
|
|
378
|
+
}
|
|
379
|
+
} finally{
|
|
380
|
+
if (_didIteratorError) {
|
|
381
|
+
throw _iteratorError;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return {
|
|
386
|
+
valid: errors.length === 0,
|
|
387
|
+
errors: errors
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Create the ValidateForm tool for the UI generation agent.
|
|
392
|
+
* Validates both form schema and data bindings.
|
|
393
|
+
*/ export function createValidateFormTool(placements, schema, data) {
|
|
394
|
+
return {
|
|
395
|
+
description: "Validate the current form structure. Checks that:\n1. Form fields will produce data matching the expected schema\n2. All data bindings (like {{email.subject}}) reference valid paths in the provided data\nCall this after building your form to verify it's correct.",
|
|
396
|
+
inputSchema: z.object({}),
|
|
397
|
+
execute: function() {
|
|
398
|
+
var _errors;
|
|
399
|
+
var errors = [];
|
|
400
|
+
// 1. Extract form schema from placements
|
|
401
|
+
var extracted = extractFormSchema(placements);
|
|
402
|
+
// 2. Validate against expected Zod schema (if provided)
|
|
403
|
+
if (schema) {
|
|
404
|
+
var _errors1;
|
|
405
|
+
var schemaResult = validateAgainstZod(extracted, schema);
|
|
406
|
+
(_errors1 = errors).push.apply(_errors1, _to_consumable_array(schemaResult.errors));
|
|
407
|
+
}
|
|
408
|
+
// 3. Validate all data bindings
|
|
409
|
+
var bindingResult = validateDataBindings(placements, data);
|
|
410
|
+
(_errors = errors).push.apply(_errors, _to_consumable_array(bindingResult.errors));
|
|
411
|
+
return {
|
|
412
|
+
valid: errors.length === 0,
|
|
413
|
+
errors: errors.map(function(e) {
|
|
414
|
+
return {
|
|
415
|
+
type: e.type,
|
|
416
|
+
message: e.message
|
|
417
|
+
};
|
|
418
|
+
}),
|
|
419
|
+
extractedFields: extracted.fields.map(function(f) {
|
|
420
|
+
return {
|
|
421
|
+
name: f.name,
|
|
422
|
+
type: f.type
|
|
423
|
+
};
|
|
424
|
+
})
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
}
|