@makehq/forman-schema 1.4.1 → 1.5.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/index.cjs +121 -19
- package/dist/index.d.cts +12 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +121 -19
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -29,6 +29,22 @@ module.exports = __toCommonJS(index_exports);
|
|
|
29
29
|
|
|
30
30
|
// src/utils.ts
|
|
31
31
|
var FORMAN_VISUAL_TYPES = ["banner", "markdown", "html", "separator"];
|
|
32
|
+
function isVisualType(type) {
|
|
33
|
+
return FORMAN_VISUAL_TYPES.includes(type);
|
|
34
|
+
}
|
|
35
|
+
var FORMAN_REFERENCE_TYPES = [
|
|
36
|
+
"account",
|
|
37
|
+
"hook",
|
|
38
|
+
"device",
|
|
39
|
+
"keychain",
|
|
40
|
+
"datastore",
|
|
41
|
+
"aiagent",
|
|
42
|
+
"udt",
|
|
43
|
+
"scenario"
|
|
44
|
+
];
|
|
45
|
+
function isReferenceType(type) {
|
|
46
|
+
return FORMAN_REFERENCE_TYPES.includes(type);
|
|
47
|
+
}
|
|
32
48
|
function noEmpty(text) {
|
|
33
49
|
return text?.trim() || void 0;
|
|
34
50
|
}
|
|
@@ -51,8 +67,10 @@ var API_ENDPOINTS = {
|
|
|
51
67
|
aiagent: "api://ai-agents/v1/agents",
|
|
52
68
|
datastore: "api://data-stores",
|
|
53
69
|
hook: "api://hooks/{{kind}}",
|
|
70
|
+
device: "api://devices",
|
|
54
71
|
keychain: "api://keys/{{kind}}",
|
|
55
|
-
udt: "api://data-structures"
|
|
72
|
+
udt: "api://data-structures",
|
|
73
|
+
scenario: "api://scenario-list"
|
|
56
74
|
};
|
|
57
75
|
function normalizeFormanFieldType(field) {
|
|
58
76
|
const [type, kind] = field.type.split(":");
|
|
@@ -71,6 +89,69 @@ function normalizeFormanFieldType(field) {
|
|
|
71
89
|
}
|
|
72
90
|
};
|
|
73
91
|
}
|
|
92
|
+
function buildRestoreStructure(items) {
|
|
93
|
+
const result = {};
|
|
94
|
+
for (const item of items) {
|
|
95
|
+
const { domain, path, state } = item;
|
|
96
|
+
if (!result[domain]) {
|
|
97
|
+
result[domain] = {};
|
|
98
|
+
}
|
|
99
|
+
let current = result[domain];
|
|
100
|
+
for (const [index, key] of path.entries()) {
|
|
101
|
+
const nextKey = path[index + 1];
|
|
102
|
+
const isLastElement = index === path.length - 1;
|
|
103
|
+
const nextIsNumber = typeof nextKey === "number";
|
|
104
|
+
if (Array.isArray(current)) {
|
|
105
|
+
if (typeof key !== "number") {
|
|
106
|
+
throw new Error("Invalid path");
|
|
107
|
+
}
|
|
108
|
+
if (!current[key]) {
|
|
109
|
+
current[key] = {};
|
|
110
|
+
}
|
|
111
|
+
if (nextIsNumber) {
|
|
112
|
+
if (!current[key].value) {
|
|
113
|
+
current[key].value = {
|
|
114
|
+
mode: "chose",
|
|
115
|
+
items: []
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (!current[key].value.items) {
|
|
119
|
+
current[key].value.items = [];
|
|
120
|
+
}
|
|
121
|
+
current = current[key].value.items;
|
|
122
|
+
} else if (isLastElement) {
|
|
123
|
+
Object.assign(current[key], state);
|
|
124
|
+
} else {
|
|
125
|
+
current = current[key];
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
if (typeof key !== "string") {
|
|
129
|
+
throw new Error("Invalid path");
|
|
130
|
+
}
|
|
131
|
+
if (!current[key]) {
|
|
132
|
+
current[key] = {};
|
|
133
|
+
}
|
|
134
|
+
if (isLastElement) {
|
|
135
|
+
Object.assign(current[key], state);
|
|
136
|
+
} else {
|
|
137
|
+
if (nextIsNumber) {
|
|
138
|
+
if (!current[key].items) {
|
|
139
|
+
current[key].items = [];
|
|
140
|
+
current[key].mode = "chose";
|
|
141
|
+
}
|
|
142
|
+
current = current[key].items;
|
|
143
|
+
} else {
|
|
144
|
+
if (!current[key].nested) {
|
|
145
|
+
current[key].nested = {};
|
|
146
|
+
}
|
|
147
|
+
current = current[key].nested;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
74
155
|
|
|
75
156
|
// src/forman.ts
|
|
76
157
|
var SchemaConversionError = class extends Error {
|
|
@@ -182,7 +263,7 @@ function handleCollectionType(field, result, context) {
|
|
|
182
263
|
required: []
|
|
183
264
|
});
|
|
184
265
|
function addField(subField, tail) {
|
|
185
|
-
if (
|
|
266
|
+
if (isVisualType(subField.type)) {
|
|
186
267
|
return;
|
|
187
268
|
}
|
|
188
269
|
if (!subField.name) return;
|
|
@@ -427,6 +508,7 @@ async function validateFormanWithDomainsInternal(domains, options) {
|
|
|
427
508
|
(acc, domain) => {
|
|
428
509
|
acc[domain] = {
|
|
429
510
|
seenFields: /* @__PURE__ */ new Set(),
|
|
511
|
+
fieldStates: [],
|
|
430
512
|
validateFields: (fields, context) => {
|
|
431
513
|
return validateFormanValue(
|
|
432
514
|
domains[domain].values,
|
|
@@ -484,11 +566,14 @@ async function validateFormanWithDomainsInternal(domains, options) {
|
|
|
484
566
|
}
|
|
485
567
|
return {
|
|
486
568
|
valid: errors.length === 0,
|
|
487
|
-
errors
|
|
569
|
+
errors,
|
|
570
|
+
states: errors.length === 0 && options?.states ? buildRestoreStructure(
|
|
571
|
+
Object.keys(domains).map((domain) => roots[domain].fieldStates.map((state) => ({ domain, ...state }))).flat()
|
|
572
|
+
) : void 0
|
|
488
573
|
};
|
|
489
574
|
}
|
|
490
575
|
async function validateFormanValue(value, field, context) {
|
|
491
|
-
if (
|
|
576
|
+
if (isVisualType(field.type)) {
|
|
492
577
|
return {
|
|
493
578
|
valid: true,
|
|
494
579
|
errors: []
|
|
@@ -528,6 +613,24 @@ async function validateFormanValue(value, field, context) {
|
|
|
528
613
|
]
|
|
529
614
|
};
|
|
530
615
|
}
|
|
616
|
+
if (containsIMLExpression(value)) {
|
|
617
|
+
if (normalizedField.mappable === false) {
|
|
618
|
+
return {
|
|
619
|
+
valid: false,
|
|
620
|
+
errors: [
|
|
621
|
+
{
|
|
622
|
+
domain: context.domain,
|
|
623
|
+
path: context.path.join("."),
|
|
624
|
+
message: "Value contains prohibited IML expression."
|
|
625
|
+
}
|
|
626
|
+
]
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
return {
|
|
630
|
+
valid: true,
|
|
631
|
+
errors: []
|
|
632
|
+
};
|
|
633
|
+
}
|
|
531
634
|
switch (normalizedField.type) {
|
|
532
635
|
case "collection":
|
|
533
636
|
return handleCollectionType2(value, normalizedField, context);
|
|
@@ -536,10 +639,12 @@ async function validateFormanValue(value, field, context) {
|
|
|
536
639
|
case "select":
|
|
537
640
|
case "account":
|
|
538
641
|
case "hook":
|
|
642
|
+
case "device":
|
|
539
643
|
case "keychain":
|
|
540
644
|
case "datastore":
|
|
541
645
|
case "aiagent":
|
|
542
646
|
case "udt":
|
|
647
|
+
case "scenario":
|
|
543
648
|
case "file":
|
|
544
649
|
case "folder":
|
|
545
650
|
return handleSelectType2(value, normalizedField, context);
|
|
@@ -579,7 +684,7 @@ async function handleCollectionType2(value, field, context) {
|
|
|
579
684
|
};
|
|
580
685
|
}
|
|
581
686
|
}
|
|
582
|
-
if (
|
|
687
|
+
if (isVisualType(subField.type)) {
|
|
583
688
|
continue;
|
|
584
689
|
}
|
|
585
690
|
if (!subField.name) {
|
|
@@ -596,7 +701,7 @@ async function handleCollectionType2(value, field, context) {
|
|
|
596
701
|
path: [...path, subField.name],
|
|
597
702
|
validateNestedFields: async (fields, context2) => {
|
|
598
703
|
for (const subField2 of fields) {
|
|
599
|
-
if (
|
|
704
|
+
if (isVisualType(subField2.type)) {
|
|
600
705
|
continue;
|
|
601
706
|
}
|
|
602
707
|
if (!subField2.name) {
|
|
@@ -643,7 +748,7 @@ async function handleArrayType2(value, field, context) {
|
|
|
643
748
|
const result = await validateFormanValue(
|
|
644
749
|
item,
|
|
645
750
|
Array.isArray(field.spec) ? { name: index.toString(), type: "collection", spec: field.spec } : Object.assign({}, field.spec, { name: index.toString() }),
|
|
646
|
-
{ ...context, path: [...context.path, index
|
|
751
|
+
{ ...context, path: [...context.path, index] }
|
|
647
752
|
);
|
|
648
753
|
errors.push(...result.errors);
|
|
649
754
|
}
|
|
@@ -747,6 +852,15 @@ async function handleSelectType2(value, field, context) {
|
|
|
747
852
|
]
|
|
748
853
|
};
|
|
749
854
|
}
|
|
855
|
+
if (item.label) {
|
|
856
|
+
context.roots[context.domain].fieldStates.push({
|
|
857
|
+
path: context.path,
|
|
858
|
+
state: {
|
|
859
|
+
mode: isReferenceType(field.type) ? void 0 : "chose",
|
|
860
|
+
label: item.label
|
|
861
|
+
}
|
|
862
|
+
});
|
|
863
|
+
}
|
|
750
864
|
if (item.nested) nested = item.nested;
|
|
751
865
|
}
|
|
752
866
|
if (nested) {
|
|
@@ -815,18 +929,6 @@ async function handleNestedFields(nested, value, field, context) {
|
|
|
815
929
|
}
|
|
816
930
|
async function handlePrimitiveType2(value, field, context) {
|
|
817
931
|
const errors = [];
|
|
818
|
-
if (containsIMLExpression(value)) {
|
|
819
|
-
return {
|
|
820
|
-
valid: true,
|
|
821
|
-
errors
|
|
822
|
-
};
|
|
823
|
-
}
|
|
824
|
-
if (errors.length > 0) {
|
|
825
|
-
return {
|
|
826
|
-
valid: false,
|
|
827
|
-
errors
|
|
828
|
-
};
|
|
829
|
-
}
|
|
830
932
|
if (field.validate) {
|
|
831
933
|
if (typeof value === "string") {
|
|
832
934
|
if (field.validate.pattern && !new RegExp(
|
package/dist/index.d.cts
CHANGED
|
@@ -3,7 +3,7 @@ import { JSONSchema7 } from 'json-schema';
|
|
|
3
3
|
/**
|
|
4
4
|
* Valid Forman Schema field types
|
|
5
5
|
*/
|
|
6
|
-
type FormanSchemaFieldType = 'aiagent' | 'account' | 'hook' | 'keychain' | 'datastore' | 'udt' | 'array' | 'collection' | 'text' | 'number' | 'boolean' | 'date' | 'json' | 'buffer' | 'cert' | 'color' | 'email' | 'filename' | 'file' | 'folder' | 'hidden' | 'integer' | 'uinteger' | 'path' | 'pkey' | 'port' | 'select' | 'time' | 'timestamp' | 'timezone' | 'url' | 'uuid' | `account:${string}` | `hook:${string}` | `keychain:${string}` | 'banner' | 'markdown' | 'html' | 'separator' | string;
|
|
6
|
+
type FormanSchemaFieldType = 'aiagent' | 'account' | 'hook' | 'device' | 'keychain' | 'datastore' | 'udt' | 'scenario' | 'array' | 'collection' | 'text' | 'number' | 'boolean' | 'date' | 'json' | 'buffer' | 'cert' | 'color' | 'email' | 'filename' | 'file' | 'folder' | 'hidden' | 'integer' | 'uinteger' | 'path' | 'pkey' | 'port' | 'select' | 'time' | 'timestamp' | 'timezone' | 'url' | 'uuid' | `account:${string}` | `hook:${string}` | `keychain:${string}` | 'banner' | 'markdown' | 'html' | 'separator' | string;
|
|
7
7
|
/**
|
|
8
8
|
* Validation configuration for Forman Schema fields
|
|
9
9
|
*/
|
|
@@ -163,10 +163,21 @@ type FormanValidationResult = {
|
|
|
163
163
|
/** Error message */
|
|
164
164
|
message: string;
|
|
165
165
|
}[];
|
|
166
|
+
/** States of fields grouped by domain */
|
|
167
|
+
states?: Record<string, FormanSchemaFieldState>;
|
|
168
|
+
};
|
|
169
|
+
type FormanSchemaFieldState = {
|
|
170
|
+
mode?: 'chose' | 'edit';
|
|
171
|
+
label?: string;
|
|
172
|
+
data?: Record<string, unknown>;
|
|
173
|
+
nested?: Record<string, FormanSchemaFieldState>;
|
|
174
|
+
items?: Record<string, FormanSchemaFieldState>[];
|
|
166
175
|
};
|
|
167
176
|
type FormanValidationOptions = {
|
|
168
177
|
/** Unknown fields are not allowed when strict is true */
|
|
169
178
|
strict?: boolean;
|
|
179
|
+
/** Whether to generate states for fields */
|
|
180
|
+
states?: boolean;
|
|
170
181
|
/** Remote resource resolver */
|
|
171
182
|
resolveRemote?(path: string, data: Record<string, unknown>): Promise<unknown>;
|
|
172
183
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { JSONSchema7 } from 'json-schema';
|
|
|
3
3
|
/**
|
|
4
4
|
* Valid Forman Schema field types
|
|
5
5
|
*/
|
|
6
|
-
type FormanSchemaFieldType = 'aiagent' | 'account' | 'hook' | 'keychain' | 'datastore' | 'udt' | 'array' | 'collection' | 'text' | 'number' | 'boolean' | 'date' | 'json' | 'buffer' | 'cert' | 'color' | 'email' | 'filename' | 'file' | 'folder' | 'hidden' | 'integer' | 'uinteger' | 'path' | 'pkey' | 'port' | 'select' | 'time' | 'timestamp' | 'timezone' | 'url' | 'uuid' | `account:${string}` | `hook:${string}` | `keychain:${string}` | 'banner' | 'markdown' | 'html' | 'separator' | string;
|
|
6
|
+
type FormanSchemaFieldType = 'aiagent' | 'account' | 'hook' | 'device' | 'keychain' | 'datastore' | 'udt' | 'scenario' | 'array' | 'collection' | 'text' | 'number' | 'boolean' | 'date' | 'json' | 'buffer' | 'cert' | 'color' | 'email' | 'filename' | 'file' | 'folder' | 'hidden' | 'integer' | 'uinteger' | 'path' | 'pkey' | 'port' | 'select' | 'time' | 'timestamp' | 'timezone' | 'url' | 'uuid' | `account:${string}` | `hook:${string}` | `keychain:${string}` | 'banner' | 'markdown' | 'html' | 'separator' | string;
|
|
7
7
|
/**
|
|
8
8
|
* Validation configuration for Forman Schema fields
|
|
9
9
|
*/
|
|
@@ -163,10 +163,21 @@ type FormanValidationResult = {
|
|
|
163
163
|
/** Error message */
|
|
164
164
|
message: string;
|
|
165
165
|
}[];
|
|
166
|
+
/** States of fields grouped by domain */
|
|
167
|
+
states?: Record<string, FormanSchemaFieldState>;
|
|
168
|
+
};
|
|
169
|
+
type FormanSchemaFieldState = {
|
|
170
|
+
mode?: 'chose' | 'edit';
|
|
171
|
+
label?: string;
|
|
172
|
+
data?: Record<string, unknown>;
|
|
173
|
+
nested?: Record<string, FormanSchemaFieldState>;
|
|
174
|
+
items?: Record<string, FormanSchemaFieldState>[];
|
|
166
175
|
};
|
|
167
176
|
type FormanValidationOptions = {
|
|
168
177
|
/** Unknown fields are not allowed when strict is true */
|
|
169
178
|
strict?: boolean;
|
|
179
|
+
/** Whether to generate states for fields */
|
|
180
|
+
states?: boolean;
|
|
170
181
|
/** Remote resource resolver */
|
|
171
182
|
resolveRemote?(path: string, data: Record<string, unknown>): Promise<unknown>;
|
|
172
183
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
// src/utils.ts
|
|
2
2
|
var FORMAN_VISUAL_TYPES = ["banner", "markdown", "html", "separator"];
|
|
3
|
+
function isVisualType(type) {
|
|
4
|
+
return FORMAN_VISUAL_TYPES.includes(type);
|
|
5
|
+
}
|
|
6
|
+
var FORMAN_REFERENCE_TYPES = [
|
|
7
|
+
"account",
|
|
8
|
+
"hook",
|
|
9
|
+
"device",
|
|
10
|
+
"keychain",
|
|
11
|
+
"datastore",
|
|
12
|
+
"aiagent",
|
|
13
|
+
"udt",
|
|
14
|
+
"scenario"
|
|
15
|
+
];
|
|
16
|
+
function isReferenceType(type) {
|
|
17
|
+
return FORMAN_REFERENCE_TYPES.includes(type);
|
|
18
|
+
}
|
|
3
19
|
function noEmpty(text) {
|
|
4
20
|
return text?.trim() || void 0;
|
|
5
21
|
}
|
|
@@ -22,8 +38,10 @@ var API_ENDPOINTS = {
|
|
|
22
38
|
aiagent: "api://ai-agents/v1/agents",
|
|
23
39
|
datastore: "api://data-stores",
|
|
24
40
|
hook: "api://hooks/{{kind}}",
|
|
41
|
+
device: "api://devices",
|
|
25
42
|
keychain: "api://keys/{{kind}}",
|
|
26
|
-
udt: "api://data-structures"
|
|
43
|
+
udt: "api://data-structures",
|
|
44
|
+
scenario: "api://scenario-list"
|
|
27
45
|
};
|
|
28
46
|
function normalizeFormanFieldType(field) {
|
|
29
47
|
const [type, kind] = field.type.split(":");
|
|
@@ -42,6 +60,69 @@ function normalizeFormanFieldType(field) {
|
|
|
42
60
|
}
|
|
43
61
|
};
|
|
44
62
|
}
|
|
63
|
+
function buildRestoreStructure(items) {
|
|
64
|
+
const result = {};
|
|
65
|
+
for (const item of items) {
|
|
66
|
+
const { domain, path, state } = item;
|
|
67
|
+
if (!result[domain]) {
|
|
68
|
+
result[domain] = {};
|
|
69
|
+
}
|
|
70
|
+
let current = result[domain];
|
|
71
|
+
for (const [index, key] of path.entries()) {
|
|
72
|
+
const nextKey = path[index + 1];
|
|
73
|
+
const isLastElement = index === path.length - 1;
|
|
74
|
+
const nextIsNumber = typeof nextKey === "number";
|
|
75
|
+
if (Array.isArray(current)) {
|
|
76
|
+
if (typeof key !== "number") {
|
|
77
|
+
throw new Error("Invalid path");
|
|
78
|
+
}
|
|
79
|
+
if (!current[key]) {
|
|
80
|
+
current[key] = {};
|
|
81
|
+
}
|
|
82
|
+
if (nextIsNumber) {
|
|
83
|
+
if (!current[key].value) {
|
|
84
|
+
current[key].value = {
|
|
85
|
+
mode: "chose",
|
|
86
|
+
items: []
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
if (!current[key].value.items) {
|
|
90
|
+
current[key].value.items = [];
|
|
91
|
+
}
|
|
92
|
+
current = current[key].value.items;
|
|
93
|
+
} else if (isLastElement) {
|
|
94
|
+
Object.assign(current[key], state);
|
|
95
|
+
} else {
|
|
96
|
+
current = current[key];
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
if (typeof key !== "string") {
|
|
100
|
+
throw new Error("Invalid path");
|
|
101
|
+
}
|
|
102
|
+
if (!current[key]) {
|
|
103
|
+
current[key] = {};
|
|
104
|
+
}
|
|
105
|
+
if (isLastElement) {
|
|
106
|
+
Object.assign(current[key], state);
|
|
107
|
+
} else {
|
|
108
|
+
if (nextIsNumber) {
|
|
109
|
+
if (!current[key].items) {
|
|
110
|
+
current[key].items = [];
|
|
111
|
+
current[key].mode = "chose";
|
|
112
|
+
}
|
|
113
|
+
current = current[key].items;
|
|
114
|
+
} else {
|
|
115
|
+
if (!current[key].nested) {
|
|
116
|
+
current[key].nested = {};
|
|
117
|
+
}
|
|
118
|
+
current = current[key].nested;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
45
126
|
|
|
46
127
|
// src/forman.ts
|
|
47
128
|
var SchemaConversionError = class extends Error {
|
|
@@ -153,7 +234,7 @@ function handleCollectionType(field, result, context) {
|
|
|
153
234
|
required: []
|
|
154
235
|
});
|
|
155
236
|
function addField(subField, tail) {
|
|
156
|
-
if (
|
|
237
|
+
if (isVisualType(subField.type)) {
|
|
157
238
|
return;
|
|
158
239
|
}
|
|
159
240
|
if (!subField.name) return;
|
|
@@ -398,6 +479,7 @@ async function validateFormanWithDomainsInternal(domains, options) {
|
|
|
398
479
|
(acc, domain) => {
|
|
399
480
|
acc[domain] = {
|
|
400
481
|
seenFields: /* @__PURE__ */ new Set(),
|
|
482
|
+
fieldStates: [],
|
|
401
483
|
validateFields: (fields, context) => {
|
|
402
484
|
return validateFormanValue(
|
|
403
485
|
domains[domain].values,
|
|
@@ -455,11 +537,14 @@ async function validateFormanWithDomainsInternal(domains, options) {
|
|
|
455
537
|
}
|
|
456
538
|
return {
|
|
457
539
|
valid: errors.length === 0,
|
|
458
|
-
errors
|
|
540
|
+
errors,
|
|
541
|
+
states: errors.length === 0 && options?.states ? buildRestoreStructure(
|
|
542
|
+
Object.keys(domains).map((domain) => roots[domain].fieldStates.map((state) => ({ domain, ...state }))).flat()
|
|
543
|
+
) : void 0
|
|
459
544
|
};
|
|
460
545
|
}
|
|
461
546
|
async function validateFormanValue(value, field, context) {
|
|
462
|
-
if (
|
|
547
|
+
if (isVisualType(field.type)) {
|
|
463
548
|
return {
|
|
464
549
|
valid: true,
|
|
465
550
|
errors: []
|
|
@@ -499,6 +584,24 @@ async function validateFormanValue(value, field, context) {
|
|
|
499
584
|
]
|
|
500
585
|
};
|
|
501
586
|
}
|
|
587
|
+
if (containsIMLExpression(value)) {
|
|
588
|
+
if (normalizedField.mappable === false) {
|
|
589
|
+
return {
|
|
590
|
+
valid: false,
|
|
591
|
+
errors: [
|
|
592
|
+
{
|
|
593
|
+
domain: context.domain,
|
|
594
|
+
path: context.path.join("."),
|
|
595
|
+
message: "Value contains prohibited IML expression."
|
|
596
|
+
}
|
|
597
|
+
]
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
return {
|
|
601
|
+
valid: true,
|
|
602
|
+
errors: []
|
|
603
|
+
};
|
|
604
|
+
}
|
|
502
605
|
switch (normalizedField.type) {
|
|
503
606
|
case "collection":
|
|
504
607
|
return handleCollectionType2(value, normalizedField, context);
|
|
@@ -507,10 +610,12 @@ async function validateFormanValue(value, field, context) {
|
|
|
507
610
|
case "select":
|
|
508
611
|
case "account":
|
|
509
612
|
case "hook":
|
|
613
|
+
case "device":
|
|
510
614
|
case "keychain":
|
|
511
615
|
case "datastore":
|
|
512
616
|
case "aiagent":
|
|
513
617
|
case "udt":
|
|
618
|
+
case "scenario":
|
|
514
619
|
case "file":
|
|
515
620
|
case "folder":
|
|
516
621
|
return handleSelectType2(value, normalizedField, context);
|
|
@@ -550,7 +655,7 @@ async function handleCollectionType2(value, field, context) {
|
|
|
550
655
|
};
|
|
551
656
|
}
|
|
552
657
|
}
|
|
553
|
-
if (
|
|
658
|
+
if (isVisualType(subField.type)) {
|
|
554
659
|
continue;
|
|
555
660
|
}
|
|
556
661
|
if (!subField.name) {
|
|
@@ -567,7 +672,7 @@ async function handleCollectionType2(value, field, context) {
|
|
|
567
672
|
path: [...path, subField.name],
|
|
568
673
|
validateNestedFields: async (fields, context2) => {
|
|
569
674
|
for (const subField2 of fields) {
|
|
570
|
-
if (
|
|
675
|
+
if (isVisualType(subField2.type)) {
|
|
571
676
|
continue;
|
|
572
677
|
}
|
|
573
678
|
if (!subField2.name) {
|
|
@@ -614,7 +719,7 @@ async function handleArrayType2(value, field, context) {
|
|
|
614
719
|
const result = await validateFormanValue(
|
|
615
720
|
item,
|
|
616
721
|
Array.isArray(field.spec) ? { name: index.toString(), type: "collection", spec: field.spec } : Object.assign({}, field.spec, { name: index.toString() }),
|
|
617
|
-
{ ...context, path: [...context.path, index
|
|
722
|
+
{ ...context, path: [...context.path, index] }
|
|
618
723
|
);
|
|
619
724
|
errors.push(...result.errors);
|
|
620
725
|
}
|
|
@@ -718,6 +823,15 @@ async function handleSelectType2(value, field, context) {
|
|
|
718
823
|
]
|
|
719
824
|
};
|
|
720
825
|
}
|
|
826
|
+
if (item.label) {
|
|
827
|
+
context.roots[context.domain].fieldStates.push({
|
|
828
|
+
path: context.path,
|
|
829
|
+
state: {
|
|
830
|
+
mode: isReferenceType(field.type) ? void 0 : "chose",
|
|
831
|
+
label: item.label
|
|
832
|
+
}
|
|
833
|
+
});
|
|
834
|
+
}
|
|
721
835
|
if (item.nested) nested = item.nested;
|
|
722
836
|
}
|
|
723
837
|
if (nested) {
|
|
@@ -786,18 +900,6 @@ async function handleNestedFields(nested, value, field, context) {
|
|
|
786
900
|
}
|
|
787
901
|
async function handlePrimitiveType2(value, field, context) {
|
|
788
902
|
const errors = [];
|
|
789
|
-
if (containsIMLExpression(value)) {
|
|
790
|
-
return {
|
|
791
|
-
valid: true,
|
|
792
|
-
errors
|
|
793
|
-
};
|
|
794
|
-
}
|
|
795
|
-
if (errors.length > 0) {
|
|
796
|
-
return {
|
|
797
|
-
valid: false,
|
|
798
|
-
errors
|
|
799
|
-
};
|
|
800
|
-
}
|
|
801
903
|
if (field.validate) {
|
|
802
904
|
if (typeof value === "string") {
|
|
803
905
|
if (field.validate.pattern && !new RegExp(
|