@bluprynt/forms-core 4.0.1 → 4.1.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/README.md +12 -1
- package/dist/form-definition.schema.json +388 -2
- package/dist/index.cjs +1395 -41
- package/dist/index.d.cts +637 -47
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +637 -47
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1391 -42
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -110,6 +110,18 @@ const resolveRelativeDate = (relative, now) => {
|
|
|
110
110
|
*
|
|
111
111
|
* **Date handling**: condition values that are relative date expressions
|
|
112
112
|
* (e.g. `"+7d"`) are resolved against `ctx.now` before comparison.
|
|
113
|
+
*
|
|
114
|
+
* **Multiselect handling**: when `ctx.fieldTypes` reports the referenced field
|
|
115
|
+
* as `multiselect`, its array value is compared as a set instead of a scalar:
|
|
116
|
+
* `set` means "at least one option chosen", `eq`/`ne` compare set membership
|
|
117
|
+
* ignoring order and duplicates, `in`/`notin` test whether *any* chosen option
|
|
118
|
+
* appears in the condition's list, and the ordering operators are always
|
|
119
|
+
* `false`. Fields of every other type -- including `array` -- keep the original
|
|
120
|
+
* scalar semantics.
|
|
121
|
+
*
|
|
122
|
+
* **Object-valued fields** (`file`, `sustainability`) go through the scalar path
|
|
123
|
+
* too, so only `set`/`notset` are meaningful: any object present counts as
|
|
124
|
+
* `set`, and `eq`/`ne`/`in`/`notin` compare by reference and so never match.
|
|
113
125
|
*/
|
|
114
126
|
var ConditionEvaluator = class {
|
|
115
127
|
/**
|
|
@@ -128,6 +140,7 @@ var ConditionEvaluator = class {
|
|
|
128
140
|
evalSimple(cond, ctx) {
|
|
129
141
|
if (ctx.visibilityMap && ctx.visibilityMap.get(cond.field) === false) return cond.op === "notset";
|
|
130
142
|
const fieldValue = ctx.values[String(cond.field)];
|
|
143
|
+
if (ctx.fieldTypes?.get(cond.field) === "multiselect") return this.evalMultiselect(cond, fieldValue);
|
|
131
144
|
switch (cond.op) {
|
|
132
145
|
case "set": return fieldValue !== null && fieldValue !== void 0 && fieldValue !== "";
|
|
133
146
|
case "notset": return fieldValue === null || fieldValue === void 0 || fieldValue === "";
|
|
@@ -142,6 +155,32 @@ var ConditionEvaluator = class {
|
|
|
142
155
|
default: return false;
|
|
143
156
|
}
|
|
144
157
|
}
|
|
158
|
+
evalMultiselect(cond, fieldValue) {
|
|
159
|
+
const selected = Array.isArray(fieldValue) ? fieldValue : [];
|
|
160
|
+
const candidates = cond.value;
|
|
161
|
+
switch (cond.op) {
|
|
162
|
+
case "set": return selected.length > 0;
|
|
163
|
+
case "notset": return selected.length === 0;
|
|
164
|
+
case "eq": return this.sameSet(selected, candidates);
|
|
165
|
+
case "ne": return !this.sameSet(selected, candidates);
|
|
166
|
+
case "in": return Array.isArray(candidates) && selected.some((item) => candidates.includes(item));
|
|
167
|
+
case "notin": return Array.isArray(candidates) && !selected.some((item) => candidates.includes(item));
|
|
168
|
+
default: return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Compares the chosen options against a condition value as sets, ignoring
|
|
173
|
+
* order and duplicates. A scalar condition value is read as a one-element
|
|
174
|
+
* set, so `{ op: 'eq', value: 'a' }` means "`a` is the only option chosen".
|
|
175
|
+
*/
|
|
176
|
+
sameSet(selected, expected) {
|
|
177
|
+
const expectedItems = Array.isArray(expected) ? expected : [expected];
|
|
178
|
+
const selectedSet = new Set(selected);
|
|
179
|
+
const expectedSet = new Set(expectedItems);
|
|
180
|
+
if (selectedSet.size !== expectedSet.size) return false;
|
|
181
|
+
for (const item of expectedSet) if (!selectedSet.has(item)) return false;
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
145
184
|
resolveIfDate(value, now) {
|
|
146
185
|
if (isRelativeDate(value)) return resolveRelativeDate(value, now);
|
|
147
186
|
return value;
|
|
@@ -402,6 +441,93 @@ var DependencyGraph = class DependencyGraph {
|
|
|
402
441
|
}
|
|
403
442
|
};
|
|
404
443
|
//#endregion
|
|
444
|
+
//#region src/validators/array-obj-validator.ts
|
|
445
|
+
const isRow = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
446
|
+
/**
|
|
447
|
+
* Validates an `array_obj` field: the row list itself, then every sub-field of
|
|
448
|
+
* every row.
|
|
449
|
+
*
|
|
450
|
+
* Sub-field errors keep the container's `fieldId` -- matching the key the
|
|
451
|
+
* `fieldErrors` map stores them under -- and carry `itemIndex` (the row) plus
|
|
452
|
+
* `itemFieldId` (the sub-field). A row-level `TYPE` error carries `itemIndex`
|
|
453
|
+
* only.
|
|
454
|
+
*/
|
|
455
|
+
var ArrayObjValidator = class {
|
|
456
|
+
validate(ctx) {
|
|
457
|
+
const { fieldId, value, now } = ctx;
|
|
458
|
+
const { items, validateField } = ctx;
|
|
459
|
+
const validation = ctx.validation;
|
|
460
|
+
const errors = [];
|
|
461
|
+
if (value === null || value === void 0) return errors;
|
|
462
|
+
if (!Array.isArray(value)) {
|
|
463
|
+
errors.push({
|
|
464
|
+
fieldId,
|
|
465
|
+
rule: "TYPE",
|
|
466
|
+
message: "Must be an array",
|
|
467
|
+
params: { expectedType: "array" }
|
|
468
|
+
});
|
|
469
|
+
return errors;
|
|
470
|
+
}
|
|
471
|
+
if (validation?.minItems !== void 0 && value.length < validation.minItems) errors.push({
|
|
472
|
+
fieldId,
|
|
473
|
+
rule: "MIN_ITEMS",
|
|
474
|
+
message: `Must have at least ${validation.minItems} items`,
|
|
475
|
+
params: {
|
|
476
|
+
minItems: validation.minItems,
|
|
477
|
+
actual: value.length
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
if (validation?.maxItems !== void 0 && value.length > validation.maxItems) errors.push({
|
|
481
|
+
fieldId,
|
|
482
|
+
rule: "MAX_ITEMS",
|
|
483
|
+
message: `Must have at most ${validation.maxItems} items`,
|
|
484
|
+
params: {
|
|
485
|
+
maxItems: validation.maxItems,
|
|
486
|
+
actual: value.length
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
if (!items) return errors;
|
|
490
|
+
for (let i = 0; i < value.length; i++) {
|
|
491
|
+
const raw = value[i];
|
|
492
|
+
if (raw !== null && raw !== void 0 && !isRow(raw)) {
|
|
493
|
+
errors.push({
|
|
494
|
+
fieldId,
|
|
495
|
+
rule: "TYPE",
|
|
496
|
+
message: "Must be an object",
|
|
497
|
+
params: { expectedType: "object" },
|
|
498
|
+
itemIndex: i
|
|
499
|
+
});
|
|
500
|
+
continue;
|
|
501
|
+
}
|
|
502
|
+
const row = isRow(raw) ? raw : {};
|
|
503
|
+
for (const subField of items) {
|
|
504
|
+
if (subField.type === "static") continue;
|
|
505
|
+
const fakeEntry = {
|
|
506
|
+
id: subField.id,
|
|
507
|
+
type: subField.type,
|
|
508
|
+
condition: void 0,
|
|
509
|
+
validation: subField.validation,
|
|
510
|
+
parentId: fieldId,
|
|
511
|
+
options: subField.options,
|
|
512
|
+
item: void 0,
|
|
513
|
+
items: void 0,
|
|
514
|
+
label: subField.label,
|
|
515
|
+
title: void 0
|
|
516
|
+
};
|
|
517
|
+
const subErrors = validateField(subField.id, row[String(subField.id)], fakeEntry, now);
|
|
518
|
+
errors.push(...subErrors.map((err) => ({
|
|
519
|
+
...err,
|
|
520
|
+
fieldId,
|
|
521
|
+
itemIndex: i,
|
|
522
|
+
itemFieldId: subField.id,
|
|
523
|
+
message: `${subField.label}: ${err.message}`
|
|
524
|
+
})));
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
return errors;
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
//#endregion
|
|
405
531
|
//#region src/validators/array-validator.ts
|
|
406
532
|
var ArrayValidator = class {
|
|
407
533
|
validate(ctx) {
|
|
@@ -437,7 +563,7 @@ var ArrayValidator = class {
|
|
|
437
563
|
actual: value.length
|
|
438
564
|
}
|
|
439
565
|
});
|
|
440
|
-
if (item) for (let i = 0; i < value.length; i++) {
|
|
566
|
+
if (item && item.type !== "static") for (let i = 0; i < value.length; i++) {
|
|
441
567
|
const fakeEntry = {
|
|
442
568
|
id: fieldId,
|
|
443
569
|
type: item.type,
|
|
@@ -446,6 +572,7 @@ var ArrayValidator = class {
|
|
|
446
572
|
parentId: void 0,
|
|
447
573
|
options: item.options,
|
|
448
574
|
item: void 0,
|
|
575
|
+
items: void 0,
|
|
449
576
|
label: item.label,
|
|
450
577
|
title: void 0
|
|
451
578
|
};
|
|
@@ -459,6 +586,32 @@ var ArrayValidator = class {
|
|
|
459
586
|
}
|
|
460
587
|
};
|
|
461
588
|
//#endregion
|
|
589
|
+
//#region src/validators/blockchain-validator.ts
|
|
590
|
+
var BlockchainValidator = class {
|
|
591
|
+
validate(ctx) {
|
|
592
|
+
const { fieldId, value } = ctx;
|
|
593
|
+
const validation = ctx.validation;
|
|
594
|
+
const errors = [];
|
|
595
|
+
const isEmpty = value === null || value === void 0 || value === "";
|
|
596
|
+
if (validation?.required && isEmpty) {
|
|
597
|
+
errors.push({
|
|
598
|
+
fieldId,
|
|
599
|
+
rule: "REQUIRED",
|
|
600
|
+
message: "Value is required"
|
|
601
|
+
});
|
|
602
|
+
return errors;
|
|
603
|
+
}
|
|
604
|
+
if (isEmpty) return errors;
|
|
605
|
+
if (typeof value !== "string") errors.push({
|
|
606
|
+
fieldId,
|
|
607
|
+
rule: "TYPE",
|
|
608
|
+
message: "Must be a blockchain address string",
|
|
609
|
+
params: { expectedType: "blockchain" }
|
|
610
|
+
});
|
|
611
|
+
return errors;
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
//#endregion
|
|
462
615
|
//#region src/validators/boolean-validator.ts
|
|
463
616
|
var BooleanValidator = class {
|
|
464
617
|
validate(ctx) {
|
|
@@ -556,6 +709,51 @@ var FileValidator = class {
|
|
|
556
709
|
}
|
|
557
710
|
};
|
|
558
711
|
//#endregion
|
|
712
|
+
//#region src/validators/multiselect-validator.ts
|
|
713
|
+
/**
|
|
714
|
+
* Validates `multiselect` fields, whose value is an array of the chosen
|
|
715
|
+
* options' `value`s.
|
|
716
|
+
*
|
|
717
|
+
* An absent value and an empty array both count as "nothing selected", so both
|
|
718
|
+
* fail `required`. Option membership is reported as a single field-level
|
|
719
|
+
* `INVALID_OPTION` error rather than one error per offending element: the
|
|
720
|
+
* viewer filters out errors carrying an `itemIndex` on the non-array render
|
|
721
|
+
* path, so indexed errors would never be displayed.
|
|
722
|
+
*/
|
|
723
|
+
var MultiselectValidator = class {
|
|
724
|
+
validate(ctx) {
|
|
725
|
+
const { fieldId, value } = ctx;
|
|
726
|
+
const validation = ctx.validation;
|
|
727
|
+
const options = ctx.options;
|
|
728
|
+
const errors = [];
|
|
729
|
+
const isEmpty = value === null || value === void 0 || Array.isArray(value) && value.length === 0;
|
|
730
|
+
if (validation?.required && isEmpty) {
|
|
731
|
+
errors.push({
|
|
732
|
+
fieldId,
|
|
733
|
+
rule: "REQUIRED",
|
|
734
|
+
message: "Value is required"
|
|
735
|
+
});
|
|
736
|
+
return errors;
|
|
737
|
+
}
|
|
738
|
+
if (isEmpty) return errors;
|
|
739
|
+
if (!Array.isArray(value)) {
|
|
740
|
+
errors.push({
|
|
741
|
+
fieldId,
|
|
742
|
+
rule: "TYPE",
|
|
743
|
+
message: "Must be an array",
|
|
744
|
+
params: { expectedType: "multiselect" }
|
|
745
|
+
});
|
|
746
|
+
return errors;
|
|
747
|
+
}
|
|
748
|
+
if (options && value.some((selected) => !options.some((opt) => opt.value === selected))) errors.push({
|
|
749
|
+
fieldId,
|
|
750
|
+
rule: "INVALID_OPTION",
|
|
751
|
+
message: "Value is not a valid option"
|
|
752
|
+
});
|
|
753
|
+
return errors;
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
//#endregion
|
|
559
757
|
//#region src/validators/number-validator.ts
|
|
560
758
|
var NumberValidator = class {
|
|
561
759
|
validate(ctx) {
|
|
@@ -683,6 +881,53 @@ var StringValidator = class {
|
|
|
683
881
|
}
|
|
684
882
|
};
|
|
685
883
|
//#endregion
|
|
884
|
+
//#region src/validators/sustainability-validator.ts
|
|
885
|
+
const OPTIONAL_TEXT_PROPERTIES = ["ccri", "cmc"];
|
|
886
|
+
var SustainabilityValidator = class {
|
|
887
|
+
validate(ctx) {
|
|
888
|
+
const { fieldId, value } = ctx;
|
|
889
|
+
const validation = ctx.validation;
|
|
890
|
+
const errors = [];
|
|
891
|
+
if (value === null || value === void 0) {
|
|
892
|
+
if (validation?.required) errors.push({
|
|
893
|
+
fieldId,
|
|
894
|
+
rule: "REQUIRED",
|
|
895
|
+
message: "Value is required"
|
|
896
|
+
});
|
|
897
|
+
return errors;
|
|
898
|
+
}
|
|
899
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
900
|
+
errors.push({
|
|
901
|
+
fieldId,
|
|
902
|
+
rule: "TYPE",
|
|
903
|
+
message: "Must be a valid sustainability object",
|
|
904
|
+
params: { expectedType: "sustainability" }
|
|
905
|
+
});
|
|
906
|
+
return errors;
|
|
907
|
+
}
|
|
908
|
+
const record = value;
|
|
909
|
+
const address = record.address ?? "";
|
|
910
|
+
if (typeof address !== "string" || OPTIONAL_TEXT_PROPERTIES.some((key) => !isOptionalText(record[key]))) {
|
|
911
|
+
errors.push({
|
|
912
|
+
fieldId,
|
|
913
|
+
rule: "TYPE",
|
|
914
|
+
message: "Must be a valid sustainability object",
|
|
915
|
+
params: { expectedType: "sustainability" }
|
|
916
|
+
});
|
|
917
|
+
return errors;
|
|
918
|
+
}
|
|
919
|
+
if (validation?.required && address === "") errors.push({
|
|
920
|
+
fieldId,
|
|
921
|
+
rule: "REQUIRED",
|
|
922
|
+
message: "Value is required"
|
|
923
|
+
});
|
|
924
|
+
return errors;
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
function isOptionalText(value) {
|
|
928
|
+
return value === void 0 || value === null || typeof value === "string";
|
|
929
|
+
}
|
|
930
|
+
//#endregion
|
|
686
931
|
//#region src/field-validator.ts
|
|
687
932
|
/**
|
|
688
933
|
* Validates form values against the schema's validation rules.
|
|
@@ -699,9 +944,19 @@ var StringValidator = class {
|
|
|
699
944
|
* - `date` -- `required`, `minDate`, `maxDate`. Relative date boundaries
|
|
700
945
|
* are resolved against `now`.
|
|
701
946
|
* - `select` -- `required`, plus the value must be one of the defined options.
|
|
947
|
+
* - `multiselect` -- `required` (an absent value and an empty array both fail),
|
|
948
|
+
* plus every selected value must be one of the defined options.
|
|
949
|
+
* - `static` -- never validated; static blocks hold no value.
|
|
950
|
+
* - `blockchain` -- `required` only. The CAIP address format is never checked.
|
|
951
|
+
* - `sustainability` -- `required` (the value's `address` must be a non-empty
|
|
952
|
+
* string) plus a shape check; `ccri` and `cmc` are optional text.
|
|
702
953
|
* - `array` -- `minItems`, `maxItems`, plus each item is validated
|
|
703
954
|
* individually according to the array's {@link ArrayItemDef}. Item-level
|
|
704
955
|
* errors carry an `itemIndex`.
|
|
956
|
+
* - `array_obj` -- `minItems`, `maxItems`, plus every sub-field of every row is
|
|
957
|
+
* validated according to the field's {@link ArrayObjItemDef} list. Sub-field
|
|
958
|
+
* errors carry an `itemIndex` (the row) and an `itemFieldId` (the sub-field),
|
|
959
|
+
* while `fieldId` stays the container's id.
|
|
705
960
|
*
|
|
706
961
|
* For all types, if `required` fails, no further rules are checked for that
|
|
707
962
|
* field (early return). If the value is empty/absent and `required` is not
|
|
@@ -721,8 +976,12 @@ var FieldValidator = class {
|
|
|
721
976
|
boolean: new BooleanValidator(),
|
|
722
977
|
date: new DateValidator(),
|
|
723
978
|
select: new SelectValidator(),
|
|
979
|
+
multiselect: new MultiselectValidator(),
|
|
724
980
|
array: new ArrayValidator(),
|
|
725
|
-
|
|
981
|
+
array_obj: new ArrayObjValidator(),
|
|
982
|
+
file: new FileValidator(),
|
|
983
|
+
blockchain: new BlockchainValidator(),
|
|
984
|
+
sustainability: new SustainabilityValidator()
|
|
726
985
|
};
|
|
727
986
|
}
|
|
728
987
|
/**
|
|
@@ -763,6 +1022,17 @@ var FieldValidator = class {
|
|
|
763
1022
|
};
|
|
764
1023
|
return validator.validate(ctx);
|
|
765
1024
|
}
|
|
1025
|
+
if (entry.type === "array_obj") {
|
|
1026
|
+
const ctx = {
|
|
1027
|
+
fieldId,
|
|
1028
|
+
value,
|
|
1029
|
+
validation: entry.validation,
|
|
1030
|
+
now,
|
|
1031
|
+
items: entry.items,
|
|
1032
|
+
validateField: this.validateField.bind(this)
|
|
1033
|
+
};
|
|
1034
|
+
return validator.validate(ctx);
|
|
1035
|
+
}
|
|
766
1036
|
return validator.validate({
|
|
767
1037
|
fieldId,
|
|
768
1038
|
value,
|
|
@@ -817,11 +1087,17 @@ var FormDefinitionEditor = class {
|
|
|
817
1087
|
}
|
|
818
1088
|
/**
|
|
819
1089
|
* Returns the next available numeric id (max existing + 1).
|
|
1090
|
+
*
|
|
1091
|
+
* `array_obj` sub-field ids share the form-wide id space, so they count
|
|
1092
|
+
* here too -- otherwise a new top-level field could collide with one.
|
|
820
1093
|
*/
|
|
821
1094
|
nextId() {
|
|
822
1095
|
let max = 0;
|
|
823
1096
|
this.walkAll(this.definition.content, (item) => {
|
|
824
1097
|
if (item.id > max) max = item.id;
|
|
1098
|
+
if (item.type === "array_obj") {
|
|
1099
|
+
for (const subField of item.items ?? []) if (subField.id > max) max = subField.id;
|
|
1100
|
+
}
|
|
825
1101
|
});
|
|
826
1102
|
return max + 1;
|
|
827
1103
|
}
|
|
@@ -960,6 +1236,7 @@ var FormDefinitionEditor = class {
|
|
|
960
1236
|
const item = this.findItem(id);
|
|
961
1237
|
if (!item) throw new Error(`Item with id ${id} not found`);
|
|
962
1238
|
if (item.type === "section") throw new Error("Sections do not have validation");
|
|
1239
|
+
if (item.type === "static") throw new Error("Static fields do not have validation");
|
|
963
1240
|
const field = item;
|
|
964
1241
|
if (validation === void 0) delete field.validation;
|
|
965
1242
|
else field.validation = validation;
|
|
@@ -976,12 +1253,12 @@ var FormDefinitionEditor = class {
|
|
|
976
1253
|
return this;
|
|
977
1254
|
}
|
|
978
1255
|
/**
|
|
979
|
-
* Sets the
|
|
1256
|
+
* Sets the options for a `select` or `multiselect` field.
|
|
980
1257
|
*/
|
|
981
1258
|
setOptions(id, options) {
|
|
982
1259
|
const item = this.findItem(id);
|
|
983
1260
|
if (!item) throw new Error(`Item with id ${id} not found`);
|
|
984
|
-
if (item.type !== "select") throw new Error(`Field ${id} is not a select field`);
|
|
1261
|
+
if (item.type !== "select" && item.type !== "multiselect") throw new Error(`Field ${id} is not a select or multiselect field`);
|
|
985
1262
|
const field = item;
|
|
986
1263
|
field.options = options;
|
|
987
1264
|
return this;
|
|
@@ -998,6 +1275,94 @@ var FormDefinitionEditor = class {
|
|
|
998
1275
|
return this;
|
|
999
1276
|
}
|
|
1000
1277
|
/**
|
|
1278
|
+
* Replaces the whole sub-field list of an `array_obj` field.
|
|
1279
|
+
*
|
|
1280
|
+
* @throws If the id is not found or does not refer to an `array_obj` field.
|
|
1281
|
+
*/
|
|
1282
|
+
setArrayItems(id, itemDefs) {
|
|
1283
|
+
this.assertArrayObjField(id).items = itemDefs;
|
|
1284
|
+
return this;
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Returns the sub-field list of an `array_obj` field.
|
|
1288
|
+
*
|
|
1289
|
+
* @throws If the id is not found or does not refer to an `array_obj` field.
|
|
1290
|
+
*/
|
|
1291
|
+
getArrayItems(id) {
|
|
1292
|
+
return this.assertArrayObjField(id).items ?? [];
|
|
1293
|
+
}
|
|
1294
|
+
/**
|
|
1295
|
+
* Sets or clears the layout hint of an `array_obj` field.
|
|
1296
|
+
*
|
|
1297
|
+
* Presentation metadata only -- the engine never reads it. Passing
|
|
1298
|
+
* `undefined` removes the key, which reads as `'list'`.
|
|
1299
|
+
*
|
|
1300
|
+
* @throws If the id is not found or does not refer to an `array_obj` field.
|
|
1301
|
+
*/
|
|
1302
|
+
setArrayKind(id, kind) {
|
|
1303
|
+
const field = this.assertArrayObjField(id);
|
|
1304
|
+
if (kind === void 0) delete field.kind;
|
|
1305
|
+
else field.kind = kind;
|
|
1306
|
+
return this;
|
|
1307
|
+
}
|
|
1308
|
+
/**
|
|
1309
|
+
* Appends a sub-field to an `array_obj` field. The sub-field's `id` is
|
|
1310
|
+
* auto-assigned when omitted.
|
|
1311
|
+
*
|
|
1312
|
+
* @returns The id of the sub-field that was added.
|
|
1313
|
+
* @throws If the id is not found, does not refer to an `array_obj` field,
|
|
1314
|
+
* or the requested sub-field id is already taken.
|
|
1315
|
+
*/
|
|
1316
|
+
addArrayItemField(id, subField) {
|
|
1317
|
+
const field = this.assertArrayObjField(id);
|
|
1318
|
+
const subFieldId = subField.id ?? this.nextId();
|
|
1319
|
+
this.assertIdAvailable(subFieldId);
|
|
1320
|
+
field.items?.push({
|
|
1321
|
+
...subField,
|
|
1322
|
+
id: subFieldId
|
|
1323
|
+
});
|
|
1324
|
+
return subFieldId;
|
|
1325
|
+
}
|
|
1326
|
+
/**
|
|
1327
|
+
* Merges properties into an existing `array_obj` sub-field.
|
|
1328
|
+
*
|
|
1329
|
+
* Like {@link updateField}, omitted properties are kept rather than
|
|
1330
|
+
* removed -- pass a property explicitly as `undefined` to clear it.
|
|
1331
|
+
*
|
|
1332
|
+
* @throws If the field or the sub-field is not found.
|
|
1333
|
+
*/
|
|
1334
|
+
updateArrayItemField(id, subFieldId, patch) {
|
|
1335
|
+
const subField = this.assertArrayObjField(id).items?.find((f) => f.id === subFieldId);
|
|
1336
|
+
if (!subField) throw new Error(`Sub-field with id ${subFieldId} not found in field ${id}`);
|
|
1337
|
+
Object.assign(subField, patch, { id: subFieldId });
|
|
1338
|
+
return this;
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* Removes a sub-field from an `array_obj` field.
|
|
1342
|
+
*
|
|
1343
|
+
* @throws If the field or the sub-field is not found.
|
|
1344
|
+
*/
|
|
1345
|
+
removeArrayItemField(id, subFieldId) {
|
|
1346
|
+
const field = this.assertArrayObjField(id);
|
|
1347
|
+
const index = field.items?.findIndex((f) => f.id === subFieldId) ?? -1;
|
|
1348
|
+
if (index < 0) throw new Error(`Sub-field with id ${subFieldId} not found in field ${id}`);
|
|
1349
|
+
field.items?.splice(index, 1);
|
|
1350
|
+
return this;
|
|
1351
|
+
}
|
|
1352
|
+
/**
|
|
1353
|
+
* Moves a sub-field of an `array_obj` field to another position.
|
|
1354
|
+
*
|
|
1355
|
+
* @throws If the field is not found or either index is out of range.
|
|
1356
|
+
*/
|
|
1357
|
+
moveArrayItemField(id, fromIndex, toIndex) {
|
|
1358
|
+
const items = this.assertArrayObjField(id).items ?? [];
|
|
1359
|
+
if (fromIndex < 0 || fromIndex >= items.length) throw new Error(`Index ${fromIndex} out of range`);
|
|
1360
|
+
if (toIndex < 0 || toIndex >= items.length) throw new Error(`Index ${toIndex} out of range`);
|
|
1361
|
+
const [moved] = items.splice(fromIndex, 1);
|
|
1362
|
+
if (moved) items.splice(toIndex, 0, moved);
|
|
1363
|
+
return this;
|
|
1364
|
+
}
|
|
1365
|
+
/**
|
|
1001
1366
|
* Sets the label for a field.
|
|
1002
1367
|
*/
|
|
1003
1368
|
setLabel(id, label) {
|
|
@@ -1009,6 +1374,18 @@ var FormDefinitionEditor = class {
|
|
|
1009
1374
|
return this;
|
|
1010
1375
|
}
|
|
1011
1376
|
/**
|
|
1377
|
+
* Sets the displayed text of a `static` field.
|
|
1378
|
+
*
|
|
1379
|
+
* @throws If the id is not found or does not refer to a static field.
|
|
1380
|
+
*/
|
|
1381
|
+
setText(id, text) {
|
|
1382
|
+
const item = this.findItem(id);
|
|
1383
|
+
if (!item) throw new Error(`Item with id ${id} not found`);
|
|
1384
|
+
if (item.type !== "static") throw new Error(`Field ${id} is not a static field`);
|
|
1385
|
+
item.text = text;
|
|
1386
|
+
return this;
|
|
1387
|
+
}
|
|
1388
|
+
/**
|
|
1012
1389
|
* Sets the description for a field or section.
|
|
1013
1390
|
*/
|
|
1014
1391
|
setFieldDescription(id, description) {
|
|
@@ -1019,6 +1396,41 @@ var FormDefinitionEditor = class {
|
|
|
1019
1396
|
return this;
|
|
1020
1397
|
}
|
|
1021
1398
|
/**
|
|
1399
|
+
* Sets the placeholder for a field or section.
|
|
1400
|
+
*
|
|
1401
|
+
* Passing `undefined` removes the property. Unlike {@link updateField},
|
|
1402
|
+
* which merges and therefore cannot clear, this genuinely deletes the key.
|
|
1403
|
+
*/
|
|
1404
|
+
setPlaceholder(id, placeholder) {
|
|
1405
|
+
return this.setMetadata(id, "placeholder", placeholder);
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
1408
|
+
* Sets the answer guidelines for a field or section.
|
|
1409
|
+
*
|
|
1410
|
+
* Passing `undefined` removes the property.
|
|
1411
|
+
*/
|
|
1412
|
+
setAnswerGuidelines(id, answerGuidelines) {
|
|
1413
|
+
return this.setMetadata(id, "answer_guidelines", answerGuidelines);
|
|
1414
|
+
}
|
|
1415
|
+
/**
|
|
1416
|
+
* Sets the external reference id for a field or section.
|
|
1417
|
+
*
|
|
1418
|
+
* Passing `undefined` removes the property.
|
|
1419
|
+
*/
|
|
1420
|
+
setReferenceId(id, referenceId) {
|
|
1421
|
+
return this.setMetadata(id, "reference_id", referenceId);
|
|
1422
|
+
}
|
|
1423
|
+
/**
|
|
1424
|
+
* Assigns or deletes one optional string property on a field or section.
|
|
1425
|
+
*/
|
|
1426
|
+
setMetadata(id, property, value) {
|
|
1427
|
+
const item = this.findItem(id);
|
|
1428
|
+
if (!item) throw new Error(`Item with id ${id} not found`);
|
|
1429
|
+
if (value === void 0) delete item[property];
|
|
1430
|
+
else item[property] = value;
|
|
1431
|
+
return this;
|
|
1432
|
+
}
|
|
1433
|
+
/**
|
|
1022
1434
|
* Returns a deep clone of the current form definition.
|
|
1023
1435
|
*/
|
|
1024
1436
|
toJSON() {
|
|
@@ -1033,6 +1445,30 @@ var FormDefinitionEditor = class {
|
|
|
1033
1445
|
}
|
|
1034
1446
|
assertIdAvailable(id) {
|
|
1035
1447
|
if (this.findItem(id)) throw new Error(`Item with id ${id} already exists`);
|
|
1448
|
+
if (this.findArrayObjItem(id)) throw new Error(`Item with id ${id} already exists`);
|
|
1449
|
+
}
|
|
1450
|
+
/**
|
|
1451
|
+
* Finds an `array_obj` sub-field anywhere in the definition by its id.
|
|
1452
|
+
*/
|
|
1453
|
+
findArrayObjItem(id) {
|
|
1454
|
+
let found;
|
|
1455
|
+
this.walkAll(this.definition.content, (item) => {
|
|
1456
|
+
if (found || item.type !== "array_obj") return;
|
|
1457
|
+
const subField = (item.items ?? []).find((f) => f.id === id);
|
|
1458
|
+
if (subField) found = {
|
|
1459
|
+
field: item,
|
|
1460
|
+
subField
|
|
1461
|
+
};
|
|
1462
|
+
});
|
|
1463
|
+
return found;
|
|
1464
|
+
}
|
|
1465
|
+
assertArrayObjField(id) {
|
|
1466
|
+
const item = this.findItem(id);
|
|
1467
|
+
if (!item) throw new Error(`Item with id ${id} not found`);
|
|
1468
|
+
if (item.type !== "array_obj") throw new Error(`Field ${id} is not an array_obj field`);
|
|
1469
|
+
const field = item;
|
|
1470
|
+
if (!field.items) field.items = [];
|
|
1471
|
+
return field;
|
|
1036
1472
|
}
|
|
1037
1473
|
insertItem(item, parentId, index) {
|
|
1038
1474
|
const target = this.getTargetContent(parentId);
|
|
@@ -1244,6 +1680,11 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1244
1680
|
"properties": { "required": { "type": "boolean" } },
|
|
1245
1681
|
"additionalProperties": false
|
|
1246
1682
|
},
|
|
1683
|
+
"multiselectValidation": {
|
|
1684
|
+
"type": "object",
|
|
1685
|
+
"properties": { "required": { "type": "boolean" } },
|
|
1686
|
+
"additionalProperties": false
|
|
1687
|
+
},
|
|
1247
1688
|
"arrayValidation": {
|
|
1248
1689
|
"type": "object",
|
|
1249
1690
|
"properties": {
|
|
@@ -1258,11 +1699,35 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1258
1699
|
},
|
|
1259
1700
|
"additionalProperties": false
|
|
1260
1701
|
},
|
|
1702
|
+
"arrayObjValidation": {
|
|
1703
|
+
"type": "object",
|
|
1704
|
+
"properties": {
|
|
1705
|
+
"minItems": {
|
|
1706
|
+
"type": "integer",
|
|
1707
|
+
"minimum": 0
|
|
1708
|
+
},
|
|
1709
|
+
"maxItems": {
|
|
1710
|
+
"type": "integer",
|
|
1711
|
+
"minimum": 1
|
|
1712
|
+
}
|
|
1713
|
+
},
|
|
1714
|
+
"additionalProperties": false
|
|
1715
|
+
},
|
|
1261
1716
|
"fileValidation": {
|
|
1262
1717
|
"type": "object",
|
|
1263
1718
|
"properties": { "required": { "type": "boolean" } },
|
|
1264
1719
|
"additionalProperties": false
|
|
1265
1720
|
},
|
|
1721
|
+
"blockchainValidation": {
|
|
1722
|
+
"type": "object",
|
|
1723
|
+
"properties": { "required": { "type": "boolean" } },
|
|
1724
|
+
"additionalProperties": false
|
|
1725
|
+
},
|
|
1726
|
+
"sustainabilityValidation": {
|
|
1727
|
+
"type": "object",
|
|
1728
|
+
"properties": { "required": { "type": "boolean" } },
|
|
1729
|
+
"additionalProperties": false
|
|
1730
|
+
},
|
|
1266
1731
|
"selectOption": {
|
|
1267
1732
|
"type": "object",
|
|
1268
1733
|
"required": ["value", "label"],
|
|
@@ -1279,6 +1744,9 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1279
1744
|
"type": { "const": "string" },
|
|
1280
1745
|
"label": { "type": "string" },
|
|
1281
1746
|
"description": { "type": "string" },
|
|
1747
|
+
"placeholder": { "type": "string" },
|
|
1748
|
+
"answer_guidelines": { "type": "string" },
|
|
1749
|
+
"reference_id": { "type": "string" },
|
|
1282
1750
|
"validation": { "$ref": "#/$defs/stringValidation" }
|
|
1283
1751
|
},
|
|
1284
1752
|
"additionalProperties": false
|
|
@@ -1290,6 +1758,9 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1290
1758
|
"type": { "const": "number" },
|
|
1291
1759
|
"label": { "type": "string" },
|
|
1292
1760
|
"description": { "type": "string" },
|
|
1761
|
+
"placeholder": { "type": "string" },
|
|
1762
|
+
"answer_guidelines": { "type": "string" },
|
|
1763
|
+
"reference_id": { "type": "string" },
|
|
1293
1764
|
"validation": { "$ref": "#/$defs/numberValidation" }
|
|
1294
1765
|
},
|
|
1295
1766
|
"additionalProperties": false
|
|
@@ -1301,6 +1772,9 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1301
1772
|
"type": { "const": "boolean" },
|
|
1302
1773
|
"label": { "type": "string" },
|
|
1303
1774
|
"description": { "type": "string" },
|
|
1775
|
+
"placeholder": { "type": "string" },
|
|
1776
|
+
"answer_guidelines": { "type": "string" },
|
|
1777
|
+
"reference_id": { "type": "string" },
|
|
1304
1778
|
"validation": { "$ref": "#/$defs/booleanValidation" }
|
|
1305
1779
|
},
|
|
1306
1780
|
"additionalProperties": false
|
|
@@ -1312,6 +1786,9 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1312
1786
|
"type": { "const": "date" },
|
|
1313
1787
|
"label": { "type": "string" },
|
|
1314
1788
|
"description": { "type": "string" },
|
|
1789
|
+
"placeholder": { "type": "string" },
|
|
1790
|
+
"answer_guidelines": { "type": "string" },
|
|
1791
|
+
"reference_id": { "type": "string" },
|
|
1315
1792
|
"validation": { "$ref": "#/$defs/dateValidation" }
|
|
1316
1793
|
},
|
|
1317
1794
|
"additionalProperties": false
|
|
@@ -1327,6 +1804,9 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1327
1804
|
"type": { "const": "select" },
|
|
1328
1805
|
"label": { "type": "string" },
|
|
1329
1806
|
"description": { "type": "string" },
|
|
1807
|
+
"placeholder": { "type": "string" },
|
|
1808
|
+
"answer_guidelines": { "type": "string" },
|
|
1809
|
+
"reference_id": { "type": "string" },
|
|
1330
1810
|
"options": {
|
|
1331
1811
|
"type": "array",
|
|
1332
1812
|
"minItems": 1,
|
|
@@ -1343,19 +1823,335 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1343
1823
|
"type": { "const": "file" },
|
|
1344
1824
|
"label": { "type": "string" },
|
|
1345
1825
|
"description": { "type": "string" },
|
|
1826
|
+
"placeholder": { "type": "string" },
|
|
1827
|
+
"answer_guidelines": { "type": "string" },
|
|
1828
|
+
"reference_id": { "type": "string" },
|
|
1346
1829
|
"validation": { "$ref": "#/$defs/fileValidation" }
|
|
1347
1830
|
},
|
|
1348
1831
|
"additionalProperties": false
|
|
1349
1832
|
},
|
|
1350
|
-
"
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1833
|
+
"arrayItemBlockchain": {
|
|
1834
|
+
"type": "object",
|
|
1835
|
+
"required": ["type", "label"],
|
|
1836
|
+
"properties": {
|
|
1837
|
+
"type": { "const": "blockchain" },
|
|
1838
|
+
"label": { "type": "string" },
|
|
1839
|
+
"description": { "type": "string" },
|
|
1840
|
+
"placeholder": { "type": "string" },
|
|
1841
|
+
"answer_guidelines": { "type": "string" },
|
|
1842
|
+
"reference_id": { "type": "string" },
|
|
1843
|
+
"validation": { "$ref": "#/$defs/blockchainValidation" }
|
|
1844
|
+
},
|
|
1845
|
+
"additionalProperties": false
|
|
1846
|
+
},
|
|
1847
|
+
"arrayItemSustainability": {
|
|
1848
|
+
"type": "object",
|
|
1849
|
+
"required": ["type", "label"],
|
|
1850
|
+
"properties": {
|
|
1851
|
+
"type": { "const": "sustainability" },
|
|
1852
|
+
"label": { "type": "string" },
|
|
1853
|
+
"description": { "type": "string" },
|
|
1854
|
+
"placeholder": { "type": "string" },
|
|
1855
|
+
"answer_guidelines": { "type": "string" },
|
|
1856
|
+
"reference_id": { "type": "string" },
|
|
1857
|
+
"validation": { "$ref": "#/$defs/sustainabilityValidation" }
|
|
1858
|
+
},
|
|
1859
|
+
"additionalProperties": false
|
|
1860
|
+
},
|
|
1861
|
+
"arrayItemMultiselect": {
|
|
1862
|
+
"type": "object",
|
|
1863
|
+
"required": [
|
|
1864
|
+
"type",
|
|
1865
|
+
"label",
|
|
1866
|
+
"options"
|
|
1867
|
+
],
|
|
1868
|
+
"properties": {
|
|
1869
|
+
"type": { "const": "multiselect" },
|
|
1870
|
+
"label": { "type": "string" },
|
|
1871
|
+
"description": { "type": "string" },
|
|
1872
|
+
"placeholder": { "type": "string" },
|
|
1873
|
+
"answer_guidelines": { "type": "string" },
|
|
1874
|
+
"reference_id": { "type": "string" },
|
|
1875
|
+
"options": {
|
|
1876
|
+
"type": "array",
|
|
1877
|
+
"minItems": 1,
|
|
1878
|
+
"items": { "$ref": "#/$defs/selectOption" }
|
|
1879
|
+
},
|
|
1880
|
+
"validation": { "$ref": "#/$defs/multiselectValidation" }
|
|
1881
|
+
},
|
|
1882
|
+
"additionalProperties": false
|
|
1883
|
+
},
|
|
1884
|
+
"arrayItemStatic": {
|
|
1885
|
+
"type": "object",
|
|
1886
|
+
"required": ["type", "text"],
|
|
1887
|
+
"properties": {
|
|
1888
|
+
"type": { "const": "static" },
|
|
1889
|
+
"text": { "type": "string" },
|
|
1890
|
+
"label": { "type": "string" },
|
|
1891
|
+
"description": { "type": "string" },
|
|
1892
|
+
"placeholder": { "type": "string" },
|
|
1893
|
+
"answer_guidelines": { "type": "string" },
|
|
1894
|
+
"reference_id": { "type": "string" }
|
|
1895
|
+
},
|
|
1896
|
+
"additionalProperties": false
|
|
1897
|
+
},
|
|
1898
|
+
"arrayItem": { "oneOf": [
|
|
1899
|
+
{ "$ref": "#/$defs/arrayItemString" },
|
|
1900
|
+
{ "$ref": "#/$defs/arrayItemNumber" },
|
|
1901
|
+
{ "$ref": "#/$defs/arrayItemBoolean" },
|
|
1902
|
+
{ "$ref": "#/$defs/arrayItemDate" },
|
|
1903
|
+
{ "$ref": "#/$defs/arrayItemSelect" },
|
|
1904
|
+
{ "$ref": "#/$defs/arrayItemFile" },
|
|
1905
|
+
{ "$ref": "#/$defs/arrayItemBlockchain" },
|
|
1906
|
+
{ "$ref": "#/$defs/arrayItemSustainability" },
|
|
1907
|
+
{ "$ref": "#/$defs/arrayItemMultiselect" },
|
|
1908
|
+
{ "$ref": "#/$defs/arrayItemStatic" }
|
|
1909
|
+
] },
|
|
1910
|
+
"arrayObjItemString": {
|
|
1911
|
+
"type": "object",
|
|
1912
|
+
"required": [
|
|
1913
|
+
"id",
|
|
1914
|
+
"type",
|
|
1915
|
+
"label"
|
|
1916
|
+
],
|
|
1917
|
+
"properties": {
|
|
1918
|
+
"id": {
|
|
1919
|
+
"type": "integer",
|
|
1920
|
+
"minimum": 1
|
|
1921
|
+
},
|
|
1922
|
+
"type": { "const": "string" },
|
|
1923
|
+
"label": { "type": "string" },
|
|
1924
|
+
"description": { "type": "string" },
|
|
1925
|
+
"placeholder": { "type": "string" },
|
|
1926
|
+
"answer_guidelines": { "type": "string" },
|
|
1927
|
+
"reference_id": { "type": "string" },
|
|
1928
|
+
"validation": { "$ref": "#/$defs/stringValidation" }
|
|
1929
|
+
},
|
|
1930
|
+
"additionalProperties": false
|
|
1931
|
+
},
|
|
1932
|
+
"arrayObjItemNumber": {
|
|
1933
|
+
"type": "object",
|
|
1934
|
+
"required": [
|
|
1935
|
+
"id",
|
|
1936
|
+
"type",
|
|
1937
|
+
"label"
|
|
1938
|
+
],
|
|
1939
|
+
"properties": {
|
|
1940
|
+
"id": {
|
|
1941
|
+
"type": "integer",
|
|
1942
|
+
"minimum": 1
|
|
1943
|
+
},
|
|
1944
|
+
"type": { "const": "number" },
|
|
1945
|
+
"label": { "type": "string" },
|
|
1946
|
+
"description": { "type": "string" },
|
|
1947
|
+
"placeholder": { "type": "string" },
|
|
1948
|
+
"answer_guidelines": { "type": "string" },
|
|
1949
|
+
"reference_id": { "type": "string" },
|
|
1950
|
+
"validation": { "$ref": "#/$defs/numberValidation" }
|
|
1951
|
+
},
|
|
1952
|
+
"additionalProperties": false
|
|
1953
|
+
},
|
|
1954
|
+
"arrayObjItemBoolean": {
|
|
1955
|
+
"type": "object",
|
|
1956
|
+
"required": [
|
|
1957
|
+
"id",
|
|
1958
|
+
"type",
|
|
1959
|
+
"label"
|
|
1960
|
+
],
|
|
1961
|
+
"properties": {
|
|
1962
|
+
"id": {
|
|
1963
|
+
"type": "integer",
|
|
1964
|
+
"minimum": 1
|
|
1965
|
+
},
|
|
1966
|
+
"type": { "const": "boolean" },
|
|
1967
|
+
"label": { "type": "string" },
|
|
1968
|
+
"description": { "type": "string" },
|
|
1969
|
+
"placeholder": { "type": "string" },
|
|
1970
|
+
"answer_guidelines": { "type": "string" },
|
|
1971
|
+
"reference_id": { "type": "string" },
|
|
1972
|
+
"validation": { "$ref": "#/$defs/booleanValidation" }
|
|
1973
|
+
},
|
|
1974
|
+
"additionalProperties": false
|
|
1975
|
+
},
|
|
1976
|
+
"arrayObjItemDate": {
|
|
1977
|
+
"type": "object",
|
|
1978
|
+
"required": [
|
|
1979
|
+
"id",
|
|
1980
|
+
"type",
|
|
1981
|
+
"label"
|
|
1982
|
+
],
|
|
1983
|
+
"properties": {
|
|
1984
|
+
"id": {
|
|
1985
|
+
"type": "integer",
|
|
1986
|
+
"minimum": 1
|
|
1987
|
+
},
|
|
1988
|
+
"type": { "const": "date" },
|
|
1989
|
+
"label": { "type": "string" },
|
|
1990
|
+
"description": { "type": "string" },
|
|
1991
|
+
"placeholder": { "type": "string" },
|
|
1992
|
+
"answer_guidelines": { "type": "string" },
|
|
1993
|
+
"reference_id": { "type": "string" },
|
|
1994
|
+
"validation": { "$ref": "#/$defs/dateValidation" }
|
|
1995
|
+
},
|
|
1996
|
+
"additionalProperties": false
|
|
1997
|
+
},
|
|
1998
|
+
"arrayObjItemSelect": {
|
|
1999
|
+
"type": "object",
|
|
2000
|
+
"required": [
|
|
2001
|
+
"id",
|
|
2002
|
+
"type",
|
|
2003
|
+
"label",
|
|
2004
|
+
"options"
|
|
2005
|
+
],
|
|
2006
|
+
"properties": {
|
|
2007
|
+
"id": {
|
|
2008
|
+
"type": "integer",
|
|
2009
|
+
"minimum": 1
|
|
2010
|
+
},
|
|
2011
|
+
"type": { "const": "select" },
|
|
2012
|
+
"label": { "type": "string" },
|
|
2013
|
+
"description": { "type": "string" },
|
|
2014
|
+
"placeholder": { "type": "string" },
|
|
2015
|
+
"answer_guidelines": { "type": "string" },
|
|
2016
|
+
"reference_id": { "type": "string" },
|
|
2017
|
+
"options": {
|
|
2018
|
+
"type": "array",
|
|
2019
|
+
"minItems": 1,
|
|
2020
|
+
"items": { "$ref": "#/$defs/selectOption" }
|
|
2021
|
+
},
|
|
2022
|
+
"validation": { "$ref": "#/$defs/selectValidation" }
|
|
2023
|
+
},
|
|
2024
|
+
"additionalProperties": false
|
|
2025
|
+
},
|
|
2026
|
+
"arrayObjItemMultiselect": {
|
|
2027
|
+
"type": "object",
|
|
2028
|
+
"required": [
|
|
2029
|
+
"id",
|
|
2030
|
+
"type",
|
|
2031
|
+
"label",
|
|
2032
|
+
"options"
|
|
2033
|
+
],
|
|
2034
|
+
"properties": {
|
|
2035
|
+
"id": {
|
|
2036
|
+
"type": "integer",
|
|
2037
|
+
"minimum": 1
|
|
2038
|
+
},
|
|
2039
|
+
"type": { "const": "multiselect" },
|
|
2040
|
+
"label": { "type": "string" },
|
|
2041
|
+
"description": { "type": "string" },
|
|
2042
|
+
"placeholder": { "type": "string" },
|
|
2043
|
+
"answer_guidelines": { "type": "string" },
|
|
2044
|
+
"reference_id": { "type": "string" },
|
|
2045
|
+
"options": {
|
|
2046
|
+
"type": "array",
|
|
2047
|
+
"minItems": 1,
|
|
2048
|
+
"items": { "$ref": "#/$defs/selectOption" }
|
|
2049
|
+
},
|
|
2050
|
+
"validation": { "$ref": "#/$defs/multiselectValidation" }
|
|
2051
|
+
},
|
|
2052
|
+
"additionalProperties": false
|
|
2053
|
+
},
|
|
2054
|
+
"arrayObjItemFile": {
|
|
2055
|
+
"type": "object",
|
|
2056
|
+
"required": [
|
|
2057
|
+
"id",
|
|
2058
|
+
"type",
|
|
2059
|
+
"label"
|
|
2060
|
+
],
|
|
2061
|
+
"properties": {
|
|
2062
|
+
"id": {
|
|
2063
|
+
"type": "integer",
|
|
2064
|
+
"minimum": 1
|
|
2065
|
+
},
|
|
2066
|
+
"type": { "const": "file" },
|
|
2067
|
+
"label": { "type": "string" },
|
|
2068
|
+
"description": { "type": "string" },
|
|
2069
|
+
"placeholder": { "type": "string" },
|
|
2070
|
+
"answer_guidelines": { "type": "string" },
|
|
2071
|
+
"reference_id": { "type": "string" },
|
|
2072
|
+
"validation": { "$ref": "#/$defs/fileValidation" }
|
|
2073
|
+
},
|
|
2074
|
+
"additionalProperties": false
|
|
2075
|
+
},
|
|
2076
|
+
"arrayObjItemBlockchain": {
|
|
2077
|
+
"type": "object",
|
|
2078
|
+
"required": [
|
|
2079
|
+
"id",
|
|
2080
|
+
"type",
|
|
2081
|
+
"label"
|
|
2082
|
+
],
|
|
2083
|
+
"properties": {
|
|
2084
|
+
"id": {
|
|
2085
|
+
"type": "integer",
|
|
2086
|
+
"minimum": 1
|
|
2087
|
+
},
|
|
2088
|
+
"type": { "const": "blockchain" },
|
|
2089
|
+
"label": { "type": "string" },
|
|
2090
|
+
"description": { "type": "string" },
|
|
2091
|
+
"placeholder": { "type": "string" },
|
|
2092
|
+
"answer_guidelines": { "type": "string" },
|
|
2093
|
+
"reference_id": { "type": "string" },
|
|
2094
|
+
"validation": { "$ref": "#/$defs/blockchainValidation" }
|
|
2095
|
+
},
|
|
2096
|
+
"additionalProperties": false
|
|
2097
|
+
},
|
|
2098
|
+
"arrayObjItemSustainability": {
|
|
2099
|
+
"type": "object",
|
|
2100
|
+
"required": [
|
|
2101
|
+
"id",
|
|
2102
|
+
"type",
|
|
2103
|
+
"label"
|
|
2104
|
+
],
|
|
2105
|
+
"properties": {
|
|
2106
|
+
"id": {
|
|
2107
|
+
"type": "integer",
|
|
2108
|
+
"minimum": 1
|
|
2109
|
+
},
|
|
2110
|
+
"type": { "const": "sustainability" },
|
|
2111
|
+
"label": { "type": "string" },
|
|
2112
|
+
"description": { "type": "string" },
|
|
2113
|
+
"placeholder": { "type": "string" },
|
|
2114
|
+
"answer_guidelines": { "type": "string" },
|
|
2115
|
+
"reference_id": { "type": "string" },
|
|
2116
|
+
"validation": { "$ref": "#/$defs/sustainabilityValidation" }
|
|
2117
|
+
},
|
|
2118
|
+
"additionalProperties": false
|
|
2119
|
+
},
|
|
2120
|
+
"arrayObjItemStatic": {
|
|
2121
|
+
"type": "object",
|
|
2122
|
+
"required": [
|
|
2123
|
+
"id",
|
|
2124
|
+
"type",
|
|
2125
|
+
"text"
|
|
2126
|
+
],
|
|
2127
|
+
"properties": {
|
|
2128
|
+
"id": {
|
|
2129
|
+
"type": "integer",
|
|
2130
|
+
"minimum": 1
|
|
2131
|
+
},
|
|
2132
|
+
"type": { "const": "static" },
|
|
2133
|
+
"text": { "type": "string" },
|
|
2134
|
+
"label": { "type": "string" },
|
|
2135
|
+
"description": { "type": "string" },
|
|
2136
|
+
"placeholder": { "type": "string" },
|
|
2137
|
+
"answer_guidelines": { "type": "string" },
|
|
2138
|
+
"reference_id": { "type": "string" }
|
|
2139
|
+
},
|
|
2140
|
+
"additionalProperties": false
|
|
2141
|
+
},
|
|
2142
|
+
"arrayObjItem": { "oneOf": [
|
|
2143
|
+
{ "$ref": "#/$defs/arrayObjItemString" },
|
|
2144
|
+
{ "$ref": "#/$defs/arrayObjItemNumber" },
|
|
2145
|
+
{ "$ref": "#/$defs/arrayObjItemBoolean" },
|
|
2146
|
+
{ "$ref": "#/$defs/arrayObjItemDate" },
|
|
2147
|
+
{ "$ref": "#/$defs/arrayObjItemSelect" },
|
|
2148
|
+
{ "$ref": "#/$defs/arrayObjItemMultiselect" },
|
|
2149
|
+
{ "$ref": "#/$defs/arrayObjItemFile" },
|
|
2150
|
+
{ "$ref": "#/$defs/arrayObjItemBlockchain" },
|
|
2151
|
+
{ "$ref": "#/$defs/arrayObjItemSustainability" },
|
|
2152
|
+
{ "$ref": "#/$defs/arrayObjItemStatic" }
|
|
2153
|
+
] },
|
|
2154
|
+
"stringField": {
|
|
1359
2155
|
"type": "object",
|
|
1360
2156
|
"required": [
|
|
1361
2157
|
"id",
|
|
@@ -1370,6 +2166,9 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1370
2166
|
"type": { "const": "string" },
|
|
1371
2167
|
"label": { "type": "string" },
|
|
1372
2168
|
"description": { "type": "string" },
|
|
2169
|
+
"placeholder": { "type": "string" },
|
|
2170
|
+
"answer_guidelines": { "type": "string" },
|
|
2171
|
+
"reference_id": { "type": "string" },
|
|
1373
2172
|
"condition": { "$ref": "#/$defs/condition" },
|
|
1374
2173
|
"validation": { "$ref": "#/$defs/stringValidation" }
|
|
1375
2174
|
},
|
|
@@ -1390,6 +2189,9 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1390
2189
|
"type": { "const": "number" },
|
|
1391
2190
|
"label": { "type": "string" },
|
|
1392
2191
|
"description": { "type": "string" },
|
|
2192
|
+
"placeholder": { "type": "string" },
|
|
2193
|
+
"answer_guidelines": { "type": "string" },
|
|
2194
|
+
"reference_id": { "type": "string" },
|
|
1393
2195
|
"condition": { "$ref": "#/$defs/condition" },
|
|
1394
2196
|
"validation": { "$ref": "#/$defs/numberValidation" }
|
|
1395
2197
|
},
|
|
@@ -1410,6 +2212,9 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1410
2212
|
"type": { "const": "boolean" },
|
|
1411
2213
|
"label": { "type": "string" },
|
|
1412
2214
|
"description": { "type": "string" },
|
|
2215
|
+
"placeholder": { "type": "string" },
|
|
2216
|
+
"answer_guidelines": { "type": "string" },
|
|
2217
|
+
"reference_id": { "type": "string" },
|
|
1413
2218
|
"condition": { "$ref": "#/$defs/condition" },
|
|
1414
2219
|
"validation": { "$ref": "#/$defs/booleanValidation" }
|
|
1415
2220
|
},
|
|
@@ -1430,6 +2235,9 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1430
2235
|
"type": { "const": "date" },
|
|
1431
2236
|
"label": { "type": "string" },
|
|
1432
2237
|
"description": { "type": "string" },
|
|
2238
|
+
"placeholder": { "type": "string" },
|
|
2239
|
+
"answer_guidelines": { "type": "string" },
|
|
2240
|
+
"reference_id": { "type": "string" },
|
|
1433
2241
|
"condition": { "$ref": "#/$defs/condition" },
|
|
1434
2242
|
"validation": { "$ref": "#/$defs/dateValidation" }
|
|
1435
2243
|
},
|
|
@@ -1451,6 +2259,9 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1451
2259
|
"type": { "const": "select" },
|
|
1452
2260
|
"label": { "type": "string" },
|
|
1453
2261
|
"description": { "type": "string" },
|
|
2262
|
+
"placeholder": { "type": "string" },
|
|
2263
|
+
"answer_guidelines": { "type": "string" },
|
|
2264
|
+
"reference_id": { "type": "string" },
|
|
1454
2265
|
"condition": { "$ref": "#/$defs/condition" },
|
|
1455
2266
|
"options": {
|
|
1456
2267
|
"type": "array",
|
|
@@ -1461,6 +2272,58 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1461
2272
|
},
|
|
1462
2273
|
"additionalProperties": false
|
|
1463
2274
|
},
|
|
2275
|
+
"multiselectField": {
|
|
2276
|
+
"type": "object",
|
|
2277
|
+
"required": [
|
|
2278
|
+
"id",
|
|
2279
|
+
"type",
|
|
2280
|
+
"label",
|
|
2281
|
+
"options"
|
|
2282
|
+
],
|
|
2283
|
+
"properties": {
|
|
2284
|
+
"id": {
|
|
2285
|
+
"type": "integer",
|
|
2286
|
+
"minimum": 1
|
|
2287
|
+
},
|
|
2288
|
+
"type": { "const": "multiselect" },
|
|
2289
|
+
"label": { "type": "string" },
|
|
2290
|
+
"description": { "type": "string" },
|
|
2291
|
+
"placeholder": { "type": "string" },
|
|
2292
|
+
"answer_guidelines": { "type": "string" },
|
|
2293
|
+
"reference_id": { "type": "string" },
|
|
2294
|
+
"condition": { "$ref": "#/$defs/condition" },
|
|
2295
|
+
"options": {
|
|
2296
|
+
"type": "array",
|
|
2297
|
+
"minItems": 1,
|
|
2298
|
+
"items": { "$ref": "#/$defs/selectOption" }
|
|
2299
|
+
},
|
|
2300
|
+
"validation": { "$ref": "#/$defs/multiselectValidation" }
|
|
2301
|
+
},
|
|
2302
|
+
"additionalProperties": false
|
|
2303
|
+
},
|
|
2304
|
+
"staticField": {
|
|
2305
|
+
"type": "object",
|
|
2306
|
+
"required": [
|
|
2307
|
+
"id",
|
|
2308
|
+
"type",
|
|
2309
|
+
"text"
|
|
2310
|
+
],
|
|
2311
|
+
"properties": {
|
|
2312
|
+
"id": {
|
|
2313
|
+
"type": "integer",
|
|
2314
|
+
"minimum": 1
|
|
2315
|
+
},
|
|
2316
|
+
"type": { "const": "static" },
|
|
2317
|
+
"text": { "type": "string" },
|
|
2318
|
+
"label": { "type": "string" },
|
|
2319
|
+
"description": { "type": "string" },
|
|
2320
|
+
"placeholder": { "type": "string" },
|
|
2321
|
+
"answer_guidelines": { "type": "string" },
|
|
2322
|
+
"reference_id": { "type": "string" },
|
|
2323
|
+
"condition": { "$ref": "#/$defs/condition" }
|
|
2324
|
+
},
|
|
2325
|
+
"additionalProperties": false
|
|
2326
|
+
},
|
|
1464
2327
|
"arrayField": {
|
|
1465
2328
|
"type": "object",
|
|
1466
2329
|
"required": [
|
|
@@ -1477,12 +2340,48 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1477
2340
|
"type": { "const": "array" },
|
|
1478
2341
|
"label": { "type": "string" },
|
|
1479
2342
|
"description": { "type": "string" },
|
|
2343
|
+
"placeholder": { "type": "string" },
|
|
2344
|
+
"answer_guidelines": { "type": "string" },
|
|
2345
|
+
"reference_id": { "type": "string" },
|
|
1480
2346
|
"condition": { "$ref": "#/$defs/condition" },
|
|
1481
2347
|
"item": { "$ref": "#/$defs/arrayItem" },
|
|
1482
2348
|
"validation": { "$ref": "#/$defs/arrayValidation" }
|
|
1483
2349
|
},
|
|
1484
2350
|
"additionalProperties": false
|
|
1485
2351
|
},
|
|
2352
|
+
"arrayObjField": {
|
|
2353
|
+
"type": "object",
|
|
2354
|
+
"required": [
|
|
2355
|
+
"id",
|
|
2356
|
+
"type",
|
|
2357
|
+
"label",
|
|
2358
|
+
"items"
|
|
2359
|
+
],
|
|
2360
|
+
"properties": {
|
|
2361
|
+
"id": {
|
|
2362
|
+
"type": "integer",
|
|
2363
|
+
"minimum": 1
|
|
2364
|
+
},
|
|
2365
|
+
"type": { "const": "array_obj" },
|
|
2366
|
+
"label": { "type": "string" },
|
|
2367
|
+
"description": { "type": "string" },
|
|
2368
|
+
"placeholder": { "type": "string" },
|
|
2369
|
+
"answer_guidelines": { "type": "string" },
|
|
2370
|
+
"reference_id": { "type": "string" },
|
|
2371
|
+
"condition": { "$ref": "#/$defs/condition" },
|
|
2372
|
+
"items": {
|
|
2373
|
+
"type": "array",
|
|
2374
|
+
"minItems": 1,
|
|
2375
|
+
"items": { "$ref": "#/$defs/arrayObjItem" }
|
|
2376
|
+
},
|
|
2377
|
+
"kind": {
|
|
2378
|
+
"type": "string",
|
|
2379
|
+
"enum": ["list", "table"]
|
|
2380
|
+
},
|
|
2381
|
+
"validation": { "$ref": "#/$defs/arrayObjValidation" }
|
|
2382
|
+
},
|
|
2383
|
+
"additionalProperties": false
|
|
2384
|
+
},
|
|
1486
2385
|
"fileField": {
|
|
1487
2386
|
"type": "object",
|
|
1488
2387
|
"required": [
|
|
@@ -1498,19 +2397,73 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1498
2397
|
"type": { "const": "file" },
|
|
1499
2398
|
"label": { "type": "string" },
|
|
1500
2399
|
"description": { "type": "string" },
|
|
2400
|
+
"placeholder": { "type": "string" },
|
|
2401
|
+
"answer_guidelines": { "type": "string" },
|
|
2402
|
+
"reference_id": { "type": "string" },
|
|
1501
2403
|
"condition": { "$ref": "#/$defs/condition" },
|
|
1502
2404
|
"validation": { "$ref": "#/$defs/fileValidation" }
|
|
1503
2405
|
},
|
|
1504
2406
|
"additionalProperties": false
|
|
1505
2407
|
},
|
|
2408
|
+
"blockchainField": {
|
|
2409
|
+
"type": "object",
|
|
2410
|
+
"required": [
|
|
2411
|
+
"id",
|
|
2412
|
+
"type",
|
|
2413
|
+
"label"
|
|
2414
|
+
],
|
|
2415
|
+
"properties": {
|
|
2416
|
+
"id": {
|
|
2417
|
+
"type": "integer",
|
|
2418
|
+
"minimum": 1
|
|
2419
|
+
},
|
|
2420
|
+
"type": { "const": "blockchain" },
|
|
2421
|
+
"label": { "type": "string" },
|
|
2422
|
+
"description": { "type": "string" },
|
|
2423
|
+
"placeholder": { "type": "string" },
|
|
2424
|
+
"answer_guidelines": { "type": "string" },
|
|
2425
|
+
"reference_id": { "type": "string" },
|
|
2426
|
+
"condition": { "$ref": "#/$defs/condition" },
|
|
2427
|
+
"validation": { "$ref": "#/$defs/blockchainValidation" }
|
|
2428
|
+
},
|
|
2429
|
+
"additionalProperties": false
|
|
2430
|
+
},
|
|
2431
|
+
"sustainabilityField": {
|
|
2432
|
+
"type": "object",
|
|
2433
|
+
"required": [
|
|
2434
|
+
"id",
|
|
2435
|
+
"type",
|
|
2436
|
+
"label"
|
|
2437
|
+
],
|
|
2438
|
+
"properties": {
|
|
2439
|
+
"id": {
|
|
2440
|
+
"type": "integer",
|
|
2441
|
+
"minimum": 1
|
|
2442
|
+
},
|
|
2443
|
+
"type": { "const": "sustainability" },
|
|
2444
|
+
"label": { "type": "string" },
|
|
2445
|
+
"description": { "type": "string" },
|
|
2446
|
+
"placeholder": { "type": "string" },
|
|
2447
|
+
"answer_guidelines": { "type": "string" },
|
|
2448
|
+
"reference_id": { "type": "string" },
|
|
2449
|
+
"condition": { "$ref": "#/$defs/condition" },
|
|
2450
|
+
"validation": { "$ref": "#/$defs/sustainabilityValidation" }
|
|
2451
|
+
},
|
|
2452
|
+
"additionalProperties": false
|
|
2453
|
+
},
|
|
1506
2454
|
"fieldItem": { "oneOf": [
|
|
1507
2455
|
{ "$ref": "#/$defs/stringField" },
|
|
1508
2456
|
{ "$ref": "#/$defs/numberField" },
|
|
1509
2457
|
{ "$ref": "#/$defs/booleanField" },
|
|
1510
2458
|
{ "$ref": "#/$defs/dateField" },
|
|
1511
2459
|
{ "$ref": "#/$defs/selectField" },
|
|
2460
|
+
{ "$ref": "#/$defs/multiselectField" },
|
|
1512
2461
|
{ "$ref": "#/$defs/arrayField" },
|
|
1513
|
-
{ "$ref": "#/$defs/
|
|
2462
|
+
{ "$ref": "#/$defs/arrayObjField" },
|
|
2463
|
+
{ "$ref": "#/$defs/fileField" },
|
|
2464
|
+
{ "$ref": "#/$defs/staticField" },
|
|
2465
|
+
{ "$ref": "#/$defs/blockchainField" },
|
|
2466
|
+
{ "$ref": "#/$defs/sustainabilityField" }
|
|
1514
2467
|
] },
|
|
1515
2468
|
"section": {
|
|
1516
2469
|
"type": "object",
|
|
@@ -1528,6 +2481,9 @@ const validateFn = new ajv_dist_2020.default({ allErrors: true }).compile({
|
|
|
1528
2481
|
"type": { "const": "section" },
|
|
1529
2482
|
"title": { "type": "string" },
|
|
1530
2483
|
"description": { "type": "string" },
|
|
2484
|
+
"placeholder": { "type": "string" },
|
|
2485
|
+
"answer_guidelines": { "type": "string" },
|
|
2486
|
+
"reference_id": { "type": "string" },
|
|
1531
2487
|
"condition": { "$ref": "#/$defs/condition" },
|
|
1532
2488
|
"content": {
|
|
1533
2489
|
"type": "array",
|
|
@@ -1567,17 +2523,44 @@ const itemRequiredProperties = new Map([
|
|
|
1567
2523
|
"label",
|
|
1568
2524
|
"options"
|
|
1569
2525
|
])],
|
|
2526
|
+
["multiselect", new Set([
|
|
2527
|
+
"id",
|
|
2528
|
+
"type",
|
|
2529
|
+
"label",
|
|
2530
|
+
"options"
|
|
2531
|
+
])],
|
|
1570
2532
|
["array", new Set([
|
|
1571
2533
|
"id",
|
|
1572
2534
|
"type",
|
|
1573
2535
|
"label",
|
|
1574
2536
|
"item"
|
|
1575
2537
|
])],
|
|
2538
|
+
["array_obj", new Set([
|
|
2539
|
+
"id",
|
|
2540
|
+
"type",
|
|
2541
|
+
"label",
|
|
2542
|
+
"items"
|
|
2543
|
+
])],
|
|
1576
2544
|
["file", new Set([
|
|
1577
2545
|
"id",
|
|
1578
2546
|
"type",
|
|
1579
2547
|
"label"
|
|
1580
2548
|
])],
|
|
2549
|
+
["blockchain", new Set([
|
|
2550
|
+
"id",
|
|
2551
|
+
"type",
|
|
2552
|
+
"label"
|
|
2553
|
+
])],
|
|
2554
|
+
["sustainability", new Set([
|
|
2555
|
+
"id",
|
|
2556
|
+
"type",
|
|
2557
|
+
"label"
|
|
2558
|
+
])],
|
|
2559
|
+
["static", new Set([
|
|
2560
|
+
"id",
|
|
2561
|
+
"type",
|
|
2562
|
+
"text"
|
|
2563
|
+
])],
|
|
1581
2564
|
["section", new Set([
|
|
1582
2565
|
"id",
|
|
1583
2566
|
"type",
|
|
@@ -1591,6 +2574,9 @@ const itemAllowedProperties = new Map([
|
|
|
1591
2574
|
"type",
|
|
1592
2575
|
"label",
|
|
1593
2576
|
"description",
|
|
2577
|
+
"placeholder",
|
|
2578
|
+
"answer_guidelines",
|
|
2579
|
+
"reference_id",
|
|
1594
2580
|
"condition",
|
|
1595
2581
|
"validation"
|
|
1596
2582
|
])],
|
|
@@ -1599,6 +2585,9 @@ const itemAllowedProperties = new Map([
|
|
|
1599
2585
|
"type",
|
|
1600
2586
|
"label",
|
|
1601
2587
|
"description",
|
|
2588
|
+
"placeholder",
|
|
2589
|
+
"answer_guidelines",
|
|
2590
|
+
"reference_id",
|
|
1602
2591
|
"condition",
|
|
1603
2592
|
"validation"
|
|
1604
2593
|
])],
|
|
@@ -1607,6 +2596,9 @@ const itemAllowedProperties = new Map([
|
|
|
1607
2596
|
"type",
|
|
1608
2597
|
"label",
|
|
1609
2598
|
"description",
|
|
2599
|
+
"placeholder",
|
|
2600
|
+
"answer_guidelines",
|
|
2601
|
+
"reference_id",
|
|
1610
2602
|
"condition",
|
|
1611
2603
|
"validation"
|
|
1612
2604
|
])],
|
|
@@ -1615,6 +2607,9 @@ const itemAllowedProperties = new Map([
|
|
|
1615
2607
|
"type",
|
|
1616
2608
|
"label",
|
|
1617
2609
|
"description",
|
|
2610
|
+
"placeholder",
|
|
2611
|
+
"answer_guidelines",
|
|
2612
|
+
"reference_id",
|
|
1618
2613
|
"condition",
|
|
1619
2614
|
"validation"
|
|
1620
2615
|
])],
|
|
@@ -1623,6 +2618,21 @@ const itemAllowedProperties = new Map([
|
|
|
1623
2618
|
"type",
|
|
1624
2619
|
"label",
|
|
1625
2620
|
"description",
|
|
2621
|
+
"placeholder",
|
|
2622
|
+
"answer_guidelines",
|
|
2623
|
+
"reference_id",
|
|
2624
|
+
"condition",
|
|
2625
|
+
"options",
|
|
2626
|
+
"validation"
|
|
2627
|
+
])],
|
|
2628
|
+
["multiselect", new Set([
|
|
2629
|
+
"id",
|
|
2630
|
+
"type",
|
|
2631
|
+
"label",
|
|
2632
|
+
"description",
|
|
2633
|
+
"placeholder",
|
|
2634
|
+
"answer_guidelines",
|
|
2635
|
+
"reference_id",
|
|
1626
2636
|
"condition",
|
|
1627
2637
|
"options",
|
|
1628
2638
|
"validation"
|
|
@@ -1632,23 +2642,78 @@ const itemAllowedProperties = new Map([
|
|
|
1632
2642
|
"type",
|
|
1633
2643
|
"label",
|
|
1634
2644
|
"description",
|
|
2645
|
+
"placeholder",
|
|
2646
|
+
"answer_guidelines",
|
|
2647
|
+
"reference_id",
|
|
1635
2648
|
"condition",
|
|
1636
2649
|
"item",
|
|
1637
2650
|
"validation"
|
|
1638
2651
|
])],
|
|
2652
|
+
["array_obj", new Set([
|
|
2653
|
+
"id",
|
|
2654
|
+
"type",
|
|
2655
|
+
"label",
|
|
2656
|
+
"description",
|
|
2657
|
+
"placeholder",
|
|
2658
|
+
"answer_guidelines",
|
|
2659
|
+
"reference_id",
|
|
2660
|
+
"condition",
|
|
2661
|
+
"items",
|
|
2662
|
+
"kind",
|
|
2663
|
+
"validation"
|
|
2664
|
+
])],
|
|
1639
2665
|
["file", new Set([
|
|
1640
2666
|
"id",
|
|
1641
2667
|
"type",
|
|
1642
2668
|
"label",
|
|
1643
2669
|
"description",
|
|
2670
|
+
"placeholder",
|
|
2671
|
+
"answer_guidelines",
|
|
2672
|
+
"reference_id",
|
|
2673
|
+
"condition",
|
|
2674
|
+
"validation"
|
|
2675
|
+
])],
|
|
2676
|
+
["blockchain", new Set([
|
|
2677
|
+
"id",
|
|
2678
|
+
"type",
|
|
2679
|
+
"label",
|
|
2680
|
+
"description",
|
|
2681
|
+
"placeholder",
|
|
2682
|
+
"answer_guidelines",
|
|
2683
|
+
"reference_id",
|
|
2684
|
+
"condition",
|
|
2685
|
+
"validation"
|
|
2686
|
+
])],
|
|
2687
|
+
["sustainability", new Set([
|
|
2688
|
+
"id",
|
|
2689
|
+
"type",
|
|
2690
|
+
"label",
|
|
2691
|
+
"description",
|
|
2692
|
+
"placeholder",
|
|
2693
|
+
"answer_guidelines",
|
|
2694
|
+
"reference_id",
|
|
1644
2695
|
"condition",
|
|
1645
2696
|
"validation"
|
|
1646
2697
|
])],
|
|
2698
|
+
["static", new Set([
|
|
2699
|
+
"id",
|
|
2700
|
+
"type",
|
|
2701
|
+
"text",
|
|
2702
|
+
"label",
|
|
2703
|
+
"description",
|
|
2704
|
+
"placeholder",
|
|
2705
|
+
"answer_guidelines",
|
|
2706
|
+
"reference_id",
|
|
2707
|
+
"condition"
|
|
2708
|
+
])],
|
|
1647
2709
|
["section", new Set([
|
|
1648
2710
|
"id",
|
|
1649
2711
|
"type",
|
|
1650
2712
|
"title",
|
|
1651
2713
|
"description",
|
|
2714
|
+
"placeholder",
|
|
2715
|
+
"answer_guidelines",
|
|
2716
|
+
"reference_id",
|
|
1652
2717
|
"condition",
|
|
1653
2718
|
"content"
|
|
1654
2719
|
])]
|
|
@@ -1666,12 +2731,17 @@ const itemAllowedProperties = new Map([
|
|
|
1666
2731
|
* ### Semantic validation (`validate`)
|
|
1667
2732
|
* Checks for logical issues that go beyond JSON schema validity:
|
|
1668
2733
|
* 1. **Duplicate IDs** (`DUPLICATE_ID`) -- every content item id must be unique.
|
|
2734
|
+
* `array_obj` sub-field ids share that id space and are checked with it.
|
|
1669
2735
|
* 2. **Nesting depth** (`NESTING_DEPTH`) -- sections may not be nested more
|
|
1670
2736
|
* than 3 levels deep.
|
|
1671
2737
|
* 3. **Unknown field references** (`UNKNOWN_FIELD_REF`) -- conditions must
|
|
1672
2738
|
* only reference field ids that exist in the registry.
|
|
1673
|
-
* 4. **Condition references
|
|
1674
|
-
* must not reference section
|
|
2739
|
+
* 4. **Condition references a valueless item** (`CONDITION_REFS_SECTION`,
|
|
2740
|
+
* `CONDITION_REFS_STATIC`) -- conditions must not reference section or
|
|
2741
|
+
* static ids, because neither holds a value.
|
|
2742
|
+
* 4b. **Condition references an `array_obj` sub-field** (`CONDITION_REFS_ARRAY_OBJ_ITEM`)
|
|
2743
|
+
* -- a sub-field holds one value per row, so a form-level condition cannot
|
|
2744
|
+
* say which row it means.
|
|
1675
2745
|
* 5. **Constraint contradictions** (`INVALID_MIN_MAX`) -- e.g. `minLength > maxLength`,
|
|
1676
2746
|
* `min > max`, `minDate > maxDate` (absolute dates only), `minItems > maxItems`.
|
|
1677
2747
|
* 6. **Invalid regex** (`INVALID_REGEX`) -- string field `pattern` values must
|
|
@@ -1869,22 +2939,51 @@ var FormDefinitionValidator = class {
|
|
|
1869
2939
|
const issues = [];
|
|
1870
2940
|
this.checkDuplicateIds(definition.content, issues);
|
|
1871
2941
|
this.checkNestingDepth(definition.content, 0, issues);
|
|
1872
|
-
this.
|
|
1873
|
-
this.
|
|
2942
|
+
const arrayObjItemIds = this.collectArrayObjItemIds(definition.content);
|
|
2943
|
+
this.checkConditionRefsArrayObjItem(registry, arrayObjItemIds, issues);
|
|
2944
|
+
this.checkConditionRefs(registry, arrayObjItemIds, issues);
|
|
2945
|
+
this.checkConditionRefsValueless(registry, issues);
|
|
1874
2946
|
this.checkConstraintContradictions(registry, issues);
|
|
1875
2947
|
this.checkInvalidRegex(registry, issues);
|
|
1876
2948
|
return issues;
|
|
1877
2949
|
}
|
|
1878
2950
|
checkDuplicateIds(content, issues) {
|
|
1879
2951
|
const seen = /* @__PURE__ */ new Set();
|
|
1880
|
-
|
|
1881
|
-
if (seen.has(
|
|
2952
|
+
const record = (id) => {
|
|
2953
|
+
if (seen.has(id)) issues.push({
|
|
1882
2954
|
code: "DUPLICATE_ID",
|
|
1883
|
-
message: `Duplicate id: ${
|
|
1884
|
-
itemId:
|
|
2955
|
+
message: `Duplicate id: ${id}`,
|
|
2956
|
+
itemId: id
|
|
1885
2957
|
});
|
|
1886
|
-
else seen.add(
|
|
2958
|
+
else seen.add(id);
|
|
2959
|
+
};
|
|
2960
|
+
this.walkItems(content, (item) => {
|
|
2961
|
+
record(item.id);
|
|
2962
|
+
if (item.type === "array_obj") for (const subField of item.items ?? []) record(subField.id);
|
|
2963
|
+
});
|
|
2964
|
+
}
|
|
2965
|
+
collectArrayObjItemIds(content) {
|
|
2966
|
+
const ids = /* @__PURE__ */ new Map();
|
|
2967
|
+
this.walkItems(content, (item) => {
|
|
2968
|
+
if (item.type !== "array_obj") return;
|
|
2969
|
+
for (const subField of item.items ?? []) if (!ids.has(subField.id)) ids.set(subField.id, item.id);
|
|
1887
2970
|
});
|
|
2971
|
+
return ids;
|
|
2972
|
+
}
|
|
2973
|
+
checkConditionRefsArrayObjItem(registry, arrayObjItemIds, issues) {
|
|
2974
|
+
if (arrayObjItemIds.size === 0) return;
|
|
2975
|
+
for (const [id, entry] of registry) {
|
|
2976
|
+
if (!entry.condition) continue;
|
|
2977
|
+
for (const ref of DependencyGraph.extractFieldRefs(entry.condition)) {
|
|
2978
|
+
const containerId = arrayObjItemIds.get(ref);
|
|
2979
|
+
if (containerId === void 0) continue;
|
|
2980
|
+
issues.push({
|
|
2981
|
+
code: "CONDITION_REFS_ARRAY_OBJ_ITEM",
|
|
2982
|
+
message: `Condition references sub-field ${ref} of array_obj field ${containerId}, whose value is per-row and not addressable (in item ${id})`,
|
|
2983
|
+
itemId: id
|
|
2984
|
+
});
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
1888
2987
|
}
|
|
1889
2988
|
checkNestingDepth(content, depth, issues) {
|
|
1890
2989
|
for (const item of content) if (item.type === "section") if (depth >= 3) issues.push({
|
|
@@ -1894,28 +2993,37 @@ var FormDefinitionValidator = class {
|
|
|
1894
2993
|
});
|
|
1895
2994
|
else this.checkNestingDepth(item.content, depth + 1, issues);
|
|
1896
2995
|
}
|
|
1897
|
-
checkConditionRefs(registry, issues) {
|
|
2996
|
+
checkConditionRefs(registry, arrayObjItemIds, issues) {
|
|
1898
2997
|
for (const [id, entry] of registry) {
|
|
1899
2998
|
if (!entry.condition) continue;
|
|
1900
2999
|
const refs = DependencyGraph.extractFieldRefs(entry.condition);
|
|
1901
|
-
for (const ref of refs)
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
3000
|
+
for (const ref of refs) {
|
|
3001
|
+
if (arrayObjItemIds.has(ref)) continue;
|
|
3002
|
+
if (!registry.has(ref)) issues.push({
|
|
3003
|
+
code: "UNKNOWN_FIELD_REF",
|
|
3004
|
+
message: `Condition references unknown field: ${ref} (in item ${id})`,
|
|
3005
|
+
itemId: id
|
|
3006
|
+
});
|
|
3007
|
+
}
|
|
1906
3008
|
}
|
|
1907
3009
|
}
|
|
1908
|
-
|
|
3010
|
+
checkConditionRefsValueless(registry, issues) {
|
|
1909
3011
|
for (const [id, entry] of registry) {
|
|
1910
3012
|
if (!entry.condition) continue;
|
|
1911
3013
|
const refs = DependencyGraph.extractFieldRefs(entry.condition);
|
|
1912
3014
|
for (const ref of refs) {
|
|
1913
3015
|
const refEntry = registry.get(ref);
|
|
1914
|
-
if (refEntry
|
|
3016
|
+
if (!refEntry) continue;
|
|
3017
|
+
if (refEntry.type === "section") issues.push({
|
|
1915
3018
|
code: "CONDITION_REFS_SECTION",
|
|
1916
3019
|
message: `Condition references section ${ref}, which has no value (in item ${id})`,
|
|
1917
3020
|
itemId: id
|
|
1918
3021
|
});
|
|
3022
|
+
if (refEntry.type === "static") issues.push({
|
|
3023
|
+
code: "CONDITION_REFS_STATIC",
|
|
3024
|
+
message: `Condition references static field ${ref}, which has no value (in item ${id})`,
|
|
3025
|
+
itemId: id
|
|
3026
|
+
});
|
|
1919
3027
|
}
|
|
1920
3028
|
}
|
|
1921
3029
|
}
|
|
@@ -1956,7 +3064,8 @@ var FormDefinitionValidator = class {
|
|
|
1956
3064
|
}
|
|
1957
3065
|
break;
|
|
1958
3066
|
}
|
|
1959
|
-
case "array":
|
|
3067
|
+
case "array":
|
|
3068
|
+
case "array_obj": {
|
|
1960
3069
|
const v = entry.validation;
|
|
1961
3070
|
if (v.minItems !== void 0 && v.maxItems !== void 0 && v.maxItems < v.minItems) issues.push({
|
|
1962
3071
|
code: "INVALID_MIN_MAX",
|
|
@@ -2042,6 +3151,7 @@ var VisibilityResolver = class {
|
|
|
2042
3151
|
registry;
|
|
2043
3152
|
conditionEvaluator;
|
|
2044
3153
|
topologicalOrder;
|
|
3154
|
+
fieldTypes;
|
|
2045
3155
|
/**
|
|
2046
3156
|
* @param registry - The engine's field registry.
|
|
2047
3157
|
* @param conditionEvaluator - Evaluator for condition trees.
|
|
@@ -2051,6 +3161,7 @@ var VisibilityResolver = class {
|
|
|
2051
3161
|
this.registry = registry;
|
|
2052
3162
|
this.conditionEvaluator = conditionEvaluator;
|
|
2053
3163
|
this.topologicalOrder = topologicalOrder;
|
|
3164
|
+
this.fieldTypes = new Map([...registry].map(([id, entry]) => [id, entry.type]));
|
|
2054
3165
|
}
|
|
2055
3166
|
/**
|
|
2056
3167
|
* Determines whether a single field or section is visible.
|
|
@@ -2077,7 +3188,8 @@ var VisibilityResolver = class {
|
|
|
2077
3188
|
if (entry.condition) {
|
|
2078
3189
|
if (!this.conditionEvaluator.evalCondition(entry.condition, {
|
|
2079
3190
|
values,
|
|
2080
|
-
now
|
|
3191
|
+
now,
|
|
3192
|
+
fieldTypes: this.fieldTypes
|
|
2081
3193
|
})) return false;
|
|
2082
3194
|
}
|
|
2083
3195
|
if (entry.parentId !== void 0) return this.isVisible(entry.parentId, values, now);
|
|
@@ -2115,7 +3227,8 @@ var VisibilityResolver = class {
|
|
|
2115
3227
|
const visible = this.conditionEvaluator.evalCondition(entry.condition, {
|
|
2116
3228
|
values,
|
|
2117
3229
|
visibilityMap: result,
|
|
2118
|
-
now
|
|
3230
|
+
now,
|
|
3231
|
+
fieldTypes: this.fieldTypes
|
|
2119
3232
|
});
|
|
2120
3233
|
result.set(id, visible);
|
|
2121
3234
|
} else result.set(id, true);
|
|
@@ -2382,14 +3495,16 @@ var FormEngine = class FormEngine {
|
|
|
2382
3495
|
}
|
|
2383
3496
|
static walkContent(content, parentId, registry, contentOrder) {
|
|
2384
3497
|
for (const item of content) {
|
|
3498
|
+
const isValueField = item.type !== "section" && item.type !== "static";
|
|
2385
3499
|
const entry = {
|
|
2386
3500
|
id: item.id,
|
|
2387
3501
|
type: item.type,
|
|
2388
3502
|
condition: item.condition,
|
|
2389
|
-
validation:
|
|
3503
|
+
validation: isValueField ? item.validation : void 0,
|
|
2390
3504
|
parentId,
|
|
2391
|
-
options: item.type === "select" ? item.options : void 0,
|
|
3505
|
+
options: item.type === "select" || item.type === "multiselect" ? item.options : void 0,
|
|
2392
3506
|
item: item.type === "array" ? item.item : void 0,
|
|
3507
|
+
items: item.type === "array_obj" ? item.items : void 0,
|
|
2393
3508
|
label: item.type !== "section" ? item.label : void 0,
|
|
2394
3509
|
title: item.type === "section" ? item.title : void 0
|
|
2395
3510
|
};
|
|
@@ -2400,6 +3515,108 @@ var FormEngine = class FormEngine {
|
|
|
2400
3515
|
}
|
|
2401
3516
|
};
|
|
2402
3517
|
//#endregion
|
|
3518
|
+
//#region src/suggestions.ts
|
|
3519
|
+
/**
|
|
3520
|
+
* Pure helpers for reading and writing the `suggestions` block of a
|
|
3521
|
+
* {@link FormDocument}.
|
|
3522
|
+
*
|
|
3523
|
+
* Every function is total over legacy documents: `doc.suggestions` may be
|
|
3524
|
+
* `undefined` (documents written before suggestions existed) and each helper
|
|
3525
|
+
* treats that as "no suggestions". Writers never mutate their input -- they
|
|
3526
|
+
* return a new document -- and they drop the `suggestions` key entirely once it
|
|
3527
|
+
* would be empty, so a document that never had suggestions round-trips
|
|
3528
|
+
* unchanged.
|
|
3529
|
+
*
|
|
3530
|
+
* These helpers deliberately do **not** check that `fieldId` refers to an
|
|
3531
|
+
* existing, non-section field. That check belongs to the general-purpose
|
|
3532
|
+
* authoring API ({@link FormValuesEditor}); callers that already resolved a
|
|
3533
|
+
* field -- such as the viewer's render loop -- would only pay for it twice.
|
|
3534
|
+
*/
|
|
3535
|
+
/**
|
|
3536
|
+
* Returns the suggestion recorded for a field.
|
|
3537
|
+
*
|
|
3538
|
+
* @param doc - The form document to read from.
|
|
3539
|
+
* @param fieldId - Numeric id of the field.
|
|
3540
|
+
* @returns The suggestion, or `undefined` when the field has none.
|
|
3541
|
+
*/
|
|
3542
|
+
const getSuggestion = (doc, fieldId) => doc.suggestions?.[String(fieldId)];
|
|
3543
|
+
/**
|
|
3544
|
+
* Records a suggestion for a field, replacing any existing one.
|
|
3545
|
+
*
|
|
3546
|
+
* @param doc - The form document to update.
|
|
3547
|
+
* @param fieldId - Numeric id of the field.
|
|
3548
|
+
* @param suggestion - The suggestion to store. Deep-copied before storing.
|
|
3549
|
+
* @returns A new document carrying the suggestion.
|
|
3550
|
+
* @throws If `confidence` is not a finite number within `0..1`.
|
|
3551
|
+
*/
|
|
3552
|
+
const setSuggestion = (doc, fieldId, suggestion) => {
|
|
3553
|
+
const { confidence } = suggestion;
|
|
3554
|
+
if (!Number.isFinite(confidence) || confidence < 0 || confidence > 1) throw new Error(`Suggestion confidence must be a number between 0 and 1, received ${confidence}`);
|
|
3555
|
+
return {
|
|
3556
|
+
...doc,
|
|
3557
|
+
suggestions: {
|
|
3558
|
+
...doc.suggestions,
|
|
3559
|
+
[String(fieldId)]: deepCopy(suggestion)
|
|
3560
|
+
}
|
|
3561
|
+
};
|
|
3562
|
+
};
|
|
3563
|
+
/**
|
|
3564
|
+
* Removes the suggestion recorded for a field, leaving the field's value alone.
|
|
3565
|
+
*
|
|
3566
|
+
* When the removed entry was the last one, the `suggestions` key is dropped
|
|
3567
|
+
* from the document rather than left as an empty object.
|
|
3568
|
+
*
|
|
3569
|
+
* @param doc - The form document to update.
|
|
3570
|
+
* @param fieldId - Numeric id of the field.
|
|
3571
|
+
* @returns A new document without that suggestion, or `doc` itself when there
|
|
3572
|
+
* was nothing to remove.
|
|
3573
|
+
*/
|
|
3574
|
+
const removeSuggestion = (doc, fieldId) => {
|
|
3575
|
+
const key = String(fieldId);
|
|
3576
|
+
if (!doc.suggestions || !(key in doc.suggestions)) return doc;
|
|
3577
|
+
const { [key]: _removed, ...rest } = doc.suggestions;
|
|
3578
|
+
if (Object.keys(rest).length === 0) {
|
|
3579
|
+
const { suggestions: _dropped, ...withoutSuggestions } = doc;
|
|
3580
|
+
return withoutSuggestions;
|
|
3581
|
+
}
|
|
3582
|
+
return {
|
|
3583
|
+
...doc,
|
|
3584
|
+
suggestions: rest
|
|
3585
|
+
};
|
|
3586
|
+
};
|
|
3587
|
+
/**
|
|
3588
|
+
* Copies a field's suggested value into the document's values, keeping the
|
|
3589
|
+
* suggestion in place so the origin of the answer stays visible.
|
|
3590
|
+
*
|
|
3591
|
+
* The value is deep-copied: array and object suggestions must not become
|
|
3592
|
+
* aliases of the stored value, or later in-place edits (e.g. appending an array
|
|
3593
|
+
* item) would silently rewrite the suggestion too.
|
|
3594
|
+
*
|
|
3595
|
+
* @param doc - The form document to update.
|
|
3596
|
+
* @param fieldId - Numeric id of the field.
|
|
3597
|
+
* @returns A new document with the value applied, or `doc` itself when the
|
|
3598
|
+
* field has no suggestion.
|
|
3599
|
+
*/
|
|
3600
|
+
const applySuggestion = (doc, fieldId) => {
|
|
3601
|
+
const suggestion = getSuggestion(doc, fieldId);
|
|
3602
|
+
if (!suggestion) return doc;
|
|
3603
|
+
return {
|
|
3604
|
+
...doc,
|
|
3605
|
+
values: {
|
|
3606
|
+
...doc.values,
|
|
3607
|
+
[String(fieldId)]: deepCopy(suggestion.value)
|
|
3608
|
+
}
|
|
3609
|
+
};
|
|
3610
|
+
};
|
|
3611
|
+
/**
|
|
3612
|
+
* Returns all suggestions on a document as a plain object, never `undefined`.
|
|
3613
|
+
*
|
|
3614
|
+
* @param doc - The form document to read from.
|
|
3615
|
+
* @returns A copy of the suggestions map. Empty when the document has none.
|
|
3616
|
+
*/
|
|
3617
|
+
const getSuggestions = (doc) => ({ ...doc.suggestions });
|
|
3618
|
+
const deepCopy = (value) => value === void 0 ? value : JSON.parse(JSON.stringify(value));
|
|
3619
|
+
//#endregion
|
|
2403
3620
|
//#region src/form-values-editor.ts
|
|
2404
3621
|
/**
|
|
2405
3622
|
* Mutable editor for building and modifying form values against a {@link FormDefinition}.
|
|
@@ -2471,13 +3688,16 @@ var FormValuesEditor = class {
|
|
|
2471
3688
|
* If the field currently has no value, it is initialized to an empty array
|
|
2472
3689
|
* before appending.
|
|
2473
3690
|
*
|
|
2474
|
-
* @param fieldId - Numeric id of the array field.
|
|
2475
|
-
* @param value - The value to append. Defaults to `undefined
|
|
3691
|
+
* @param fieldId - Numeric id of the `array` or `array_obj` field.
|
|
3692
|
+
* @param value - The value to append. Defaults to `undefined` for an
|
|
3693
|
+
* `array` field and to an empty row (`{}`) for an `array_obj` field.
|
|
2476
3694
|
* @returns `this` for chaining.
|
|
2477
3695
|
* @throws If `fieldId` is not an array field.
|
|
2478
3696
|
*/
|
|
2479
3697
|
addArrayItem(fieldId, value) {
|
|
2480
|
-
this.getOrInitArray(fieldId)
|
|
3698
|
+
const arr = this.getOrInitArray(fieldId);
|
|
3699
|
+
const entry = this.engine.getFieldDef(fieldId);
|
|
3700
|
+
arr.push(value === void 0 && entry?.type === "array_obj" ? {} : value);
|
|
2481
3701
|
return this;
|
|
2482
3702
|
}
|
|
2483
3703
|
/**
|
|
@@ -2527,6 +3747,114 @@ var FormValuesEditor = class {
|
|
|
2527
3747
|
return this;
|
|
2528
3748
|
}
|
|
2529
3749
|
/**
|
|
3750
|
+
* Returns the value of one sub-field within one row of an `array_obj` field.
|
|
3751
|
+
*
|
|
3752
|
+
* @param fieldId - Numeric id of the `array_obj` field.
|
|
3753
|
+
* @param index - Zero-based row index.
|
|
3754
|
+
* @param subFieldId - Numeric id of the sub-field.
|
|
3755
|
+
* @returns The sub-field value, or `undefined` if not set.
|
|
3756
|
+
* @throws If the field is not an `array_obj`, the row index is out of
|
|
3757
|
+
* bounds, or the sub-field does not belong to the field.
|
|
3758
|
+
*/
|
|
3759
|
+
getArrayObjValue(fieldId, index, subFieldId) {
|
|
3760
|
+
return this.assertArrayObjRow(fieldId, index, subFieldId)[String(subFieldId)];
|
|
3761
|
+
}
|
|
3762
|
+
/**
|
|
3763
|
+
* Sets the value of one sub-field within one row of an `array_obj` field.
|
|
3764
|
+
*
|
|
3765
|
+
* @param fieldId - Numeric id of the `array_obj` field.
|
|
3766
|
+
* @param index - Zero-based row index.
|
|
3767
|
+
* @param subFieldId - Numeric id of the sub-field.
|
|
3768
|
+
* @param value - The value to set.
|
|
3769
|
+
* @returns `this` for chaining.
|
|
3770
|
+
* @throws If the field is not an `array_obj`, the row index is out of
|
|
3771
|
+
* bounds, or the sub-field does not belong to the field or is static.
|
|
3772
|
+
*/
|
|
3773
|
+
setArrayObjValue(fieldId, index, subFieldId, value) {
|
|
3774
|
+
this.assertArrayObjRow(fieldId, index, subFieldId)[String(subFieldId)] = value;
|
|
3775
|
+
return this;
|
|
3776
|
+
}
|
|
3777
|
+
/**
|
|
3778
|
+
* Removes one sub-field's value from one row of an `array_obj` field.
|
|
3779
|
+
*
|
|
3780
|
+
* @returns `this` for chaining.
|
|
3781
|
+
* @throws Under the same conditions as {@link setArrayObjValue}.
|
|
3782
|
+
*/
|
|
3783
|
+
clearArrayObjValue(fieldId, index, subFieldId) {
|
|
3784
|
+
delete this.assertArrayObjRow(fieldId, index, subFieldId)[String(subFieldId)];
|
|
3785
|
+
return this;
|
|
3786
|
+
}
|
|
3787
|
+
/**
|
|
3788
|
+
* Returns the suggestion recorded for a field.
|
|
3789
|
+
*
|
|
3790
|
+
* @param fieldId - Numeric id of the field.
|
|
3791
|
+
* @returns The suggestion, or `undefined` if the field has none.
|
|
3792
|
+
*/
|
|
3793
|
+
getSuggestion(fieldId) {
|
|
3794
|
+
return getSuggestion(this.doc, fieldId);
|
|
3795
|
+
}
|
|
3796
|
+
/**
|
|
3797
|
+
* Returns every suggestion on the document, keyed by stringified field id.
|
|
3798
|
+
*
|
|
3799
|
+
* @returns A copy of the suggestions map. Empty when there are none.
|
|
3800
|
+
*/
|
|
3801
|
+
getSuggestions() {
|
|
3802
|
+
return getSuggestions(this.doc);
|
|
3803
|
+
}
|
|
3804
|
+
/**
|
|
3805
|
+
* Records a suggestion for a field, replacing any existing one. The field's
|
|
3806
|
+
* value is left untouched.
|
|
3807
|
+
*
|
|
3808
|
+
* @param fieldId - Numeric id of the field.
|
|
3809
|
+
* @param suggestion - The suggestion to store.
|
|
3810
|
+
* @returns `this` for chaining.
|
|
3811
|
+
* @throws If `fieldId` is unknown, references a section, or `confidence`
|
|
3812
|
+
* falls outside `0..1`.
|
|
3813
|
+
*/
|
|
3814
|
+
setSuggestion(fieldId, suggestion) {
|
|
3815
|
+
this.assertField(fieldId);
|
|
3816
|
+
this.doc = setSuggestion(this.doc, fieldId, suggestion);
|
|
3817
|
+
return this;
|
|
3818
|
+
}
|
|
3819
|
+
/**
|
|
3820
|
+
* Removes the suggestion recorded for a field, leaving its value untouched.
|
|
3821
|
+
*
|
|
3822
|
+
* @param fieldId - Numeric id of the field.
|
|
3823
|
+
* @returns `this` for chaining.
|
|
3824
|
+
*/
|
|
3825
|
+
clearSuggestion(fieldId) {
|
|
3826
|
+
this.doc = removeSuggestion(this.doc, fieldId);
|
|
3827
|
+
return this;
|
|
3828
|
+
}
|
|
3829
|
+
/**
|
|
3830
|
+
* Accepts a field's suggestion: copies the suggested value into the field's
|
|
3831
|
+
* value and **keeps** the suggestion, so its source stays visible.
|
|
3832
|
+
*
|
|
3833
|
+
* No-op when the field has no suggestion.
|
|
3834
|
+
*
|
|
3835
|
+
* @param fieldId - Numeric id of the field.
|
|
3836
|
+
* @returns `this` for chaining.
|
|
3837
|
+
* @throws If `fieldId` is unknown or references a section.
|
|
3838
|
+
*/
|
|
3839
|
+
acceptSuggestion(fieldId) {
|
|
3840
|
+
this.assertField(fieldId);
|
|
3841
|
+
this.doc = applySuggestion(this.doc, fieldId);
|
|
3842
|
+
return this;
|
|
3843
|
+
}
|
|
3844
|
+
/**
|
|
3845
|
+
* Rejects a field's suggestion: removes it entirely, leaving the field's
|
|
3846
|
+
* value untouched.
|
|
3847
|
+
*
|
|
3848
|
+
* No-op when the field has no suggestion.
|
|
3849
|
+
*
|
|
3850
|
+
* @param fieldId - Numeric id of the field.
|
|
3851
|
+
* @returns `this` for chaining.
|
|
3852
|
+
*/
|
|
3853
|
+
rejectSuggestion(fieldId) {
|
|
3854
|
+
this.doc = removeSuggestion(this.doc, fieldId);
|
|
3855
|
+
return this;
|
|
3856
|
+
}
|
|
3857
|
+
/**
|
|
2530
3858
|
* Sets the `submittedAt` timestamp on the document.
|
|
2531
3859
|
*
|
|
2532
3860
|
* @param submittedAt - ISO 8601 timestamp string.
|
|
@@ -2582,6 +3910,7 @@ var FormValuesEditor = class {
|
|
|
2582
3910
|
const entry = this.engine.getFieldDef(fieldId);
|
|
2583
3911
|
if (!entry) throw new Error(`Field with id ${fieldId} not found`);
|
|
2584
3912
|
if (entry.type === "section") throw new Error(`Item ${fieldId} is a section, not a field`);
|
|
3913
|
+
if (entry.type === "static") throw new Error(`Item ${fieldId} is a static field and holds no value`);
|
|
2585
3914
|
}
|
|
2586
3915
|
/**
|
|
2587
3916
|
* Asserts that `fieldId` is an array field and returns the current array value.
|
|
@@ -2590,7 +3919,7 @@ var FormValuesEditor = class {
|
|
|
2590
3919
|
assertArray(fieldId) {
|
|
2591
3920
|
const entry = this.engine.getFieldDef(fieldId);
|
|
2592
3921
|
if (!entry) throw new Error(`Field with id ${fieldId} not found`);
|
|
2593
|
-
if (entry.type !== "array") throw new Error(`Field ${fieldId} is not an array field`);
|
|
3922
|
+
if (entry.type !== "array" && entry.type !== "array_obj") throw new Error(`Field ${fieldId} is not an array field`);
|
|
2594
3923
|
const val = this.doc.values[String(fieldId)];
|
|
2595
3924
|
if (!Array.isArray(val)) throw new Error(`Field ${fieldId} does not currently hold an array value`);
|
|
2596
3925
|
return val;
|
|
@@ -2601,7 +3930,7 @@ var FormValuesEditor = class {
|
|
|
2601
3930
|
getOrInitArray(fieldId) {
|
|
2602
3931
|
const entry = this.engine.getFieldDef(fieldId);
|
|
2603
3932
|
if (!entry) throw new Error(`Field with id ${fieldId} not found`);
|
|
2604
|
-
if (entry.type !== "array") throw new Error(`Field ${fieldId} is not an array field`);
|
|
3933
|
+
if (entry.type !== "array" && entry.type !== "array_obj") throw new Error(`Field ${fieldId} is not an array field`);
|
|
2605
3934
|
const key = String(fieldId);
|
|
2606
3935
|
let val = this.doc.values[key];
|
|
2607
3936
|
if (!Array.isArray(val)) {
|
|
@@ -2610,6 +3939,26 @@ var FormValuesEditor = class {
|
|
|
2610
3939
|
}
|
|
2611
3940
|
return val;
|
|
2612
3941
|
}
|
|
3942
|
+
/**
|
|
3943
|
+
* Asserts that `fieldId` is an `array_obj` field holding a row at `index`
|
|
3944
|
+
* with a writable sub-field `subFieldId`, and returns that row.
|
|
3945
|
+
* The row is created in place when it is absent or not an object.
|
|
3946
|
+
*/
|
|
3947
|
+
assertArrayObjRow(fieldId, index, subFieldId) {
|
|
3948
|
+
const entry = this.engine.getFieldDef(fieldId);
|
|
3949
|
+
if (!entry) throw new Error(`Field with id ${fieldId} not found`);
|
|
3950
|
+
if (entry.type !== "array_obj") throw new Error(`Field ${fieldId} is not an array_obj field`);
|
|
3951
|
+
const subField = (entry.items ?? []).find((f) => f.id === subFieldId);
|
|
3952
|
+
if (!subField) throw new Error(`Sub-field ${subFieldId} does not belong to field ${fieldId}`);
|
|
3953
|
+
if (subField.type === "static") throw new Error(`Sub-field ${subFieldId} is a static field and holds no value`);
|
|
3954
|
+
const arr = this.assertArray(fieldId);
|
|
3955
|
+
if (index < 0 || index >= arr.length) throw new Error(`Index ${index} is out of bounds for array field ${fieldId} (length ${arr.length})`);
|
|
3956
|
+
const row = arr[index];
|
|
3957
|
+
if (typeof row === "object" && row !== null && !Array.isArray(row)) return row;
|
|
3958
|
+
const created = {};
|
|
3959
|
+
arr[index] = created;
|
|
3960
|
+
return created;
|
|
3961
|
+
}
|
|
2613
3962
|
};
|
|
2614
3963
|
//#endregion
|
|
2615
3964
|
exports.ConditionEvaluator = ConditionEvaluator;
|
|
@@ -2621,3 +3970,8 @@ exports.FormDefinitionValidator = FormDefinitionValidator;
|
|
|
2621
3970
|
exports.FormEngine = FormEngine;
|
|
2622
3971
|
exports.FormValuesEditor = FormValuesEditor;
|
|
2623
3972
|
exports.VisibilityResolver = VisibilityResolver;
|
|
3973
|
+
exports.applySuggestion = applySuggestion;
|
|
3974
|
+
exports.getSuggestion = getSuggestion;
|
|
3975
|
+
exports.getSuggestions = getSuggestions;
|
|
3976
|
+
exports.removeSuggestion = removeSuggestion;
|
|
3977
|
+
exports.setSuggestion = setSuggestion;
|