@qoretechnologies/reqraft 0.10.46-pr.95.ge595a13 → 0.10.46
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/.claude/CLAUDE.md +12 -0
- package/.tasks/INDEX.md +1 -0
- package/.tasks/TEMPLATE_TOKEN_GRAMMAR.md +72 -0
- package/dist/components/composer/Composer.d.ts.map +1 -1
- package/dist/components/composer/Composer.js +5 -1
- package/dist/components/composer/Composer.js.map +1 -1
- package/dist/components/form/engine/CompactRow.d.ts +14 -0
- package/dist/components/form/engine/CompactRow.d.ts.map +1 -1
- package/dist/components/form/engine/CompactRow.js +199 -41
- package/dist/components/form/engine/CompactRow.js.map +1 -1
- package/dist/components/form/engine/CompactToolbar.d.ts.map +1 -1
- package/dist/components/form/engine/CompactToolbar.js +72 -72
- package/dist/components/form/engine/CompactToolbar.js.map +1 -1
- package/dist/components/form/engine/FormEngine.d.ts +65 -1
- package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
- package/dist/components/form/engine/FormEngine.js +276 -108
- package/dist/components/form/engine/FormEngine.js.map +1 -1
- package/dist/components/form/engine/_structuredData/SchemaDataView.d.ts.map +1 -1
- package/dist/components/form/engine/_structuredData/SchemaDataView.js +55 -13
- package/dist/components/form/engine/_structuredData/SchemaDataView.js.map +1 -1
- package/dist/components/form/engine/_structuredData/structuredData.d.ts +15 -0
- package/dist/components/form/engine/_structuredData/structuredData.d.ts.map +1 -1
- package/dist/components/form/engine/_structuredData/structuredData.js +22 -1
- package/dist/components/form/engine/_structuredData/structuredData.js.map +1 -1
- package/dist/components/form/engine/compactRowStyles.d.ts.map +1 -1
- package/dist/components/form/engine/compactRowStyles.js +15 -3
- package/dist/components/form/engine/compactRowStyles.js.map +1 -1
- package/dist/components/form/engine/compactToolbarContext.d.ts +8 -0
- package/dist/components/form/engine/compactToolbarContext.d.ts.map +1 -1
- package/dist/components/form/engine/compactToolbarContext.js.map +1 -1
- package/dist/components/form/engine/readFirst.d.ts +24 -0
- package/dist/components/form/engine/readFirst.d.ts.map +1 -1
- package/dist/components/form/engine/readFirst.js +84 -6
- package/dist/components/form/engine/readFirst.js.map +1 -1
- package/dist/components/form/fields/Field.d.ts.map +1 -1
- package/dist/components/form/fields/Field.js +1 -1
- package/dist/components/form/fields/Field.js.map +1 -1
- package/dist/components/form/fields/allowed-values/AllowedValues.d.ts +12 -2
- package/dist/components/form/fields/allowed-values/AllowedValues.d.ts.map +1 -1
- package/dist/components/form/fields/allowed-values/AllowedValues.js +16 -6
- package/dist/components/form/fields/allowed-values/AllowedValues.js.map +1 -1
- package/dist/components/form/fields/auto/AutoFormField.d.ts.map +1 -1
- package/dist/components/form/fields/auto/AutoFormField.js +64 -14
- package/dist/components/form/fields/auto/AutoFormField.js.map +1 -1
- package/dist/components/form/fields/long-string/LongString.d.ts +9 -1
- package/dist/components/form/fields/long-string/LongString.d.ts.map +1 -1
- package/dist/components/form/fields/long-string/LongString.js +25 -4
- package/dist/components/form/fields/long-string/LongString.js.map +1 -1
- package/dist/components/form/fields/template/ExampleValueModal.d.ts +29 -0
- package/dist/components/form/fields/template/ExampleValueModal.d.ts.map +1 -0
- package/dist/components/form/fields/template/ExampleValueModal.js +122 -0
- package/dist/components/form/fields/template/ExampleValueModal.js.map +1 -0
- package/dist/components/form/fields/template/ReadOnlyTemplateTag.d.ts.map +1 -1
- package/dist/components/form/fields/template/ReadOnlyTemplateTag.js +3 -3
- package/dist/components/form/fields/template/ReadOnlyTemplateTag.js.map +1 -1
- package/dist/components/form/fields/template/TemplateField.d.ts.map +1 -1
- package/dist/components/form/fields/template/TemplateField.js +81 -27
- package/dist/components/form/fields/template/TemplateField.js.map +1 -1
- package/dist/components/form/fields/template/__fixtures__/longExampleValue.d.ts +2 -0
- package/dist/components/form/fields/template/__fixtures__/longExampleValue.d.ts.map +1 -0
- package/dist/components/form/fields/template/__fixtures__/longExampleValue.js +9 -0
- package/dist/components/form/fields/template/__fixtures__/longExampleValue.js.map +1 -0
- package/dist/components/form/index.d.ts +1 -0
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/index.js +1 -0
- package/dist/components/form/index.js.map +1 -1
- package/dist/components/searchFilterBar/SearchFilterBar.d.ts +12 -1
- package/dist/components/searchFilterBar/SearchFilterBar.d.ts.map +1 -1
- package/dist/components/searchFilterBar/SearchFilterBar.js +2 -2
- package/dist/components/searchFilterBar/SearchFilterBar.js.map +1 -1
- package/dist/components/ticketThread/TicketThread.d.ts.map +1 -1
- package/dist/components/ticketThread/TicketThread.js +1 -1
- package/dist/components/ticketThread/TicketThread.js.map +1 -1
- package/dist/helpers/common.d.ts +8 -1
- package/dist/helpers/common.d.ts.map +1 -1
- package/dist/helpers/common.js +9 -1
- package/dist/helpers/common.js.map +1 -1
- package/dist/helpers/expressions.d.ts.map +1 -1
- package/dist/helpers/expressions.js +15 -2
- package/dist/helpers/expressions.js.map +1 -1
- package/dist/helpers/optionUiTypes.d.ts +30 -0
- package/dist/helpers/optionUiTypes.d.ts.map +1 -0
- package/dist/helpers/optionUiTypes.js +156 -0
- package/dist/helpers/optionUiTypes.js.map +1 -0
- package/dist/helpers/options.d.ts +19 -0
- package/dist/helpers/options.d.ts.map +1 -1
- package/dist/helpers/options.js +25 -1
- package/dist/helpers/options.js.map +1 -1
- package/dist/helpers/providerValue.d.ts +68 -0
- package/dist/helpers/providerValue.d.ts.map +1 -0
- package/dist/helpers/providerValue.js +50 -0
- package/dist/helpers/providerValue.js.map +1 -0
- package/dist/helpers/singleLineString.d.ts +37 -0
- package/dist/helpers/singleLineString.d.ts.map +1 -0
- package/dist/helpers/singleLineString.js +66 -0
- package/dist/helpers/singleLineString.js.map +1 -0
- package/dist/helpers/templates.d.ts +100 -0
- package/dist/helpers/templates.d.ts.map +1 -1
- package/dist/helpers/templates.js +237 -4
- package/dist/helpers/templates.js.map +1 -1
- package/dist/helpers/validations.d.ts +103 -2
- package/dist/helpers/validations.d.ts.map +1 -1
- package/dist/helpers/validations.js +858 -91
- package/dist/helpers/validations.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/composer/Composer.tsx +7 -3
- package/src/components/form/engine/CompactRow.tsx +279 -33
- package/src/components/form/engine/CompactToolbar.tsx +105 -98
- package/src/components/form/engine/FormEngine.stories.tsx +995 -12
- package/src/components/form/engine/FormEngine.tsx +377 -94
- package/src/components/form/engine/_structuredData/SchemaDataView.stories.tsx +104 -0
- package/src/components/form/engine/_structuredData/SchemaDataView.tsx +158 -101
- package/src/components/form/engine/_structuredData/structuredData.ts +20 -0
- package/src/components/form/engine/compactRowStyles.ts +55 -1
- package/src/components/form/engine/compactToolbarContext.ts +8 -0
- package/src/components/form/engine/readFirst.ts +125 -35
- package/src/components/form/fields/Field.tsx +3 -1
- package/src/components/form/fields/allowed-values/AllowedValues.tsx +24 -2
- package/src/components/form/fields/array/ArrayAutoField.stories.tsx +81 -0
- package/src/components/form/fields/auto/AutoFormField.stories.tsx +47 -1
- package/src/components/form/fields/auto/AutoFormField.tsx +73 -11
- package/src/components/form/fields/long-string/LongString.tsx +46 -5
- package/src/components/form/fields/schema-definition/SchemaDefinitionField.stories.tsx +5 -0
- package/src/components/form/fields/template/ExampleValueModal.stories.tsx +114 -0
- package/src/components/form/fields/template/ExampleValueModal.tsx +99 -0
- package/src/components/form/fields/template/ReadOnlyTemplateTag.tsx +8 -4
- package/src/components/form/fields/template/TemplateField.stories.tsx +389 -1
- package/src/components/form/fields/template/TemplateField.tsx +100 -35
- package/src/components/form/fields/template/__fixtures__/longExampleValue.ts +7 -0
- package/src/components/form/index.tsx +1 -0
- package/src/components/searchFilterBar/SearchFilterBar.stories.tsx +62 -0
- package/src/components/searchFilterBar/SearchFilterBar.tsx +13 -0
- package/src/components/ticketThread/TicketThread.tsx +7 -0
- package/src/helpers/common.ts +11 -1
- package/src/helpers/expressions.ts +16 -2
- package/src/helpers/optionUiTypes.ts +161 -0
- package/src/helpers/options.ts +23 -0
- package/src/helpers/providerValue.ts +125 -0
- package/src/helpers/singleLineString.ts +61 -0
- package/src/helpers/templates.ts +272 -3
- package/src/helpers/validations.ts +1177 -109
- package/src/hooks/useWebSocket/useWebsocket.stories.tsx +23 -2
- package/src/index.tsx +1 -0
|
@@ -23,7 +23,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
23
23
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.hasAllDependenciesFullfilled = exports.validateOptionWithRequiredGroups = exports.getTypeFromValue = exports.getValueOrDefaultValue = exports.isValueSet = exports.maybeParseYaml = exports.validateField = exports.validateFieldWithResult = exports.readArgValue = exports._validateField = void 0;
|
|
26
|
+
exports.hasAllDependenciesFullfilled = exports.parseDependency = exports.getUnresolvedRequiredOptions = exports.getUnresolvedRequiredOptionReason = exports.validateOptionWithRequiredGroups = exports.getTypeFromValue = exports.getValueOrDefaultValue = exports.isValueSet = exports.maybeParseYaml = exports.validateField = exports.validateFieldWithResult = exports.readArgValue = exports._validateField = exports.setExpressionCatalogueReader = exports.cronExpressionFromValue = void 0;
|
|
27
27
|
var colors_1 = require("@qoretechnologies/reqore/dist/helpers/colors");
|
|
28
28
|
var cron_validator_1 = require("cron-validator");
|
|
29
29
|
var js_yaml_1 = __importDefault(require("js-yaml"));
|
|
@@ -35,9 +35,74 @@ var isNaN_1 = __importDefault(require("lodash/isNaN"));
|
|
|
35
35
|
var isNumber_1 = __importDefault(require("lodash/isNumber"));
|
|
36
36
|
var isPlainObject_1 = __importDefault(require("lodash/isPlainObject"));
|
|
37
37
|
var size_1 = __importDefault(require("lodash/size"));
|
|
38
|
+
var uniqWith_1 = __importDefault(require("lodash/uniqWith"));
|
|
38
39
|
var common_1 = require("./common");
|
|
40
|
+
var optionUiTypes_1 = require("./optionUiTypes");
|
|
39
41
|
var options_1 = require("./options");
|
|
42
|
+
var providerValue_1 = require("./providerValue");
|
|
40
43
|
var templates_1 = require("./templates");
|
|
44
|
+
/** The five cron fields, in order, as a schedule hash may name them. */
|
|
45
|
+
var CRON_FIELDS = [
|
|
46
|
+
['minutes', 'minute'],
|
|
47
|
+
['hours', 'hour'],
|
|
48
|
+
['days', 'day'],
|
|
49
|
+
['months', 'month'],
|
|
50
|
+
['dow', 'weekday'],
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* A five-field cron expression, from either representation a caller may hold.
|
|
54
|
+
*
|
|
55
|
+
* A schedule reaches the form in one of two shapes, and both are legitimate: a
|
|
56
|
+
* joined string (`"0 0 1 1 *"`), or the hash a Qorus job carries
|
|
57
|
+
* (`{minutes, hours, days, months, dow}` — also accepted under the singular
|
|
58
|
+
* `minute`/`hour`/`day`/`month`/`weekday` spellings). The renderer already
|
|
59
|
+
* accepted both; validation did not, and fed the hash straight to
|
|
60
|
+
* `isValidCron`, which calls `.trim()` on it.
|
|
61
|
+
*
|
|
62
|
+
* Returns `undefined` for anything that is neither, so the caller reports an
|
|
63
|
+
* invalid value rather than throwing.
|
|
64
|
+
*/
|
|
65
|
+
var cronExpressionFromValue = function (value) {
|
|
66
|
+
if (typeof value === 'string') {
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
var hash = value;
|
|
73
|
+
var parts = CRON_FIELDS.map(function (_a) {
|
|
74
|
+
var _b;
|
|
75
|
+
var plural = _a[0], singular = _a[1];
|
|
76
|
+
var field = (_b = hash[plural]) !== null && _b !== void 0 ? _b : hash[singular];
|
|
77
|
+
return field === undefined || field === null || field === '' ? '*' : String(field);
|
|
78
|
+
});
|
|
79
|
+
// An object with none of the five keys is not a schedule — every part
|
|
80
|
+
// defaulting to `*` would otherwise turn any object at all into "* * * * *"
|
|
81
|
+
return parts.every(function (part) { return part === '*'; }) &&
|
|
82
|
+
!CRON_FIELDS.some(function (_a) {
|
|
83
|
+
var plural = _a[0], singular = _a[1];
|
|
84
|
+
return plural in hash || singular in hash;
|
|
85
|
+
})
|
|
86
|
+
? undefined
|
|
87
|
+
: parts.join(' ');
|
|
88
|
+
};
|
|
89
|
+
exports.cronExpressionFromValue = cronExpressionFromValue;
|
|
90
|
+
var expressionCatalogueReader;
|
|
91
|
+
var setExpressionCatalogueReader = function (reader) {
|
|
92
|
+
expressionCatalogueReader = reader;
|
|
93
|
+
};
|
|
94
|
+
exports.setExpressionCatalogueReader = setExpressionCatalogueReader;
|
|
95
|
+
var readExpressionCatalogue = function (field) { var _a, _b; return (_b = (_a = field === null || field === void 0 ? void 0 : field.expressions) !== null && _a !== void 0 ? _a : expressionCatalogueReader === null || expressionCatalogueReader === void 0 ? void 0 : expressionCatalogueReader()) !== null && _b !== void 0 ? _b : []; };
|
|
96
|
+
// permissive patterns for the semantic string formats — mirror the qore DataProvider
|
|
97
|
+
// QoreStringFormatDataType server backstop (email/uuid/hostname/ipv4/ipv6/phone)
|
|
98
|
+
var SEMANTIC_FORMAT_PATTERNS = {
|
|
99
|
+
email: /^[^@\s]+@[^@\s]+$/,
|
|
100
|
+
uuid: /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/,
|
|
101
|
+
hostname: /^[A-Za-z0-9.-]+$/,
|
|
102
|
+
ipv4: /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/,
|
|
103
|
+
ipv6: /^([0-9A-Fa-f]{0,4}:){2,7}[0-9A-Fa-f]{0,4}$/,
|
|
104
|
+
phone: /^\+?[0-9 ().-]{3,}$/,
|
|
105
|
+
};
|
|
41
106
|
var validResult = function () { return ({ isValid: true, reasons: [] }); };
|
|
42
107
|
var invalidResult = function (reason, childReasons) {
|
|
43
108
|
if (childReasons === void 0) { childReasons = []; }
|
|
@@ -74,7 +139,7 @@ var isValueDefined = function (type, value) {
|
|
|
74
139
|
return value !== undefined && value !== '';
|
|
75
140
|
};
|
|
76
141
|
var _validateField = function (type, value, field, canBeNull) {
|
|
77
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
142
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
78
143
|
if (!type) {
|
|
79
144
|
if (value === undefined || value === null) {
|
|
80
145
|
return invalidResult('Missing value');
|
|
@@ -90,13 +155,6 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
90
155
|
if (canBeNull && (value === null || value === undefined)) {
|
|
91
156
|
return validResult();
|
|
92
157
|
}
|
|
93
|
-
// Expression values (`is_expression`) carry the AST `{ exp, args }` instead
|
|
94
|
-
// of a typed literal — validate that an expression is chosen, not the
|
|
95
|
-
// base type. (`isFunction` is set by FormEngine for expression options.)
|
|
96
|
-
if (field === null || field === void 0 ? void 0 : field.isFunction) {
|
|
97
|
-
var ast = (_a = value === null || value === void 0 ? void 0 : value.value) !== null && _a !== void 0 ? _a : value;
|
|
98
|
-
return resultFromBoolean(!!(ast === null || ast === void 0 ? void 0 : ast.exp), 'Expression operation is required');
|
|
99
|
-
}
|
|
100
158
|
// Strip type parameters e.g. hash<string, int> → hash
|
|
101
159
|
var pos = type.indexOf('<');
|
|
102
160
|
if (pos > 0) {
|
|
@@ -108,6 +166,16 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
108
166
|
var hasValue = !!(0, templates_1.getTemplateValue)(value);
|
|
109
167
|
return resultFromBoolean(hasKey && hasValue, 'Template must include key and value');
|
|
110
168
|
}
|
|
169
|
+
// Expression values (`is_expression`) carry the AST `{ exp, args }` instead of
|
|
170
|
+
// a typed literal, so the declared type says nothing about them — validate
|
|
171
|
+
// them as the expression they are, arguments and all. (`isFunction` is set by
|
|
172
|
+
// FormEngine, and by the option recursion below, for expression options.)
|
|
173
|
+
if (field === null || field === void 0 ? void 0 : field.isFunction) {
|
|
174
|
+
// The AST is normally the value itself; a caller that still holds the
|
|
175
|
+
// option envelope hands over `{ value: ast }`, so accept both.
|
|
176
|
+
var ast = (_a = value === null || value === void 0 ? void 0 : value.value) !== null && _a !== void 0 ? _a : value;
|
|
177
|
+
return (0, exports.validateFieldWithResult)('expression', { value: ast }, (0, lodash_1.omit)(field, ['isFunction']), canBeNull);
|
|
178
|
+
}
|
|
111
179
|
// Check if the field has required groups
|
|
112
180
|
if (field === null || field === void 0 ? void 0 : field.required_groups) {
|
|
113
181
|
if (!isValueDefined(type, value) &&
|
|
@@ -115,6 +183,12 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
115
183
|
return validResult();
|
|
116
184
|
}
|
|
117
185
|
}
|
|
186
|
+
// An interface type names another Qorus object by its name, so a non-empty
|
|
187
|
+
// string is the whole contract. `connection` is the exception: it carries
|
|
188
|
+
// enablement and authentication state of its own, checked below.
|
|
189
|
+
if ((0, optionUiTypes_1.isOptionInterfaceUiType)(type) && type !== 'connection') {
|
|
190
|
+
return (0, exports.validateFieldWithResult)('string', value, field);
|
|
191
|
+
}
|
|
118
192
|
switch (type) {
|
|
119
193
|
case 'richtext': {
|
|
120
194
|
if (!value || !(0, size_1.default)(value)) {
|
|
@@ -151,28 +225,53 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
151
225
|
}
|
|
152
226
|
return withContext((0, exports.validateFieldWithResult)('string', value, field), 'Connection string validation failed');
|
|
153
227
|
}
|
|
228
|
+
// semantic string formats — permissive patterns mirror the qore DataProvider
|
|
229
|
+
// QoreStringFormatDataType backstop; a server-supplied validation_regex, if
|
|
230
|
+
// present, is also enforced
|
|
231
|
+
case 'email':
|
|
232
|
+
case 'uuid':
|
|
233
|
+
case 'hostname':
|
|
234
|
+
case 'ipv4':
|
|
235
|
+
case 'ipv6':
|
|
236
|
+
case 'phone': {
|
|
237
|
+
if (value === undefined || value === null || value === '' || typeof value !== 'string') {
|
|
238
|
+
return invalidResult('Value must be a non-empty text');
|
|
239
|
+
}
|
|
240
|
+
if ((field === null || field === void 0 ? void 0 : field.validation_regex) && !value.match(field.validation_regex)) {
|
|
241
|
+
return invalidResult('Value does not match the required format');
|
|
242
|
+
}
|
|
243
|
+
return resultFromBoolean(SEMANTIC_FORMAT_PATTERNS[type].test(value), "Value is not a valid ".concat(type));
|
|
244
|
+
}
|
|
154
245
|
case 'binary': {
|
|
155
246
|
if (typeof value !== 'string') {
|
|
156
247
|
return invalidResult('Binary value must be a string');
|
|
157
248
|
}
|
|
158
|
-
var
|
|
159
|
-
if (
|
|
249
|
+
var trimmed = value.trim();
|
|
250
|
+
if (trimmed.length === 0) {
|
|
160
251
|
return invalidResult('Binary value is empty');
|
|
161
252
|
}
|
|
162
|
-
|
|
163
|
-
|
|
253
|
+
// the canonical wire form is base64 (matching the server decode); a "data:<mime>;base64,..." URL
|
|
254
|
+
// and legacy "0x"-prefixed hex are also accepted
|
|
255
|
+
if (/^data:[^;]+;base64,/.test(trimmed)) {
|
|
256
|
+
return validResult();
|
|
164
257
|
}
|
|
165
|
-
if (
|
|
166
|
-
|
|
258
|
+
if (/^0x/i.test(trimmed)) {
|
|
259
|
+
var hex = trimmed.replace(/^0x/i, '');
|
|
260
|
+
return resultFromBoolean(hex.length % 2 === 0 && /^[0-9a-fA-F]+$/.test(hex), 'Binary hex value is invalid');
|
|
167
261
|
}
|
|
168
|
-
return
|
|
262
|
+
return resultFromBoolean(/^[A-Za-z0-9+/]+={0,2}$/.test(trimmed), 'Binary value must be base64, a data: URL, or 0x-prefixed hex');
|
|
169
263
|
}
|
|
170
264
|
case 'string':
|
|
171
265
|
case 'mapper':
|
|
172
266
|
case 'workflow':
|
|
173
267
|
case 'service':
|
|
174
268
|
case 'job':
|
|
269
|
+
case 'softstring':
|
|
270
|
+
case 'select-string':
|
|
271
|
+
case 'file-string':
|
|
272
|
+
case 'file-as-string':
|
|
175
273
|
case 'long-string':
|
|
274
|
+
case 'method-name':
|
|
176
275
|
case 'code-editor':
|
|
177
276
|
case 'data': {
|
|
178
277
|
if (value === undefined || value === null || value === '' || typeof value !== 'string') {
|
|
@@ -234,6 +333,109 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
234
333
|
: withContext(contentResult, 'File content is invalid').reasons), true);
|
|
235
334
|
return reasons.length ? invalidResult(reasons) : validResult();
|
|
236
335
|
}
|
|
336
|
+
case 'collection-documents': {
|
|
337
|
+
// The value is an array of rows in mixed lifecycle states.
|
|
338
|
+
// A row is valid when it's either:
|
|
339
|
+
// 1. Server-managed: has `ai_documentid` (number) + `name`.
|
|
340
|
+
// 2. Client-managed: has `name` + `content` (base64) — i.e.
|
|
341
|
+
// a fresh upload that hasn't landed yet.
|
|
342
|
+
// Failed rows count as valid for form-level purposes (the
|
|
343
|
+
// user can Retry; the form shouldn't block save just because
|
|
344
|
+
// an upload errored). Empty list is valid here — the
|
|
345
|
+
// top-level required check (`field.required`) handles "must
|
|
346
|
+
// pick at least one" gating.
|
|
347
|
+
if (value === undefined || value === null) {
|
|
348
|
+
return validResult();
|
|
349
|
+
}
|
|
350
|
+
if (!Array.isArray(value)) {
|
|
351
|
+
return invalidResult('Value must be a list of documents');
|
|
352
|
+
}
|
|
353
|
+
var reasons_1 = [];
|
|
354
|
+
value.forEach(function (row, idx) {
|
|
355
|
+
if (!row || typeof row !== 'object') {
|
|
356
|
+
reasons_1.push("Row ".concat(idx + 1, " is not an object"));
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (typeof row.name !== 'string' || !row.name) {
|
|
360
|
+
reasons_1.push("Row ".concat(idx + 1, " is missing a name"));
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
var hasServerId = typeof row.ai_documentid === 'number';
|
|
364
|
+
var hasContent = typeof row.content === 'string' && !!row.content;
|
|
365
|
+
if (!hasServerId && !hasContent) {
|
|
366
|
+
reasons_1.push("Row ".concat(idx + 1, " (\"").concat(row.name, "\") has neither uploaded ") +
|
|
367
|
+
"content nor a server document id");
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
return reasons_1.length ? invalidResult(undefined, reasons_1) : validResult();
|
|
371
|
+
}
|
|
372
|
+
case 'array-of-pairs': {
|
|
373
|
+
var valid = true;
|
|
374
|
+
var reasons = [];
|
|
375
|
+
// Check if every pair has key & value
|
|
376
|
+
// assigned properly
|
|
377
|
+
if (!Array.isArray(value)) {
|
|
378
|
+
return invalidResult('Value must be a list');
|
|
379
|
+
}
|
|
380
|
+
if (!(value === null || value === void 0 ? void 0 : value.every(function (pair) {
|
|
381
|
+
return pair[field.fields[0]] !== '' && pair[field.fields[1]] !== '';
|
|
382
|
+
}))) {
|
|
383
|
+
valid = false;
|
|
384
|
+
reasons.push('All pairs must include both fields');
|
|
385
|
+
}
|
|
386
|
+
// Get a list of unique values
|
|
387
|
+
var uniqueValues = (0, uniqWith_1.default)(value, function (cur, prev) { return cur[field.fields[0]] === prev[field.fields[0]]; });
|
|
388
|
+
// Check if there are any duplicates
|
|
389
|
+
if ((0, size_1.default)(uniqueValues) !== (0, size_1.default)(value)) {
|
|
390
|
+
valid = false;
|
|
391
|
+
reasons.push('Pairs must use unique keys');
|
|
392
|
+
}
|
|
393
|
+
return valid ? validResult() : invalidResult(undefined, reasons);
|
|
394
|
+
}
|
|
395
|
+
case 'class-connectors': {
|
|
396
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
397
|
+
return invalidResult('At least one connector is required');
|
|
398
|
+
}
|
|
399
|
+
var valid = true;
|
|
400
|
+
var reasons = [];
|
|
401
|
+
// Check if every pair has name, input method and output method
|
|
402
|
+
// assigned properly
|
|
403
|
+
if (!(value === null || value === void 0 ? void 0 : value.every(function (pair) {
|
|
404
|
+
return !!pair.name && pair.name !== '' && !!pair.method && pair.method !== '';
|
|
405
|
+
}))) {
|
|
406
|
+
valid = false;
|
|
407
|
+
reasons.push('Each connector must have a name and method');
|
|
408
|
+
}
|
|
409
|
+
// Get a list of unique values
|
|
410
|
+
var uniqueValues = (0, uniqWith_1.default)(value, function (cur, prev) { return cur.name === prev.name; });
|
|
411
|
+
// Check if there are any duplicates
|
|
412
|
+
if ((0, size_1.default)(uniqueValues) !== (0, size_1.default)(value)) {
|
|
413
|
+
valid = false;
|
|
414
|
+
reasons.push('Connector names must be unique');
|
|
415
|
+
}
|
|
416
|
+
return valid ? validResult() : invalidResult(undefined, reasons);
|
|
417
|
+
}
|
|
418
|
+
// Classes check
|
|
419
|
+
case 'class-array': {
|
|
420
|
+
if (!(Array.isArray(value) && value.length > 0)) {
|
|
421
|
+
return invalidResult('At least one class must be provided');
|
|
422
|
+
}
|
|
423
|
+
var valid = true;
|
|
424
|
+
var reasons = [];
|
|
425
|
+
// Check if the fields are not empty
|
|
426
|
+
if (!(value === null || value === void 0 ? void 0 : value.every(function (pair) { return !!pair.name && pair.name !== ''; }))) {
|
|
427
|
+
valid = false;
|
|
428
|
+
reasons.push('Each class must have a name');
|
|
429
|
+
}
|
|
430
|
+
// Get a list of unique values
|
|
431
|
+
var uniqueValues = (0, uniqWith_1.default)(value, function (cur, prev) { return "".concat(cur.prefix).concat(cur.name) === "".concat(prev.prefix).concat(prev.name); });
|
|
432
|
+
// Check if there are any duplicates
|
|
433
|
+
if ((0, size_1.default)(uniqueValues) !== (0, size_1.default)(value)) {
|
|
434
|
+
valid = false;
|
|
435
|
+
reasons.push('Class names must be unique');
|
|
436
|
+
}
|
|
437
|
+
return valid ? validResult() : invalidResult(undefined, reasons);
|
|
438
|
+
}
|
|
237
439
|
case 'number': {
|
|
238
440
|
return resultFromBoolean(!(0, isNaN_1.default)(value) && ((0, exports.getTypeFromValue)(value) === 'float' || (0, exports.getTypeFromValue)(value) === 'int'), 'Value must be a number');
|
|
239
441
|
}
|
|
@@ -241,15 +443,25 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
241
443
|
return resultFromBoolean(!Number.isNaN(value) && (0, exports.getTypeFromValue)(value) === 'int', 'Value must be an integer');
|
|
242
444
|
case 'float':
|
|
243
445
|
return resultFromBoolean(!(0, isNaN_1.default)(value) && ((0, exports.getTypeFromValue)(value) === 'float' || (0, exports.getTypeFromValue)(value) === 'int'), 'Value must be a float');
|
|
446
|
+
case 'select-array':
|
|
244
447
|
case 'multi-select':
|
|
245
448
|
case 'array':
|
|
246
449
|
case 'file-tree':
|
|
247
450
|
return resultFromBoolean(value && value.length > 0, 'At least one value is required');
|
|
248
|
-
case 'cron':
|
|
451
|
+
case 'cron': {
|
|
249
452
|
if (!value) {
|
|
250
453
|
return invalidResult('Cron value is required');
|
|
251
454
|
}
|
|
252
|
-
|
|
455
|
+
var expression = (0, exports.cronExpressionFromValue)(value);
|
|
456
|
+
// A value that is neither a cron string nor a schedule hash is INVALID,
|
|
457
|
+
// not a crash: `isValidCron` calls `.trim()` on whatever it is given, so
|
|
458
|
+
// passing it a hash threw a TypeError out of validation and took the
|
|
459
|
+
// whole form down through the host's error boundary.
|
|
460
|
+
if (expression === undefined) {
|
|
461
|
+
return invalidResult('Cron expression is invalid');
|
|
462
|
+
}
|
|
463
|
+
return resultFromBoolean((0, cron_validator_1.isValidCron)(expression, { alias: true }), 'Cron expression is invalid');
|
|
464
|
+
}
|
|
253
465
|
case 'date':
|
|
254
466
|
return resultFromBoolean(value !== undefined &&
|
|
255
467
|
value !== null &&
|
|
@@ -293,7 +505,14 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
293
505
|
}
|
|
294
506
|
if ((field === null || field === void 0 ? void 0 : field.ui_element_type) || (field === null || field === void 0 ? void 0 : field.element_type)) {
|
|
295
507
|
for (var i = 0; i < parsedValue.length; i++) {
|
|
296
|
-
var itemResult = (0, exports.validateFieldWithResult)(field.ui_element_type || field.element_type,
|
|
508
|
+
var itemResult = (0, exports.validateFieldWithResult)(field.ui_element_type || field.element_type,
|
|
509
|
+
// An element arrives bare OR in a `{value, type}` envelope: the
|
|
510
|
+
// envelope is what the editor writes, the bare form is what storage
|
|
511
|
+
// holds. Reaching straight for `.value` failed every stored element
|
|
512
|
+
// as empty, so a reloaded alert rule reported its delivery action
|
|
513
|
+
// invalid while showing all six options set -- and threw outright on
|
|
514
|
+
// a null element.
|
|
515
|
+
(0, options_1.getListElementValue)(parsedValue[i]), field);
|
|
297
516
|
if (!itemResult.isValid) {
|
|
298
517
|
return withContext(itemResult, "List item ".concat(i, " is invalid"));
|
|
299
518
|
}
|
|
@@ -301,27 +520,409 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
301
520
|
}
|
|
302
521
|
return validResult();
|
|
303
522
|
}
|
|
304
|
-
case '
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
523
|
+
case 'list-of-hashes': {
|
|
524
|
+
var parsedValue = (0, exports.maybeParseYaml)(value);
|
|
525
|
+
if (!parsedValue || !(0, isArray_1.default)(parsedValue)) {
|
|
526
|
+
return invalidResult('Value must be a list of hashes');
|
|
527
|
+
}
|
|
528
|
+
for (var i = 0; i < parsedValue.length; i++) {
|
|
529
|
+
var item = parsedValue[i];
|
|
530
|
+
if (!(0, size_1.default)(item)) {
|
|
531
|
+
return invalidResult("Hash at index ".concat(i, " must not be empty"));
|
|
532
|
+
}
|
|
533
|
+
var itemResult = (0, exports.validateFieldWithResult)('hash', item);
|
|
534
|
+
if (!itemResult.isValid) {
|
|
535
|
+
return withContext(itemResult, "Hash at index ".concat(i, " is invalid"));
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return validResult();
|
|
539
|
+
}
|
|
540
|
+
case 'mapper-code': {
|
|
541
|
+
if (!value) {
|
|
542
|
+
return invalidResult('Mapper code is required');
|
|
543
|
+
}
|
|
544
|
+
// Split the value
|
|
545
|
+
var _r = value.split('::'), code = _r[0], method = _r[1];
|
|
546
|
+
// Both fields need to be strings & filled
|
|
547
|
+
var codeResult = (0, exports.validateFieldWithResult)('string', code);
|
|
548
|
+
if (!codeResult.isValid) {
|
|
549
|
+
return withContext(codeResult, 'Mapper code is invalid');
|
|
550
|
+
}
|
|
551
|
+
var methodResult = (0, exports.validateFieldWithResult)('string', method);
|
|
552
|
+
if (!methodResult.isValid) {
|
|
553
|
+
return withContext(methodResult, 'Mapper method is invalid');
|
|
554
|
+
}
|
|
555
|
+
return validResult();
|
|
556
|
+
}
|
|
557
|
+
case 'var-action': {
|
|
558
|
+
var varAction = value;
|
|
559
|
+
if ((varAction === null || varAction === void 0 ? void 0 : varAction.var_type) !== 'localvar' &&
|
|
560
|
+
(varAction === null || varAction === void 0 ? void 0 : varAction.var_type) !== 'globalvar' &&
|
|
561
|
+
(varAction === null || varAction === void 0 ? void 0 : varAction.var_type) !== 'autovar') {
|
|
562
|
+
return invalidResult('Variable type is invalid');
|
|
563
|
+
}
|
|
564
|
+
var nameResult = (0, exports.validateFieldWithResult)('string', varAction.var_name, {
|
|
565
|
+
has_to_have_value: true,
|
|
566
|
+
});
|
|
567
|
+
if (!nameResult.isValid) {
|
|
568
|
+
return withContext(nameResult, 'Variable name is invalid');
|
|
569
|
+
}
|
|
570
|
+
var actionResult = (0, exports.validateFieldWithResult)('string', varAction.action_type, {
|
|
571
|
+
has_to_have_value: true,
|
|
572
|
+
});
|
|
573
|
+
if (!actionResult.isValid) {
|
|
574
|
+
return withContext(actionResult, 'Variable action type is invalid');
|
|
575
|
+
}
|
|
576
|
+
// If the action type is transaction, the transaction_action needs to be set
|
|
577
|
+
if (varAction.action_type === 'transaction') {
|
|
578
|
+
var transactionResult = (0, exports.validateFieldWithResult)('string', varAction.transaction_action, {
|
|
579
|
+
has_to_have_value: true,
|
|
580
|
+
});
|
|
581
|
+
if (!transactionResult.isValid) {
|
|
582
|
+
return withContext(transactionResult, 'Transaction action is invalid');
|
|
583
|
+
}
|
|
584
|
+
return validResult();
|
|
585
|
+
}
|
|
586
|
+
// If the variable data is missing
|
|
587
|
+
if (!((_d = field === null || field === void 0 ? void 0 : field.variableData) === null || _d === void 0 ? void 0 : _d.value)) {
|
|
588
|
+
return invalidResult('Variable data is missing');
|
|
589
|
+
}
|
|
590
|
+
// Get the variable data
|
|
591
|
+
var variableData = __assign(__assign({}, value), field.variableData.value);
|
|
592
|
+
return withContext((0, exports.validateFieldWithResult)(varAction.action_type, variableData, field), 'Variable action is invalid');
|
|
593
|
+
}
|
|
594
|
+
case 'type-selector':
|
|
595
|
+
case 'data-provider':
|
|
596
|
+
case 'api-call':
|
|
597
|
+
case 'search-single':
|
|
598
|
+
case 'send-message':
|
|
599
|
+
case 'search':
|
|
600
|
+
case 'update':
|
|
601
|
+
case 'delete':
|
|
602
|
+
case 'create': {
|
|
603
|
+
var newValue = (0, providerValue_1.maybeBuildOptionProvider)(value);
|
|
604
|
+
if (!newValue) {
|
|
605
|
+
return invalidResult('Provider value is invalid');
|
|
606
|
+
}
|
|
607
|
+
// Api call only supports requests / response
|
|
608
|
+
if (type === 'api-call' && !value.supports_request) {
|
|
609
|
+
return invalidResult('API call must support requests');
|
|
610
|
+
}
|
|
611
|
+
// If the provider is from FSM variables, it needs pass this
|
|
612
|
+
if ((field === null || field === void 0 ? void 0 : field.isVariable) &&
|
|
613
|
+
!(newValue.supports_read ||
|
|
614
|
+
newValue.supports_create ||
|
|
615
|
+
newValue.supports_update ||
|
|
616
|
+
newValue.supports_delete ||
|
|
617
|
+
newValue.supports_request ||
|
|
618
|
+
newValue.supports_messages ||
|
|
619
|
+
newValue.transaction_management)) {
|
|
620
|
+
return invalidResult('Variable provider must support at least one action');
|
|
621
|
+
}
|
|
622
|
+
// Send message only supports messages
|
|
623
|
+
if (type === 'send-message' &&
|
|
624
|
+
(!newValue.supports_messages || !newValue.message_id || !newValue.message)) {
|
|
625
|
+
return invalidResult('Send message provider must include message id and content');
|
|
626
|
+
}
|
|
627
|
+
if (newValue.message_id) {
|
|
628
|
+
var messageIdResult = (0, exports.validateFieldWithResult)('string', newValue.message_id);
|
|
629
|
+
if (!messageIdResult.isValid) {
|
|
630
|
+
return withContext(messageIdResult, 'Message id is invalid');
|
|
631
|
+
}
|
|
632
|
+
if (!newValue.message) {
|
|
633
|
+
return invalidResult('Message content is missing');
|
|
634
|
+
}
|
|
635
|
+
var messageResult = (0, exports.validateFieldWithResult)(newValue.message.type, newValue.message.value);
|
|
636
|
+
if (!messageResult.isValid) {
|
|
637
|
+
return withContext(messageResult, 'Message content is invalid');
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
if (newValue.use_args) {
|
|
641
|
+
if (((_e = newValue.args) === null || _e === void 0 ? void 0 : _e.type) !== 'nothing') {
|
|
642
|
+
if (!newValue.args) {
|
|
643
|
+
return invalidResult('Arguments are missing');
|
|
644
|
+
}
|
|
645
|
+
var argsResult = (0, exports.validateFieldWithResult)(newValue.args.type === 'hash' ? 'system-options' : newValue.args.type, newValue.args.value);
|
|
646
|
+
if (!argsResult.isValid) {
|
|
647
|
+
return withContext(argsResult, 'Arguments are invalid');
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
if ((type === 'search-single' || type === 'search') &&
|
|
652
|
+
(0, size_1.default)(newValue.search_args) !== 0 &&
|
|
653
|
+
!(0, exports.validateFieldWithResult)('system-options-with-operators', newValue.search_args).isValid) {
|
|
654
|
+
return invalidResult('Search arguments are invalid');
|
|
655
|
+
}
|
|
656
|
+
var isUpdateOrCreate = type === 'update' || type === 'create';
|
|
657
|
+
if (isUpdateOrCreate) {
|
|
658
|
+
var areNormalArgsInvalid = "".concat(type, "_args") in newValue &&
|
|
659
|
+
((0, size_1.default)(newValue["".concat(type, "_args")]) === 0 ||
|
|
660
|
+
!(0, exports.validateFieldWithResult)('system-options', newValue["".concat(type, "_args")]).isValid);
|
|
661
|
+
var areFreeFormArgsInvalid = "".concat(type, "_args_freeform") in newValue &&
|
|
662
|
+
((0, size_1.default)(newValue["".concat(type, "_args_freeform")]) === 0 ||
|
|
663
|
+
!(0, exports.validateFieldWithResult)('list-of-hashes', newValue["".concat(type, "_args_freeform")]).isValid);
|
|
664
|
+
if ("".concat(type, "_args") in newValue && areNormalArgsInvalid && areFreeFormArgsInvalid) {
|
|
665
|
+
return invalidResult('Update/create arguments are invalid');
|
|
666
|
+
}
|
|
667
|
+
if ("".concat(type, "_args_freeform") in newValue && areFreeFormArgsInvalid && areNormalArgsInvalid) {
|
|
668
|
+
return invalidResult('Update/create arguments are invalid');
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
if ((newValue === null || newValue === void 0 ? void 0 : newValue.type) === 'factory') {
|
|
672
|
+
if (newValue.optionsChanged) {
|
|
673
|
+
return invalidResult('Factory options are not saved');
|
|
674
|
+
}
|
|
675
|
+
var options = true;
|
|
676
|
+
if (newValue.options) {
|
|
677
|
+
options = (0, exports.validateFieldWithResult)('system-options', newValue.options).isValid;
|
|
678
|
+
}
|
|
679
|
+
// Type path and name are required
|
|
680
|
+
return resultFromBoolean(!!(newValue.type && newValue.name && options), 'Factory provider is incomplete');
|
|
681
|
+
}
|
|
682
|
+
if (newValue.record_requires_search_options && newValue.searchOptionsChanged) {
|
|
683
|
+
return invalidResult('Search options must be saved');
|
|
684
|
+
}
|
|
685
|
+
if (newValue.search_options &&
|
|
686
|
+
!(0, exports.validateFieldWithResult)('system-options', newValue.search_options).isValid) {
|
|
687
|
+
return invalidResult('Search options are invalid');
|
|
688
|
+
}
|
|
689
|
+
return resultFromBoolean(!!(newValue.type && newValue.name), 'Provider type and name required');
|
|
690
|
+
}
|
|
691
|
+
case 'context-selector': {
|
|
692
|
+
if ((0, lodash_1.isString)(value)) {
|
|
693
|
+
var cont = value.split(':');
|
|
694
|
+
var contextResult = (0, exports.validateFieldWithResult)('string', cont[0]);
|
|
695
|
+
if (!contextResult.isValid) {
|
|
696
|
+
return withContext(contextResult, 'Context selector prefix is invalid');
|
|
697
|
+
}
|
|
698
|
+
var nameResult = (0, exports.validateFieldWithResult)('string', cont[1]);
|
|
699
|
+
if (!nameResult.isValid) {
|
|
700
|
+
return withContext(nameResult, 'Context selector name is invalid');
|
|
701
|
+
}
|
|
702
|
+
return validResult();
|
|
703
|
+
}
|
|
704
|
+
return resultFromBoolean(!!(value === null || value === void 0 ? void 0 : value.iface_kind) && !!(value === null || value === void 0 ? void 0 : value.name), 'Context selector requires iface_kind and name');
|
|
705
|
+
}
|
|
706
|
+
case 'service-event': {
|
|
707
|
+
var typeResult = (0, exports.validateFieldWithResult)('type-selector', value);
|
|
708
|
+
if (!typeResult.isValid) {
|
|
709
|
+
return withContext(typeResult, 'Service event type is invalid');
|
|
710
|
+
}
|
|
711
|
+
if (!(0, size_1.default)(value.handlers) ||
|
|
712
|
+
!(0, every_1.default)(value.handlers, function (handler) { return (handler.type === 'fsm' || handler.type === 'method') && handler.value; })) {
|
|
713
|
+
return invalidResult('Service event handlers are invalid');
|
|
714
|
+
}
|
|
715
|
+
return validResult();
|
|
716
|
+
}
|
|
717
|
+
case 'service-events': {
|
|
718
|
+
if (!(0, isArray_1.default)(value) || !(0, size_1.default)(value)) {
|
|
719
|
+
return invalidResult('At least one service event is required');
|
|
720
|
+
}
|
|
721
|
+
for (var i = 0; i < value.length; i++) {
|
|
722
|
+
var serviceEventResult = (0, exports.validateFieldWithResult)('service-event', value[i]);
|
|
723
|
+
if (!serviceEventResult.isValid) {
|
|
724
|
+
return withContext(serviceEventResult, "Service event ".concat(i, " is invalid"));
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
return validResult();
|
|
728
|
+
}
|
|
729
|
+
case 'service-webhook': {
|
|
730
|
+
if (!(0, exports.validateFieldWithResult)('string', value === null || value === void 0 ? void 0 : value.name).isValid ||
|
|
731
|
+
!(0, exports.validateFieldWithResult)('string', value === null || value === void 0 ? void 0 : value['rest-method']).isValid ||
|
|
732
|
+
!(0, exports.validateFieldWithResult)('string', value === null || value === void 0 ? void 0 : value.auth).isValid) {
|
|
733
|
+
return invalidResult('Webhook name, method and auth are required');
|
|
734
|
+
}
|
|
735
|
+
if (value.handler) {
|
|
736
|
+
if (value.handler.type !== 'fsm' && value.handler.type !== 'method') {
|
|
737
|
+
return invalidResult('Webhook handler type is invalid');
|
|
738
|
+
}
|
|
739
|
+
var handlerResult = (0, exports.validateFieldWithResult)('string', value.handler.value);
|
|
740
|
+
if (!handlerResult.isValid) {
|
|
741
|
+
return withContext(handlerResult, 'Webhook handler value is invalid');
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
return validResult();
|
|
745
|
+
}
|
|
746
|
+
case 'service-webhooks': {
|
|
747
|
+
if (!(0, isArray_1.default)(value) || !(0, size_1.default)(value)) {
|
|
748
|
+
return invalidResult('At least one webhook is required');
|
|
310
749
|
}
|
|
311
|
-
|
|
312
|
-
|
|
750
|
+
for (var i = 0; i < value.length; i++) {
|
|
751
|
+
var webhookResult = (0, exports.validateFieldWithResult)('service-webhook', value[i]);
|
|
752
|
+
if (!webhookResult.isValid) {
|
|
753
|
+
return withContext(webhookResult, "Service webhook ".concat(i, " is invalid"));
|
|
754
|
+
}
|
|
313
755
|
}
|
|
314
|
-
|
|
315
|
-
|
|
756
|
+
return validResult();
|
|
757
|
+
}
|
|
758
|
+
case 'auto':
|
|
759
|
+
case 'any': {
|
|
760
|
+
// Only a STRING has YAML in it. An `auto` field's value is usually
|
|
761
|
+
// already the structure it describes -- a hash the form's hash editor
|
|
762
|
+
// wrote, a list from a list editor -- and `jsyaml.load()` stringifies
|
|
763
|
+
// whatever it is handed first: an object becomes `"[object Object]"`,
|
|
764
|
+
// which YAML then reads as the flow sequence `["object Object"]`. So the
|
|
765
|
+
// auto-detected type came back `list`, the value was validated as a list,
|
|
766
|
+
// and every hash stored in an `auto` field was reported *"Value must be a
|
|
767
|
+
// list"* -- an invalid marker on a value that is fine. A list fared no
|
|
768
|
+
// better: `[1, 2]` stringified to `"1,2"` and detected as a string.
|
|
769
|
+
//
|
|
770
|
+
// Every other branch that accepts either shape already parses through
|
|
771
|
+
// `maybeParseYaml`, which passes a non-string straight through; this one
|
|
772
|
+
// reached for `jsyaml` directly. It cannot use `maybeParseYaml` as-is
|
|
773
|
+
// because that reports a YAML error as an absent value, and "not valid
|
|
774
|
+
// YAML" and "empty" are different answers here.
|
|
775
|
+
var parsedData = value;
|
|
776
|
+
if ((0, lodash_1.isString)(value)) {
|
|
777
|
+
try {
|
|
778
|
+
parsedData = js_yaml_1.default.load(value);
|
|
779
|
+
}
|
|
780
|
+
catch (e) {
|
|
781
|
+
return invalidResult('Value is not valid YAML');
|
|
782
|
+
}
|
|
316
783
|
}
|
|
317
784
|
if (parsedData) {
|
|
318
785
|
return withContext((0, exports.validateFieldWithResult)((0, exports.getTypeFromValue)(parsedData), value), 'Auto-detected type is invalid');
|
|
319
786
|
}
|
|
320
787
|
return invalidResult('Value is empty');
|
|
321
788
|
}
|
|
322
|
-
case '
|
|
789
|
+
case 'processor': {
|
|
790
|
+
if (!value || !value['processor-input-type'] || !value['processor-output-type']) {
|
|
791
|
+
return invalidResult('Processor input and output types are required');
|
|
792
|
+
}
|
|
793
|
+
// Validate the input and output types
|
|
794
|
+
if (value === null || value === void 0 ? void 0 : value['processor-input-type']) {
|
|
795
|
+
var inputResult = (0, exports.validateFieldWithResult)('type-selector', value === null || value === void 0 ? void 0 : value['processor-input-type']);
|
|
796
|
+
if (!inputResult.isValid) {
|
|
797
|
+
return withContext(inputResult, 'Processor input type is invalid');
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
if (value === null || value === void 0 ? void 0 : value['processor-output-type']) {
|
|
801
|
+
var outputResult = (0, exports.validateFieldWithResult)('type-selector', value === null || value === void 0 ? void 0 : value['processor-output-type']);
|
|
802
|
+
if (!outputResult.isValid) {
|
|
803
|
+
return withContext(outputResult, 'Processor output type is invalid');
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
return validResult();
|
|
807
|
+
}
|
|
808
|
+
case 'processor-mappings': {
|
|
809
|
+
// processor-mappings is an array of field mappings
|
|
810
|
+
// Each mapping must have an outputPath (the target field being mapped)
|
|
811
|
+
// and either an inputPath (source field) or options configured
|
|
812
|
+
if (!(0, isArray_1.default)(value)) {
|
|
813
|
+
return canBeNull ? validResult() : invalidResult('Processor mappings must be a list');
|
|
814
|
+
}
|
|
815
|
+
for (var i = 0; i < value.length; i++) {
|
|
816
|
+
var mapping = value[i];
|
|
817
|
+
if (!mapping || !(0, isPlainObject_1.default)(mapping)) {
|
|
818
|
+
return invalidResult("Mapping at index ".concat(i, " is invalid"));
|
|
819
|
+
}
|
|
820
|
+
// outputPath is always required - it identifies which output field is being mapped
|
|
821
|
+
var outputPathResult = (0, exports.validateFieldWithResult)('string', mapping.outputPath);
|
|
822
|
+
if (!outputPathResult.isValid) {
|
|
823
|
+
return withContext(outputPathResult, "Mapping ".concat(i, " output path is invalid"));
|
|
824
|
+
}
|
|
825
|
+
// A mapping must have either an inputPath or options (or both)
|
|
826
|
+
var hasInputPath = mapping.inputPath && mapping.inputPath !== '';
|
|
827
|
+
var hasOptions = mapping.options && (0, size_1.default)(mapping.options) > 0;
|
|
828
|
+
if (!hasInputPath && !hasOptions) {
|
|
829
|
+
return invalidResult("Mapping for \"".concat(mapping.outputPath, "\" must have an input path or options configured"));
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
return validResult();
|
|
833
|
+
}
|
|
834
|
+
case 'tool-catalog': {
|
|
835
|
+
// tool-catalog is a flat string[] of selectors; each selector is one of:
|
|
836
|
+
// "*" — all tools from every source
|
|
837
|
+
// "system:*" — all Qorus system tools
|
|
838
|
+
// "system:<tool>" — a specific system tool
|
|
839
|
+
// "<connection>" — all tools from a connection
|
|
840
|
+
// "<connection>/<tool>" — a specific tool from a connection
|
|
841
|
+
if (!(0, isArray_1.default)(value)) {
|
|
842
|
+
return canBeNull ? validResult() : invalidResult('Tool catalog must be a list');
|
|
843
|
+
}
|
|
844
|
+
for (var i = 0; i < value.length; i++) {
|
|
845
|
+
var selector = value[i];
|
|
846
|
+
if (typeof selector !== 'string' || selector.length === 0) {
|
|
847
|
+
return invalidResult("Tool selector at index ".concat(i, " must be a non-empty string"));
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
return validResult();
|
|
851
|
+
}
|
|
852
|
+
case 'fsm-list': {
|
|
853
|
+
if (!(0, isArray_1.default)(value)) {
|
|
854
|
+
return invalidResult('FSM list must be an array');
|
|
855
|
+
}
|
|
856
|
+
for (var i = 0; i < value.length; i++) {
|
|
857
|
+
var itemResult = (0, exports.validateFieldWithResult)('string', (_f = value[i]) === null || _f === void 0 ? void 0 : _f.name);
|
|
858
|
+
if (!itemResult.isValid) {
|
|
859
|
+
return withContext(itemResult, "FSM entry ".concat(i, " name is invalid"));
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
return validResult();
|
|
863
|
+
}
|
|
864
|
+
case 'api-manager': {
|
|
865
|
+
if (!value) {
|
|
866
|
+
return invalidResult('API manager value is missing');
|
|
867
|
+
}
|
|
868
|
+
var factoryResult = (0, exports.validateFieldWithResult)('string', value.factory);
|
|
869
|
+
if (!factoryResult.isValid) {
|
|
870
|
+
return withContext(factoryResult, 'API manager factory is invalid');
|
|
871
|
+
}
|
|
872
|
+
var endpointsResult = (0, exports.validateFieldWithResult)('api-endpoints', value.endpoints);
|
|
873
|
+
if (!endpointsResult.isValid) {
|
|
874
|
+
return withContext(endpointsResult, 'API manager endpoints are invalid');
|
|
875
|
+
}
|
|
876
|
+
return validResult();
|
|
877
|
+
}
|
|
878
|
+
case 'api-endpoints': {
|
|
879
|
+
if (!(0, isArray_1.default)(value) || !(0, size_1.default)(value)) {
|
|
880
|
+
return invalidResult('At least one API endpoint is required');
|
|
881
|
+
}
|
|
882
|
+
for (var i = 0; i < value.length; i++) {
|
|
883
|
+
var endpointResult = (0, exports.validateFieldWithResult)('string', (_g = value[i]) === null || _g === void 0 ? void 0 : _g.value);
|
|
884
|
+
if (!endpointResult.isValid) {
|
|
885
|
+
return withContext(endpointResult, "Endpoint ".concat(i, " value is invalid"));
|
|
886
|
+
}
|
|
887
|
+
var authorizationResult = (0, exports.validateFieldWithResult)('api-endpoint-authorization', (_h = value[i]) === null || _h === void 0 ? void 0 : _h.authorization, undefined, true);
|
|
888
|
+
if (!authorizationResult.isValid) {
|
|
889
|
+
return withContext(authorizationResult, "Endpoint ".concat(i, " authorization is invalid"));
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
return validResult();
|
|
893
|
+
}
|
|
894
|
+
case 'api-endpoint-authorization': {
|
|
895
|
+
if (!value) {
|
|
896
|
+
return canBeNull ? validResult() : invalidResult('Authorization override is missing');
|
|
897
|
+
}
|
|
898
|
+
if (typeof value !== 'object' || (0, isArray_1.default)(value)) {
|
|
899
|
+
return invalidResult('Authorization override must be an object');
|
|
900
|
+
}
|
|
901
|
+
if (value.mode !== undefined && !['merge', 'replace'].includes(value.mode)) {
|
|
902
|
+
return invalidResult('Authorization mode must be merge or replace');
|
|
903
|
+
}
|
|
904
|
+
if (value.allow_anonymous !== undefined && typeof value.allow_anonymous !== 'boolean') {
|
|
905
|
+
return invalidResult('Authorization allow_anonymous must be a boolean');
|
|
906
|
+
}
|
|
907
|
+
if (value.roles !== undefined) {
|
|
908
|
+
if (!(0, isArray_1.default)(value.roles)) {
|
|
909
|
+
return invalidResult('Authorization roles must be a list');
|
|
910
|
+
}
|
|
911
|
+
for (var i = 0; i < value.roles.length; i++) {
|
|
912
|
+
var roleResult = (0, exports.validateFieldWithResult)('string', value.roles[i]);
|
|
913
|
+
if (!roleResult.isValid) {
|
|
914
|
+
return withContext(roleResult, "Authorization role ".concat(i, " is invalid"));
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
return validResult();
|
|
919
|
+
}
|
|
920
|
+
case 'options':
|
|
921
|
+
case 'pipeline-options':
|
|
922
|
+
case 'mapper-options':
|
|
923
|
+
case 'system-options': {
|
|
323
924
|
var getIsValid = function (options, optionSchema) {
|
|
324
|
-
var _a, _b, _c, _d
|
|
925
|
+
var _a, _b, _c, _d;
|
|
325
926
|
if (optionSchema === void 0) { optionSchema = {}; }
|
|
326
927
|
if (!options || (0, size_1.default)(options) === 0) {
|
|
327
928
|
if (!canBeNull) {
|
|
@@ -329,35 +930,31 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
329
930
|
}
|
|
330
931
|
return validResult();
|
|
331
932
|
}
|
|
332
|
-
if
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
if (!((_b = options === null || options === void 0 ? void 0 : options[option]) === null || _b === void 0 ? void 0 : _b.value) &&
|
|
340
|
-
optionData.required_groups &&
|
|
341
|
-
!(0, exports.validateOptionWithRequiredGroups)(options, optionSchema, optionData.required_groups)) {
|
|
342
|
-
return invalidResult("Option ".concat(option, " requires a value"));
|
|
343
|
-
}
|
|
344
|
-
}
|
|
933
|
+
// Check if all required options are resolved by the current values
|
|
934
|
+
var unresolvedRequiredOption = (0, exports.getUnresolvedRequiredOptions)(optionSchema, options)[0];
|
|
935
|
+
if (unresolvedRequiredOption) {
|
|
936
|
+
return unresolvedRequiredOption.validation
|
|
937
|
+
? withContext(unresolvedRequiredOption.validation, "Option ".concat(unresolvedRequiredOption.name, " is invalid"))
|
|
938
|
+
: invalidResult((0, exports.getUnresolvedRequiredOptionReason)(unresolvedRequiredOption, optionSchema));
|
|
345
939
|
}
|
|
346
|
-
for (var
|
|
347
|
-
var option =
|
|
348
|
-
|
|
940
|
+
for (var _i = 0, _e = Object.keys(options); _i < _e.length; _i++) {
|
|
941
|
+
var option = _e[_i];
|
|
942
|
+
var optionData = options[option];
|
|
943
|
+
var optionType = ((typeof optionData === 'object' ? optionData === null || optionData === void 0 ? void 0 : optionData.type : undefined) ||
|
|
944
|
+
((_a = optionSchema === null || optionSchema === void 0 ? void 0 : optionSchema[option]) === null || _a === void 0 ? void 0 : _a.ui_type) ||
|
|
945
|
+
((_b = optionSchema === null || optionSchema === void 0 ? void 0 : optionSchema[option]) === null || _b === void 0 ? void 0 : _b.type));
|
|
946
|
+
var optionValue = optionData && typeof optionData === 'object' ? optionData.value : optionData;
|
|
947
|
+
if (!((_c = optionSchema === null || optionSchema === void 0 ? void 0 : optionSchema[option]) === null || _c === void 0 ? void 0 : _c.required) &&
|
|
948
|
+
!isValueDefined(optionType, optionValue)) {
|
|
949
|
+
continue;
|
|
950
|
+
}
|
|
951
|
+
if (((_d = optionSchema === null || optionSchema === void 0 ? void 0 : optionSchema[option]) === null || _d === void 0 ? void 0 : _d.depends_on) &&
|
|
349
952
|
!(0, exports.hasAllDependenciesFullfilled)(optionSchema[option].depends_on, options, optionSchema)) {
|
|
350
953
|
return invalidResult("Option ".concat(option, " dependencies are not fulfilled"));
|
|
351
954
|
}
|
|
352
|
-
if (((_d = optionSchema === null || optionSchema === void 0 ? void 0 : optionSchema[option]) === null || _d === void 0 ? void 0 : _d.preselected) &&
|
|
353
|
-
!((_e = optionSchema === null || optionSchema === void 0 ? void 0 : optionSchema[option]) === null || _e === void 0 ? void 0 : _e.required) &&
|
|
354
|
-
!((_f = options[option]) === null || _f === void 0 ? void 0 : _f.value)) {
|
|
355
|
-
continue;
|
|
356
|
-
}
|
|
357
|
-
var optionData = options[option];
|
|
358
955
|
var optionResult = typeof optionData !== 'object'
|
|
359
956
|
? (0, exports.validateFieldWithResult)((0, exports.getTypeFromValue)(optionData), optionData)
|
|
360
|
-
: (0, exports.validateFieldWithResult)(optionData.type, optionData.value, __assign(__assign({},
|
|
957
|
+
: (0, exports.validateFieldWithResult)(optionData.type, optionData.value, __assign(__assign({}, optionSchema === null || optionSchema === void 0 ? void 0 : optionSchema[option]), { optionSchema: optionSchema, options: options, isFunction: optionData.is_expression }));
|
|
361
958
|
if (!optionResult.isValid) {
|
|
362
959
|
return withContext(optionResult, "Option ".concat(option, " is invalid"));
|
|
363
960
|
}
|
|
@@ -375,12 +972,45 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
375
972
|
}
|
|
376
973
|
return getIsValid(value, field === null || field === void 0 ? void 0 : field.optionSchema);
|
|
377
974
|
}
|
|
975
|
+
case 'system-options-with-operators': {
|
|
976
|
+
var isValid = function (val) {
|
|
977
|
+
if (!val || (0, size_1.default)(val) === 0) {
|
|
978
|
+
if (canBeNull) {
|
|
979
|
+
return validResult();
|
|
980
|
+
}
|
|
981
|
+
return invalidResult('Options with operators are required');
|
|
982
|
+
}
|
|
983
|
+
for (var _i = 0, _a = Object.keys(val); _i < _a.length; _i++) {
|
|
984
|
+
var option = _a[_i];
|
|
985
|
+
var optionData = val[option];
|
|
986
|
+
var optionResult = typeof optionData !== 'object'
|
|
987
|
+
? (0, exports.validateFieldWithResult)((0, exports.getTypeFromValue)(optionData), optionData)
|
|
988
|
+
: (0, exports.validateFieldWithResult)(optionData.type, optionData.value);
|
|
989
|
+
if (!optionResult.isValid) {
|
|
990
|
+
return withContext(optionResult, "Option ".concat(option, " is invalid"));
|
|
991
|
+
}
|
|
992
|
+
if (!optionData.op ||
|
|
993
|
+
!(0, common_1.fixOperatorValue)(optionData.op).every(function (operator) { return (0, exports.validateFieldWithResult)('string', operator).isValid; })) {
|
|
994
|
+
return invalidResult("Operators for option ".concat(option, " are invalid"));
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
return validResult();
|
|
998
|
+
};
|
|
999
|
+
if ((0, isArray_1.default)(value)) {
|
|
1000
|
+
for (var i = 0; i < value.length; i++) {
|
|
1001
|
+
var optionResult = isValid(value[i]);
|
|
1002
|
+
if (!optionResult.isValid) {
|
|
1003
|
+
return withContext(optionResult, "Option set ".concat(i, " is invalid"));
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
return validResult();
|
|
1007
|
+
}
|
|
1008
|
+
return isValid(value);
|
|
1009
|
+
}
|
|
378
1010
|
case 'byte-size': {
|
|
379
|
-
// Ported from qorus-ide validations (`sizeUnit` instead of the IDE's
|
|
380
|
-
// `size`, which would shadow the lodash import here).
|
|
381
1011
|
if (typeof value !== 'string')
|
|
382
1012
|
return invalidResult('Byte size must be a string');
|
|
383
|
-
var
|
|
1013
|
+
var _s = (0, common_1.splitByteSize)(value), bytes = _s[0], sizeUnit = _s[1];
|
|
384
1014
|
var bytesResult = (0, exports.validateFieldWithResult)('number', bytes);
|
|
385
1015
|
if (!bytesResult.isValid) {
|
|
386
1016
|
return withContext(bytesResult, 'Byte size numeric part is invalid');
|
|
@@ -400,7 +1030,8 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
400
1030
|
}
|
|
401
1031
|
return validResult();
|
|
402
1032
|
}
|
|
403
|
-
case 'url':
|
|
1033
|
+
case 'url':
|
|
1034
|
+
case 'uri': {
|
|
404
1035
|
var protocolResult = (0, exports.validateFieldWithResult)('string', (0, common_1.getProtocol)(value));
|
|
405
1036
|
if (!protocolResult.isValid) {
|
|
406
1037
|
return withContext(protocolResult, 'URL protocol is invalid');
|
|
@@ -412,8 +1043,7 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
412
1043
|
return validResult();
|
|
413
1044
|
}
|
|
414
1045
|
case 'schema-definition': {
|
|
415
|
-
//
|
|
416
|
-
// minimal NEW_FIELD.md shape check so malformed definitions can't
|
|
1046
|
+
// The minimal NEW_FIELD.md shape check, so malformed definitions can't
|
|
417
1047
|
// silently save through FormEngine.
|
|
418
1048
|
if (!(0, isPlainObject_1.default)(value)) {
|
|
419
1049
|
return invalidResult('Schema definition must be an object');
|
|
@@ -424,33 +1054,52 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
424
1054
|
return validResult();
|
|
425
1055
|
}
|
|
426
1056
|
case 'expression': {
|
|
427
|
-
// Ported from qorus-ide validations `'expression'` case. The catalogue
|
|
428
|
-
// is supplied via `field.expressions` (the ExpressionBuilder passes it),
|
|
429
|
-
// not a global store as in the IDE.
|
|
430
1057
|
var castedValue_1 = value;
|
|
431
|
-
var expressions = (
|
|
432
|
-
// Expressions
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
1058
|
+
var expressions = readExpressionCatalogue(field);
|
|
1059
|
+
// Expressions validation is complicated and needs to follow the following rules
|
|
1060
|
+
// 1. If the expression is empty, it is invalid
|
|
1061
|
+
// 2. If the expression has a type, it means its a normal argument (sub expressions don't have type)
|
|
1062
|
+
// 3. If the expression has no type and `exp` is present, it is a sub expression and must be validated as such
|
|
1063
|
+
// 4. If there are no `args` we need to check if the expression actually has any required arguments or what is the `min_args` property
|
|
1064
|
+
// 1. If the expression is empty
|
|
1065
|
+
//
|
|
1066
|
+
// Checked BEFORE the catalogue guard below, and deliberately: an
|
|
1067
|
+
// expression with no value, or with no operation chosen, is incomplete on
|
|
1068
|
+
// its own terms. Nothing in the catalogue can make it valid, so making
|
|
1069
|
+
// these two answers wait for a network fetch meant the same option
|
|
1070
|
+
// reported valid or invalid depending on whether that fetch had landed —
|
|
1071
|
+
// the field's own "show invalid only" filter listed a different set of
|
|
1072
|
+
// rows on a fast machine than on a slow one.
|
|
436
1073
|
if (!castedValue_1) {
|
|
437
1074
|
return invalidResult('Expression value is empty');
|
|
438
1075
|
}
|
|
439
|
-
if (!((
|
|
1076
|
+
if (!((_j = castedValue_1.value) === null || _j === void 0 ? void 0 : _j.exp)) {
|
|
440
1077
|
return invalidResult('Expression operation is required');
|
|
441
1078
|
}
|
|
1079
|
+
// Everything past this point needs the expression's definition, which
|
|
1080
|
+
// only the catalogue can supply. Until it loads there is nothing to check
|
|
1081
|
+
// against, so an expression that names an operation is left alone rather
|
|
1082
|
+
// than reported against a catalogue we do not have.
|
|
1083
|
+
if (!(0, size_1.default)(expressions)) {
|
|
1084
|
+
return validResult();
|
|
1085
|
+
}
|
|
1086
|
+
// Get the expression definition from the catalogue
|
|
442
1087
|
var expressionDefinition = expressions.find(function (expr) { var _a; return expr.name === ((_a = castedValue_1.value) === null || _a === void 0 ? void 0 : _a.exp); });
|
|
443
1088
|
if (!expressionDefinition) {
|
|
444
|
-
return invalidResult("Expression definition ".concat(String((
|
|
1089
|
+
return invalidResult("Expression definition ".concat(String((_k = castedValue_1.value) === null || _k === void 0 ? void 0 : _k.exp), " not found"));
|
|
445
1090
|
}
|
|
446
|
-
|
|
447
|
-
|
|
1091
|
+
// If the expression has no required args, we can consider it valid
|
|
1092
|
+
var hasRequiredArgs = (_l = expressionDefinition.args) === null || _l === void 0 ? void 0 : _l.some(function (arg) { return arg.required; });
|
|
1093
|
+
if (!hasRequiredArgs && (0, size_1.default)(((_m = castedValue_1.value) === null || _m === void 0 ? void 0 : _m.args) || []) === 0) {
|
|
448
1094
|
return validResult();
|
|
449
1095
|
}
|
|
450
|
-
|
|
1096
|
+
// If there are no args provided but the expression requires some (normal expressions require at least 1 arg
|
|
1097
|
+
// because we checked for required args earlier), or min_args is set
|
|
1098
|
+
if ((0, size_1.default)(((_o = castedValue_1.value) === null || _o === void 0 ? void 0 : _o.args) || []) < (expressionDefinition.min_args || 1)) {
|
|
451
1099
|
return invalidResult('Not enough arguments provided');
|
|
452
1100
|
}
|
|
453
|
-
|
|
1101
|
+
// Now we need to validate each argument, either as a normal value or as a sub-expression
|
|
1102
|
+
var args = (_q = (_p = castedValue_1.value) === null || _p === void 0 ? void 0 : _p.args) !== null && _q !== void 0 ? _q : [];
|
|
454
1103
|
for (var index = 0; index < args.length; index++) {
|
|
455
1104
|
var argValue = args[index];
|
|
456
1105
|
var argDefinition = expressionDefinition.varargs
|
|
@@ -488,7 +1137,6 @@ var _validateField = function (type, value, field, canBeNull) {
|
|
|
488
1137
|
}
|
|
489
1138
|
};
|
|
490
1139
|
exports._validateField = _validateField;
|
|
491
|
-
// Memoized version
|
|
492
1140
|
/**
|
|
493
1141
|
* Read one arg out of a hash, whichever of the two legitimate shapes it is in.
|
|
494
1142
|
*
|
|
@@ -509,6 +1157,7 @@ var readArgValue = function (arg) {
|
|
|
509
1157
|
return (0, isPlainObject_1.default)(arg) && 'value' in arg ? arg.value : arg;
|
|
510
1158
|
};
|
|
511
1159
|
exports.readArgValue = readArgValue;
|
|
1160
|
+
// Memoized version
|
|
512
1161
|
exports.validateFieldWithResult = (0, lodash_1.memoize)(exports._validateField, function (type, value, field, canBeNull) {
|
|
513
1162
|
return "".concat(type, "-").concat(JSON.stringify(value), "-").concat(JSON.stringify(field), "-").concat(canBeNull);
|
|
514
1163
|
});
|
|
@@ -566,6 +1215,9 @@ var getValueOrDefaultValue = function (value, defaultValue, canBeNull) {
|
|
|
566
1215
|
return undefined;
|
|
567
1216
|
};
|
|
568
1217
|
exports.getValueOrDefaultValue = getValueOrDefaultValue;
|
|
1218
|
+
/** Deliberately un-annotated: the inferred literal union is what callers assign
|
|
1219
|
+
* into their own narrower type aliases, and widening it to `string` breaks
|
|
1220
|
+
* them. */
|
|
569
1221
|
var getTypeFromValue = function (value) {
|
|
570
1222
|
switch (true) {
|
|
571
1223
|
case (0, lodash_1.isNull)(value):
|
|
@@ -595,36 +1247,151 @@ var validateOptionWithRequiredGroups = function (options, schema, groups) {
|
|
|
595
1247
|
var optionsInGroups = (0, options_1.getOptionsFromRequiredGroups)(schema, groups);
|
|
596
1248
|
return optionsInGroups.some(function (option) {
|
|
597
1249
|
var _a, _b, _c;
|
|
598
|
-
return isValueDefined(((_a = schema[option]) === null || _a === void 0 ? void 0 : _a.ui_type) ||
|
|
1250
|
+
return isValueDefined(((_a = schema[option]) === null || _a === void 0 ? void 0 : _a.ui_type) ||
|
|
1251
|
+
((_b = schema[option]) === null || _b === void 0 ? void 0 : _b.type), (_c = options === null || options === void 0 ? void 0 : options[option]) === null || _c === void 0 ? void 0 : _c.value);
|
|
599
1252
|
});
|
|
600
1253
|
}
|
|
601
1254
|
return true;
|
|
602
1255
|
};
|
|
603
1256
|
exports.validateOptionWithRequiredGroups = validateOptionWithRequiredGroups;
|
|
1257
|
+
var getUnresolvedRequiredOptionReason = function (_a, optionSchema) {
|
|
1258
|
+
var _b;
|
|
1259
|
+
var name = _a.name, reason = _a.reason;
|
|
1260
|
+
switch (reason) {
|
|
1261
|
+
case 'dependency':
|
|
1262
|
+
return "Option ".concat(name, " dependencies are not fulfilled");
|
|
1263
|
+
case 'invalid':
|
|
1264
|
+
return "Option ".concat(name, " is invalid");
|
|
1265
|
+
default:
|
|
1266
|
+
return ((_b = optionSchema === null || optionSchema === void 0 ? void 0 : optionSchema[name]) === null || _b === void 0 ? void 0 : _b.required)
|
|
1267
|
+
? "Option ".concat(name, " is required")
|
|
1268
|
+
: "Option ".concat(name, " requires a value");
|
|
1269
|
+
}
|
|
1270
|
+
};
|
|
1271
|
+
exports.getUnresolvedRequiredOptionReason = getUnresolvedRequiredOptionReason;
|
|
1272
|
+
/**
|
|
1273
|
+
* List every required option that the given values do not resolve.
|
|
1274
|
+
*
|
|
1275
|
+
* `required` on an option schema means "the effective configuration must carry
|
|
1276
|
+
* this option" — NOT "the user has to type it in". An option whose schema
|
|
1277
|
+
* default or preselected value already resolves it needs no user input at all,
|
|
1278
|
+
* which is why callers pass values that have been through `fixOptions()`
|
|
1279
|
+
* (defaults, preselected values and rich-text default envelopes applied)
|
|
1280
|
+
* rather than the raw values the server returned.
|
|
1281
|
+
*
|
|
1282
|
+
* This is the single owner of the "which required options still need input"
|
|
1283
|
+
* question: `validateField('options', …)` uses it for form validity, and
|
|
1284
|
+
* qorus-ide's `ConnectionManagementModal` uses it to decide whether a
|
|
1285
|
+
* connection can be created — and its OAuth2 flow started — without showing a
|
|
1286
|
+
* form at all.
|
|
1287
|
+
*/
|
|
1288
|
+
var getUnresolvedRequiredOptions = function (optionSchema, options) {
|
|
1289
|
+
if (optionSchema === void 0) { optionSchema = {}; }
|
|
1290
|
+
if (options === void 0) { options = {}; }
|
|
1291
|
+
var unresolved = [];
|
|
1292
|
+
for (var _i = 0, _a = Object.entries(optionSchema !== null && optionSchema !== void 0 ? optionSchema : {}); _i < _a.length; _i++) {
|
|
1293
|
+
var _b = _a[_i], name_1 = _b[0], schemaEntry = _b[1];
|
|
1294
|
+
var optionData = schemaEntry;
|
|
1295
|
+
if (!(optionData === null || optionData === void 0 ? void 0 : optionData.required) && !(0, size_1.default)(optionData === null || optionData === void 0 ? void 0 : optionData.required_groups)) {
|
|
1296
|
+
continue;
|
|
1297
|
+
}
|
|
1298
|
+
var optionField = options === null || options === void 0 ? void 0 : options[name_1];
|
|
1299
|
+
var optionValue = optionField && typeof optionField === 'object' ? optionField.value : optionField;
|
|
1300
|
+
var optionType = ((typeof optionField === 'object' ? optionField === null || optionField === void 0 ? void 0 : optionField.type : undefined) ||
|
|
1301
|
+
optionData.ui_type ||
|
|
1302
|
+
optionData.type);
|
|
1303
|
+
// A dependent option cannot be considered resolved while its dependencies
|
|
1304
|
+
// are not: the schema it will be validated against — and with it any
|
|
1305
|
+
// default the server would send — is not final yet.
|
|
1306
|
+
if (optionData.depends_on &&
|
|
1307
|
+
!(0, exports.hasAllDependenciesFullfilled)(optionData.depends_on, options, optionSchema)) {
|
|
1308
|
+
unresolved.push({ name: name_1, reason: 'dependency' });
|
|
1309
|
+
continue;
|
|
1310
|
+
}
|
|
1311
|
+
if (!isValueDefined(optionType, optionValue)) {
|
|
1312
|
+
// An option required only through a group is resolved by any sibling in
|
|
1313
|
+
// that group carrying a value.
|
|
1314
|
+
if (optionData.required ||
|
|
1315
|
+
!(0, exports.validateOptionWithRequiredGroups)(options, optionSchema, optionData.required_groups)) {
|
|
1316
|
+
unresolved.push({ name: name_1, reason: 'missing' });
|
|
1317
|
+
}
|
|
1318
|
+
continue;
|
|
1319
|
+
}
|
|
1320
|
+
var validation = typeof optionField !== 'object'
|
|
1321
|
+
? (0, exports.validateFieldWithResult)((0, exports.getTypeFromValue)(optionField), optionField)
|
|
1322
|
+
: (0, exports.validateFieldWithResult)(optionField.type, optionField.value, __assign(__assign({}, optionData), { optionSchema: optionSchema, options: options, isFunction: optionField.is_expression }));
|
|
1323
|
+
if (!validation.isValid) {
|
|
1324
|
+
unresolved.push({ name: name_1, reason: 'invalid', validation: validation });
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
return unresolved;
|
|
1328
|
+
};
|
|
1329
|
+
exports.getUnresolvedRequiredOptions = getUnresolvedRequiredOptions;
|
|
1330
|
+
/**
|
|
1331
|
+
* Split a dependency entry into the sibling it names and how its value is compared.
|
|
1332
|
+
*
|
|
1333
|
+
* Three forms: `name` (the sibling must simply have a value), `name=value` (it must
|
|
1334
|
+
* have exactly that value) and `name!=value` (it must have a value, and not that
|
|
1335
|
+
* one). The negative form is what lets a field say it applies to every variant of a
|
|
1336
|
+
* record but one — spelling that as an `any-of` list of every other variant is both
|
|
1337
|
+
* unreadable in the "Depends on" lock and silently wrong the moment a variant is
|
|
1338
|
+
* added.
|
|
1339
|
+
*
|
|
1340
|
+
* `!=` deliberately requires the sibling to be answered: "not X" is a statement about
|
|
1341
|
+
* an answer, so an unanswered sibling does not satisfy it and the field stays locked.
|
|
1342
|
+
*/
|
|
1343
|
+
var parseDependency = function (dependency) {
|
|
1344
|
+
var neqIdx = dependency.indexOf('!=');
|
|
1345
|
+
if (neqIdx !== -1) {
|
|
1346
|
+
return {
|
|
1347
|
+
name: dependency.substring(0, neqIdx),
|
|
1348
|
+
op: '!=',
|
|
1349
|
+
value: dependency.substring(neqIdx + 2),
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
var eqIdx = dependency.indexOf('=');
|
|
1353
|
+
if (eqIdx !== -1) {
|
|
1354
|
+
return {
|
|
1355
|
+
name: dependency.substring(0, eqIdx),
|
|
1356
|
+
op: '=',
|
|
1357
|
+
value: dependency.substring(eqIdx + 1),
|
|
1358
|
+
};
|
|
1359
|
+
}
|
|
1360
|
+
return { name: dependency };
|
|
1361
|
+
};
|
|
1362
|
+
exports.parseDependency = parseDependency;
|
|
1363
|
+
/** Whether one dependency entry holds against the current form values. */
|
|
1364
|
+
var isDependencyFulfilled = function (dependency, options, optionsSchema) {
|
|
1365
|
+
var _a;
|
|
1366
|
+
var _b = (0, exports.parseDependency)(dependency), name = _b.name, op = _b.op, value = _b.value;
|
|
1367
|
+
if (op) {
|
|
1368
|
+
var optValue = (_a = options === null || options === void 0 ? void 0 : options[name]) === null || _a === void 0 ? void 0 : _a.value;
|
|
1369
|
+
if (optValue == null) {
|
|
1370
|
+
return false;
|
|
1371
|
+
}
|
|
1372
|
+
return op === '=' ? String(optValue) === value : String(optValue) !== value;
|
|
1373
|
+
}
|
|
1374
|
+
return (options === null || options === void 0 ? void 0 : options[name])
|
|
1375
|
+
? (0, exports.validateField)(options[name].type, options[name].value, __assign(__assign({}, optionsSchema === null || optionsSchema === void 0 ? void 0 : optionsSchema[name]), { options: options, optionSchema: optionsSchema }))
|
|
1376
|
+
: true;
|
|
1377
|
+
};
|
|
604
1378
|
var hasAllDependenciesFullfilled = function (dependencies, options, optionsSchema) {
|
|
605
1379
|
if ((0, size_1.default)(dependencies) === 0) {
|
|
606
1380
|
return true;
|
|
607
1381
|
}
|
|
608
1382
|
return dependencies.every(function (dependency) {
|
|
609
|
-
|
|
1383
|
+
// A nested list is an ANY. It used to look each entry up as a whole form-field
|
|
1384
|
+
// name, so a `name=value` entry inside one found no field and returned `true`
|
|
1385
|
+
// unconditionally — the any-of group was satisfied by anything at all, while
|
|
1386
|
+
// CompactRow's lock rendered those same entries as real comparisons. Both halves
|
|
1387
|
+
// now go through one parser, so the grammar cannot mean two things.
|
|
610
1388
|
if ((0, isArray_1.default)(dependency)) {
|
|
611
1389
|
return dependency.some(function (dep) {
|
|
612
|
-
return (
|
|
613
|
-
? (0, exports.validateField)(options[dep].type, options[dep].value, __assign(__assign({}, optionsSchema === null || optionsSchema === void 0 ? void 0 : optionsSchema[dep]), { options: options, optionSchema: optionsSchema }))
|
|
614
|
-
: true;
|
|
1390
|
+
return isDependencyFulfilled(dep, options, optionsSchema);
|
|
615
1391
|
});
|
|
616
1392
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
if (eqIdx !== -1) {
|
|
620
|
-
var depName = dependency.substring(0, eqIdx);
|
|
621
|
-
var depValue = dependency.substring(eqIdx + 1);
|
|
622
|
-
var optValue = (_a = options === null || options === void 0 ? void 0 : options[depName]) === null || _a === void 0 ? void 0 : _a.value;
|
|
623
|
-
return optValue != null && String(optValue) === depValue;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
return (options === null || options === void 0 ? void 0 : options[dependency])
|
|
627
|
-
? (0, exports.validateField)(options[dependency].type, options[dependency].value, __assign(__assign({}, optionsSchema === null || optionsSchema === void 0 ? void 0 : optionsSchema[dependency]), { options: options, optionSchema: optionsSchema }))
|
|
1393
|
+
return (0, lodash_1.isString)(dependency)
|
|
1394
|
+
? isDependencyFulfilled(dependency, options, optionsSchema)
|
|
628
1395
|
: true;
|
|
629
1396
|
});
|
|
630
1397
|
};
|