@f1studio/form-spec 5.0.0-alpha.117 → 5.0.0-alpha.121

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.
Files changed (31) hide show
  1. package/FormSpec.FS/BlueprintValidation.d.ts +1 -1
  2. package/FormSpec.FS/BlueprintValidation.d.ts.map +1 -1
  3. package/FormSpec.FS/Interop/FormSpec.Api.Helpers.d.ts +16 -0
  4. package/FormSpec.FS/Interop/FormSpec.Api.Helpers.d.ts.map +1 -1
  5. package/FormSpec.FS/Validation/Validation.FilledForm.d.ts +31 -0
  6. package/FormSpec.FS/Validation/Validation.FilledForm.d.ts.map +1 -0
  7. package/FormSpec.FS/Validation/ValidationTypes.d.ts +12 -0
  8. package/FormSpec.FS/Validation/ValidationTypes.d.ts.map +1 -0
  9. package/FormSpec.TS/FormSpec.FS/BlueprintValidation.js +45 -62
  10. package/FormSpec.TS/FormSpec.FS/BlueprintValidation.js.map +1 -1
  11. package/FormSpec.TS/FormSpec.FS/BlueprintValidation.ts.map +1 -1
  12. package/FormSpec.TS/FormSpec.FS/Interop/FormSpec.Api.Helpers.js +19 -0
  13. package/FormSpec.TS/FormSpec.FS/Interop/FormSpec.Api.Helpers.js.map +1 -1
  14. package/FormSpec.TS/FormSpec.FS/Interop/FormSpec.Api.Helpers.ts.map +1 -1
  15. package/FormSpec.TS/FormSpec.FS/Interop/PluginPropertyKeyRegistry.js.map +1 -1
  16. package/FormSpec.TS/FormSpec.FS/Interop/PluginPropertyKeyRegistry.ts.map +1 -1
  17. package/FormSpec.TS/FormSpec.FS/Validation/Validation.FilledForm.js +148 -0
  18. package/FormSpec.TS/FormSpec.FS/Validation/Validation.FilledForm.js.map +1 -0
  19. package/FormSpec.TS/FormSpec.FS/Validation/Validation.FilledForm.ts.map +1 -0
  20. package/FormSpec.TS/FormSpec.FS/Validation/ValidationTypes.js +51 -0
  21. package/FormSpec.TS/FormSpec.FS/Validation/ValidationTypes.js.map +1 -0
  22. package/FormSpec.TS/FormSpec.FS/Validation/ValidationTypes.ts.map +1 -0
  23. package/FormSpec.TS/fable_modules/Thoth.Json.10.4.1/Encode.fs.js.map +1 -1
  24. package/FormSpec.TS/fable_modules/Thoth.Json.10.4.1/Encode.fs.ts.map +1 -1
  25. package/FormSpec.TS/fable_modules/project_cracked.json +1 -1
  26. package/README.md +10 -8
  27. package/package.json +1 -1
  28. package/src/FormSpec.FS/BlueprintValidation.ts +43 -61
  29. package/src/FormSpec.FS/Interop/FormSpec.Api.Helpers.ts +42 -9
  30. package/src/FormSpec.FS/Validation/Validation.FilledForm.ts +158 -0
  31. package/src/FormSpec.FS/Validation/ValidationTypes.ts +23 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@f1studio/form-spec",
3
- "version": "5.0.0-alpha.117",
3
+ "version": "5.0.0-alpha.121",
4
4
  "description": "F1 Core - Form specification and types",
5
5
  "main": "./FormSpec.TS/FormSpec.FS/Interop/FormSpec.Api.Option.js",
6
6
  "types": "./FormSpec.FS/Interop/FormSpec.Api.Option.d.ts",
@@ -1,10 +1,12 @@
1
+ import { Blueprint_validateBlueprint } from "./Validation/Validation.FilledForm.js";
2
+ import { FSharpResult$2_Error, FSharpResult$2_Ok, FSharpResult$2_$union } from "@fable-org/fable-library-js/Result.js";
3
+ import { tryHead, map, append, isEmpty, choose, collect, empty, singleton, FSharpList } from "@fable-org/fable-library-js/List.js";
4
+ import { ValidationError } from "./Validation/ValidationTypes.js";
1
5
  import { printf, toText, isNullOrWhiteSpace } from "@fable-org/fable-library-js/String.js";
2
- import { value as value_2, Option, map, defaultArg } from "@fable-org/fable-library-js/Option.js";
3
6
  import { isMatch } from "@fable-org/fable-library-js/RegExp.js";
4
- import { map as map_1, empty, singleton, append, FSharpList, choose, collect, tryPick, tryFind, isEmpty } from "@fable-org/fable-library-js/List.js";
5
- import { Spec_FormSpec$1, Spec_MatrixInfo, Spec_MultiChoiceInfo, Spec_SingleChoiceInfo, Spec_FormField$1, Spec_FieldType_$union, Spec_FormStep$1 } from "./FormSpec.js";
6
7
  import { int32 } from "@fable-org/fable-library-js/Int32.js";
7
- import { FSharpResult$2_$union, FSharpResult$2_Ok, FSharpResult$2_Error } from "@fable-org/fable-library-js/Result.js";
8
+ import { Spec_FormSpec$1, Spec_MatrixInfo, Spec_FormStep$1, Spec_MultiChoiceInfo, Spec_SingleChoiceInfo, Spec_FieldType_$union, Spec_FormField$1 } from "./FormSpec.js";
9
+ import { map as map_1, defaultArg, Option } from "@fable-org/fable-library-js/Option.js";
8
10
  import { FSharpMap, empty as empty_1, add } from "@fable-org/fable-library-js/Map.js";
9
11
  import { Auto_generateBoxedEncoder_437914C6, toString } from "../fable_modules/Thoth.Json.10.4.1/Encode.fs.js";
10
12
  import { list_type, string_type } from "@fable-org/fable-library-js/Reflection.js";
@@ -20,75 +22,55 @@ const semverRegex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(
20
22
  * Returns Ok ((), warnings) or Error msg.
21
23
  */
22
24
  export function validateBlueprintForSave(spec: Spec_FormSpec$1<Spec_FieldType_$union>, relaxForImport: boolean): FSharpResult$2_$union<[void, FSharpList<string>], string> {
23
- const hasTitle: boolean = !isNullOrWhiteSpace(spec.Title);
24
- const hasCode: boolean = defaultArg(map<string, boolean>((c: string): boolean => !isNullOrWhiteSpace(c), spec.Code), false);
25
- const version: string = (spec.Version == null) ? "" : spec.Version.trim();
26
- const hasVersion: boolean = !isNullOrWhiteSpace(version);
27
- const isSemver: boolean = hasVersion && isMatch(semverRegex, version);
28
- const hasSteps: boolean = !isEmpty(spec.Steps);
29
- const blankStepLabel: Option<int32> = map<Spec_FormStep$1<Spec_FieldType_$union>, int32>((step_1: Spec_FormStep$1<Spec_FieldType_$union>): int32 => step_1.StepOrder, tryFind<Spec_FormStep$1<Spec_FieldType_$union>>((step: Spec_FormStep$1<Spec_FieldType_$union>): boolean => isNullOrWhiteSpace(step.StepLabel), spec.Steps));
30
- const blankFieldLabel: Option<[int32, int32]> = tryPick<Spec_FormStep$1<Spec_FieldType_$union>, [int32, int32]>((step_2: Spec_FormStep$1<Spec_FieldType_$union>): Option<[int32, int32]> => map<Spec_FormField$1<Spec_FieldType_$union>, [int32, int32]>((field_1: Spec_FormField$1<Spec_FieldType_$union>): [int32, int32] => ([step_2.StepOrder, field_1.FieldOrder] as [int32, int32]), tryFind<Spec_FormField$1<Spec_FieldType_$union>>((field: Spec_FormField$1<Spec_FieldType_$union>): boolean => isNullOrWhiteSpace(field.Label), step_2.Fields)), spec.Steps);
31
- const invalidOptionsFields: FSharpList<[int32, int32, string]> = collect<Spec_FormStep$1<Spec_FieldType_$union>, [int32, int32, string]>((step_3: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<[int32, int32, string]> => choose<Spec_FormField$1<Spec_FieldType_$union>, [int32, int32, string]>((field_2: Spec_FormField$1<Spec_FieldType_$union>): Option<[int32, int32, string]> => {
32
- let matchValue: Spec_FieldType_$union, matchValue_1: Spec_FieldType_$union, info: Spec_SingleChoiceInfo, info_1: Spec_MultiChoiceInfo;
33
- if (((matchValue = field_2.FieldType, (matchValue.tag === /* Radio */ 12) ? true : ((matchValue.tag === /* SingleChoice */ 13) ? true : ((matchValue.tag === /* Dropdown */ 14) ? true : ((matchValue.tag === /* MultiChoice */ 15) ? true : ((matchValue.tag === /* CheckboxList */ 16) ? true : ((matchValue.tag === /* TagList */ 17) ? true : ((matchValue.tag === /* TextAutoComplete */ 18) ? true : (matchValue.tag === /* Matrix */ 19))))))))) && !((matchValue_1 = field_2.FieldType, (matchValue_1.tag === /* Radio */ 12) ? ((info = matchValue_1.fields[0], !isEmpty(info.Options))) : ((matchValue_1.tag === /* SingleChoice */ 13) ? ((info = matchValue_1.fields[0], !isEmpty(info.Options))) : ((matchValue_1.tag === /* Dropdown */ 14) ? ((info = matchValue_1.fields[0], !isEmpty(info.Options))) : ((matchValue_1.tag === /* TextAutoComplete */ 18) ? ((info = matchValue_1.fields[0], !isEmpty(info.Options))) : ((matchValue_1.tag === /* MultiChoice */ 15) ? ((info_1 = matchValue_1.fields[0], !isEmpty(info_1.Options))) : ((matchValue_1.tag === /* CheckboxList */ 16) ? ((info_1 = matchValue_1.fields[0], !isEmpty(info_1.Options))) : ((matchValue_1.tag === /* TagList */ 17) ? ((info_1 = matchValue_1.fields[0], !isEmpty(info_1.Options))) : ((matchValue_1.tag === /* Matrix */ 19) ? !isEmpty(matchValue_1.fields[0].Options) : true)))))))))) {
34
- return [step_3.StepOrder, field_2.FieldOrder, field_2.Label] as [int32, int32, string];
35
- }
36
- else {
37
- return undefined;
38
- }
39
- }, step_3.Fields), spec.Steps);
40
- const invalidMatrixItemsFields: FSharpList<[int32, int32, string]> = collect<Spec_FormStep$1<Spec_FieldType_$union>, [int32, int32, string]>((step_4: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<[int32, int32, string]> => choose<Spec_FormField$1<Spec_FieldType_$union>, [int32, int32, string]>((field_3: Spec_FormField$1<Spec_FieldType_$union>): Option<[int32, int32, string]> => {
41
- const matchValue_2: Spec_FieldType_$union = field_3.FieldType;
42
- let matchResult: int32, info_4: Spec_MatrixInfo;
43
- if (matchValue_2.tag === /* Matrix */ 19) {
44
- if (isEmpty(matchValue_2.fields[0].Items)) {
45
- matchResult = 0;
46
- info_4 = matchValue_2.fields[0];
25
+ const matchValue: FSharpResult$2_$union<void, FSharpList<ValidationError>> = Blueprint_validateBlueprint(spec, relaxForImport);
26
+ if (matchValue.tag === /* Ok */ 0) {
27
+ const version: string = (spec.Version == null) ? "" : spec.Version.trim();
28
+ const hasVersion: boolean = !isNullOrWhiteSpace(version);
29
+ const semverWarning: FSharpList<string> = (hasVersion && !(hasVersion && isMatch(semverRegex, version))) ? singleton("Version should be valid semver (e.g. 1.0.0) for lineage") : empty<string>();
30
+ const invalidOptionsFields: FSharpList<[int32, int32, string]> = collect<Spec_FormStep$1<Spec_FieldType_$union>, [int32, int32, string]>((step: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<[int32, int32, string]> => choose<Spec_FormField$1<Spec_FieldType_$union>, [int32, int32, string]>((field: Spec_FormField$1<Spec_FieldType_$union>): Option<[int32, int32, string]> => {
31
+ let matchValue_1: Spec_FieldType_$union, matchValue_2: Spec_FieldType_$union, info: Spec_SingleChoiceInfo, info_1: Spec_MultiChoiceInfo;
32
+ if (((matchValue_1 = field.FieldType, (matchValue_1.tag === /* Radio */ 12) ? true : ((matchValue_1.tag === /* SingleChoice */ 13) ? true : ((matchValue_1.tag === /* Dropdown */ 14) ? true : ((matchValue_1.tag === /* MultiChoice */ 15) ? true : ((matchValue_1.tag === /* CheckboxList */ 16) ? true : ((matchValue_1.tag === /* TagList */ 17) ? true : ((matchValue_1.tag === /* TextAutoComplete */ 18) ? true : (matchValue_1.tag === /* Matrix */ 19))))))))) && !((matchValue_2 = field.FieldType, (matchValue_2.tag === /* Radio */ 12) ? ((info = matchValue_2.fields[0], !isEmpty(info.Options))) : ((matchValue_2.tag === /* SingleChoice */ 13) ? ((info = matchValue_2.fields[0], !isEmpty(info.Options))) : ((matchValue_2.tag === /* Dropdown */ 14) ? ((info = matchValue_2.fields[0], !isEmpty(info.Options))) : ((matchValue_2.tag === /* TextAutoComplete */ 18) ? ((info = matchValue_2.fields[0], !isEmpty(info.Options))) : ((matchValue_2.tag === /* MultiChoice */ 15) ? ((info_1 = matchValue_2.fields[0], !isEmpty(info_1.Options))) : ((matchValue_2.tag === /* CheckboxList */ 16) ? ((info_1 = matchValue_2.fields[0], !isEmpty(info_1.Options))) : ((matchValue_2.tag === /* TagList */ 17) ? ((info_1 = matchValue_2.fields[0], !isEmpty(info_1.Options))) : ((matchValue_2.tag === /* Matrix */ 19) ? !isEmpty(matchValue_2.fields[0].Options) : true)))))))))) {
33
+ return [step.StepOrder, field.FieldOrder, field.Label] as [int32, int32, string];
34
+ }
35
+ else {
36
+ return undefined;
37
+ }
38
+ }, step.Fields), spec.Steps);
39
+ const invalidMatrixItemsFields: FSharpList<[int32, int32, string]> = collect<Spec_FormStep$1<Spec_FieldType_$union>, [int32, int32, string]>((step_1: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<[int32, int32, string]> => choose<Spec_FormField$1<Spec_FieldType_$union>, [int32, int32, string]>((field_1: Spec_FormField$1<Spec_FieldType_$union>): Option<[int32, int32, string]> => {
40
+ const matchValue_3: Spec_FieldType_$union = field_1.FieldType;
41
+ let matchResult: int32, info_4: Spec_MatrixInfo;
42
+ if (matchValue_3.tag === /* Matrix */ 19) {
43
+ if (isEmpty(matchValue_3.fields[0].Items)) {
44
+ matchResult = 0;
45
+ info_4 = matchValue_3.fields[0];
46
+ }
47
+ else {
48
+ matchResult = 1;
49
+ }
47
50
  }
48
51
  else {
49
52
  matchResult = 1;
50
53
  }
51
- }
52
- else {
53
- matchResult = 1;
54
- }
55
- switch (matchResult) {
56
- case 0:
57
- return [step_4.StepOrder, field_3.FieldOrder, field_3.Label] as [int32, int32, string];
58
- default:
59
- return undefined;
60
- }
61
- }, step_4.Fields), spec.Steps);
62
- if (!hasTitle) {
63
- return FSharpResult$2_Error<[void, FSharpList<string>], string>("Title is required");
64
- }
65
- else if (!hasCode) {
66
- return FSharpResult$2_Error<[void, FSharpList<string>], string>("Code is required");
67
- }
68
- else if (!hasVersion) {
69
- return FSharpResult$2_Error<[void, FSharpList<string>], string>("Version is required");
70
- }
71
- else if (!hasSteps) {
72
- return FSharpResult$2_Error<[void, FSharpList<string>], string>("At least one step is required");
73
- }
74
- else if (!relaxForImport && (blankStepLabel != null)) {
75
- return FSharpResult$2_Error<[void, FSharpList<string>], string>(`Step ${value_2(blankStepLabel)} label is required`);
76
- }
77
- else if (!relaxForImport && (blankFieldLabel != null)) {
78
- const patternInput: [int32, int32] = value_2(blankFieldLabel);
79
- return FSharpResult$2_Error<[void, FSharpList<string>], string>(`Field label is required (step ${patternInput[0]}, field ${patternInput[1]})`);
80
- }
81
- else {
82
- return FSharpResult$2_Ok<[void, FSharpList<string>], string>([undefined, append((hasVersion && !isSemver) ? singleton("Version should be valid semver (e.g. 1.0.0) for lineage") : empty<string>(), append(map_1<[int32, int32, string], string>((tupledArg: [int32, int32, string]): string => {
54
+ switch (matchResult) {
55
+ case 0:
56
+ return [step_1.StepOrder, field_1.FieldOrder, field_1.Label] as [int32, int32, string];
57
+ default:
58
+ return undefined;
59
+ }
60
+ }, step_1.Fields), spec.Steps);
61
+ return FSharpResult$2_Ok<[void, FSharpList<string>], string>([undefined, append(semverWarning, append(map<[int32, int32, string], string>((tupledArg: [int32, int32, string]): string => {
83
62
  const fieldLabel: string = tupledArg[2];
84
63
  const fieldName: string = isNullOrWhiteSpace(fieldLabel) ? "(unnamed field)" : toText(printf("\'%s\'"))(fieldLabel);
85
64
  return toText(printf("%s: Field %s (step %d, field %d) has zero choices - display-only"))("EMPTY_OPTIONS")(fieldName)(tupledArg[0])(tupledArg[1]);
86
- }, invalidOptionsFields), map_1<[int32, int32, string], string>((tupledArg_1: [int32, int32, string]): string => {
65
+ }, invalidOptionsFields), map<[int32, int32, string], string>((tupledArg_1: [int32, int32, string]): string => {
87
66
  const fieldLabel_1: string = tupledArg_1[2];
88
67
  const fieldName_1: string = isNullOrWhiteSpace(fieldLabel_1) ? "(unnamed field)" : toText(printf("\'%s\'"))(fieldLabel_1);
89
68
  return toText(printf("EMPTY_MATRIX_ITEMS: Field %s (step %d, field %d) has zero matrix items - display-only"))(fieldName_1)(tupledArg_1[0])(tupledArg_1[1]);
90
69
  }, invalidMatrixItemsFields)))] as [void, FSharpList<string>]);
91
70
  }
71
+ else {
72
+ return FSharpResult$2_Error<[void, FSharpList<string>], string>(defaultArg(map_1<ValidationError, string>((e: ValidationError): string => e.Message, tryHead<ValidationError>(matchValue.fields[0])), "Validation failed"));
73
+ }
92
74
  }
93
75
 
94
76
  /**
@@ -1,22 +1,24 @@
1
1
  import { map as map_1, value as value_11, unwrap, defaultArgWith as defaultArgWith_1, Option, defaultArg as defaultArg_1 } from "@fable-org/fable-library-js/Option.js";
2
- import { tryPick, filter, mapIndexed as mapIndexed_1, isEmpty, map as map_3, ofSeq, fold, partition, ofArray, append, singleton, empty, collect, tryFind, FSharpList } from "@fable-org/fable-library-js/List.js";
2
+ import { tryPick, filter, mapIndexed as mapIndexed_1, isEmpty, map as map_3, ofSeq, fold as fold_1, partition, ofArray, append, singleton, empty, collect, tryFind, FSharpList } from "@fable-org/fable-library-js/List.js";
3
3
  import { join, substring, isNullOrEmpty, printf, toConsole } from "@fable-org/fable-library-js/String.js";
4
4
  import { Auto_generateBoxedEncoder_437914C6, toString } from "../../fable_modules/Thoth.Json.10.4.1/Encode.fs.js";
5
5
  import { array_type, string_type, union_type, TypeInfo, obj_type } from "@fable-org/fable-library-js/Reflection.js";
6
6
  import { Auto_generateBoxedDecoder_Z6670B51, fromString } from "../../fable_modules/Thoth.Json.10.4.1/Decode.fs.js";
7
- import { equals, stringHash, compare, createObj, IDisposable, disposeSafe, IEnumerator, getEnumerator, IMap, isArrayLike, uncurry2 } from "@fable-org/fable-library-js/Util.js";
7
+ import { equals, stringHash, compare, comparePrimitives, createObj, IDisposable, disposeSafe, IEnumerator, getEnumerator, IMap, isArrayLike, uncurry2 } from "@fable-org/fable-library-js/Util.js";
8
8
  import { ClinicalPathway_StateType_$union, ClinicalPathway_TaskPriority_$union, ClinicalPathway_AlertSeverity_$union, ClinicalPathway_ReferralUrgency_$union, ClinicalPathway_ActionInfo_$union, ClinicalPathway_NavigateToFormAction, ClinicalPathway_ProblemAction, ClinicalPathway_AlertAction, ClinicalPathway_EducationAction, ClinicalPathway_ProcedureAction, ClinicalPathway_TestAction, ClinicalPathway_DocumentationAction, ClinicalPathway_FieldValueSource_$union, ClinicalPathway_SetFieldValueAction, ClinicalPathway_PrescriptionAction, ClinicalPathway_MedicationAction, ClinicalPathway_ReferralAction, Shared_FieldValue, Shared_FieldValue_$union, ClinicalPathway_ClinicalPathwaySpec, ClinicalPathway_PathRequirement, ClinicalPathway_ConstraintDefinition, ClinicalPathway_PathwayExecutionMode_SinglePathway, ClinicalPathway_SinglePathwayConfig, ClinicalPathway_SelectionStrategy_HighestPriority, ClinicalPathway_TransitionDefinition, ClinicalPathway_TransitionCondition_FieldCondition, Shared_ConditionValue_Single, ClinicalPathway_FieldEvaluator_Equals, Shared_TransitionKey, ClinicalPathway_StateType_Terminal, ClinicalPathway_TerminalInfo, ClinicalPathway_StateDefinition, ClinicalPathway_StateType_Action, ClinicalPathway_ActionInfo_Task, ClinicalPathway_TaskAction, ClinicalPathway_DueDate_Today, ClinicalPathway_TaskPriority_Medium, ClinicalPathway_TaskPriority_Low, ClinicalPathway_TaskPriority_High, Shared_StateKey, Spec_FieldType_PluginField, Spec_PluginFieldConfig, Spec_FieldType_Matrix, Spec_MatrixInfo, Spec_FormLifecycle_Blueprint, Spec_FieldType_Text, Spec_TextInfo, Spec_FieldType_CheckboxList, Spec_MultiChoiceInfo, Shared_FieldOptionKey, Spec_FieldType_Checkbox, Spec_BooleanInfo, Shared_FieldKey, Shared_FieldOption, Shared_FieldValue_Single, Shared_FieldValue_PluginData, Shared_PluginDataProperty, Shared_PluginPropertyKey, Shared_FieldValue_Matrix, Shared_MatrixAnswer, Shared_MatrixItemKey, Shared_FieldValue_Multiple, Shared_FieldAnswer, Spec_FormStep$1, Spec_FormField$1, Spec_FieldType_$union, Spec_FormSpec$1, Spec_FormSpec$1_$reflection, Spec_FieldType_$reflection } from "../FormSpec.js";
9
9
  import { FSharpResult$2_Ok, FSharpResult$2_Error, FSharpResult$2_$union } from "@fable-org/fable-library-js/Result.js";
10
10
  import { newGuid, parse, tryParse } from "@fable-org/fable-library-js/Guid.js";
11
11
  import { toString as toString_1, Union, FSharpRef } from "@fable-org/fable-library-js/Types.js";
12
12
  import { IOptionalGetter, array as array_4, IGetters, dict as dict_1, string, IRequiredGetter, object, fromString as fromString_1 } from "../../fable_modules/Thoth.Json.10.4.1/Decode.fs.js";
13
13
  import { ErrorReason_$union } from "../../fable_modules/Thoth.Json.10.4.1/Types.fs.js";
14
- import { count, ofSeq as ofSeq_1, toList, FSharpMap } from "@fable-org/fable-library-js/Map.js";
14
+ import { count, ofSeq as ofSeq_1, add, empty as empty_1, toList, FSharpMap } from "@fable-org/fable-library-js/Map.js";
15
15
  import { addToDict } from "@fable-org/fable-library-js/MapUtil.js";
16
16
  import { int32 } from "@fable-org/fable-library-js/Int32.js";
17
17
  import { extractPropertyKeyFromUnknown, resolvePropertyKey } from "./PluginPropertyKeyRegistry.js";
18
- import { empty as empty_1, append as append_1, mapIndexed, map as map_2, choose, singleton as singleton_1, collect as collect_1, delay, toList as toList_1 } from "@fable-org/fable-library-js/Seq.js";
19
- import { map } from "@fable-org/fable-library-js/Array.js";
18
+ import { empty as empty_2, append as append_1, mapIndexed, map as map_2, choose, singleton as singleton_1, collect as collect_1, delay, toList as toList_1 } from "@fable-org/fable-library-js/Seq.js";
19
+ import { fold, map } from "@fable-org/fable-library-js/Array.js";
20
+ import { FilledForm_validateFilledFormData } from "../Validation/Validation.FilledForm.js";
21
+ import { ValidationError } from "../Validation/ValidationTypes.js";
20
22
  import { getFieldDetails as getFieldDetails_1, FieldDetails$1, updateField, findStepIndexForField, updateFieldDocumentation } from "../FormSpecValues.js";
21
23
  import { toArray, ofArray as ofArray_1 } from "@fable-org/fable-library-js/Set.js";
22
24
  import { now } from "@fable-org/fable-library-js/DateOffset.js";
@@ -63,12 +65,20 @@ export function listToArray<T>(list: FSharpList<T>): T[] {
63
65
  return Array.from(list);
64
66
  }
65
67
 
68
+ /**
69
+ * Serialize FormSpec to JSON. Uses PascalCase (Thoth default).
70
+ * Case conversion at API boundaries per COREMR_F1_CACHING_STRATEGY.md.
71
+ */
66
72
  export function serializeFormSpec(formSpec: any): string {
67
73
  toConsole(printf("[API.Helpers] Serializing FormSpec!!"));
68
74
  toConsole(`[API.Helpers] FormSpec: ${formSpec}`);
69
75
  return toString(0, Auto_generateBoxedEncoder_437914C6(obj_type, undefined, undefined, undefined)(formSpec));
70
76
  }
71
77
 
78
+ /**
79
+ * Deserialize FormSpec from JSON. Uses PascalCase (Thoth default).
80
+ * Case conversion at API boundaries per COREMR_F1_CACHING_STRATEGY.md.
81
+ */
72
82
  export function deserializeFormSpec(json: string): Option<Spec_FormSpec$1<Spec_FieldType_$union>> {
73
83
  toConsole(printf("[API.Helpers] Deserializing FormSpec"));
74
84
  const matchValue: FSharpResult$2_$union<Spec_FormSpec$1<Spec_FieldType_$union>, string> = fromString<Spec_FormSpec$1<Spec_FieldType_$union>>(uncurry2(Auto_generateBoxedDecoder_Z6670B51(Spec_FormSpec$1_$reflection(Spec_FieldType_$reflection()), undefined, undefined)), json);
@@ -407,13 +417,36 @@ export function normalizeFormValuesForPlatformApi(formValues: any): any {
407
417
  }, entries))));
408
418
  }
409
419
 
420
+ function jsObjectToFilledFormDataMap(o: any): FSharpMap<string, any> {
421
+ if (o == null) {
422
+ return empty_1<string, any>({
423
+ Compare: comparePrimitives,
424
+ });
425
+ }
426
+ else {
427
+ const entries: [string, any][] = Object.entries(o);
428
+ return fold<[string, any], FSharpMap<string, any>>((m: FSharpMap<string, any>, tupledArg: [string, any]): FSharpMap<string, any> => add<string, any>(tupledArg[0], tupledArg[1], m), empty_1<string, any>({
429
+ Compare: comparePrimitives,
430
+ }), entries);
431
+ }
432
+ }
433
+
434
+ /**
435
+ * Validate filled form data against FormSpec. Returns Ok () or Error with ValidationError list.
436
+ * plainValues: { [fieldKey]: value, [fieldKey_doc]: doc }. Converted at boundary to typed Map. Use before save/publish.
437
+ * TypeScript: import { validateFilledFormData } from '@f1studio/form-spec/Interop/FormSpec.Api.Helpers'
438
+ */
439
+ export function validateFilledFormData(formSpec: Spec_FormSpec$1<Spec_FieldType_$union>, plainValues: any): FSharpResult$2_$union<void, FSharpList<ValidationError>> {
440
+ return FilledForm_validateFilledFormData(formSpec, jsObjectToFilledFormDataMap(plainValues));
441
+ }
442
+
410
443
  /**
411
444
  * Build FormSpec with field values applied. Primary API - pathway uses FormSpec directly.
412
445
  * TypeScript: buildFormSpecWithValues(formSpec: FormSpec, fieldData: FieldInput[]) => FormSpec
413
446
  */
414
447
  export function buildFormSpecWithValues(formSpec: Spec_FormSpec$1<Spec_FieldType_$union>, fieldData: { fieldKey: string, objectValue: any }[]): Spec_FormSpec$1<Spec_FieldType_$union> {
415
448
  const patternInput: [FSharpList<{ fieldKey: string, objectValue: any }>, FSharpList<{ fieldKey: string, objectValue: any }>] = partition<{ fieldKey: string, objectValue: any }>((input: { fieldKey: string, objectValue: any }): boolean => !input.fieldKey.endsWith("_doc"), toList_1<{ fieldKey: string, objectValue: any }>(fieldData));
416
- return fold<{ fieldKey: string, objectValue: any }, Spec_FormSpec$1<Spec_FieldType_$union>>((spec_1: Spec_FormSpec$1<Spec_FieldType_$union>, input_2: { fieldKey: string, objectValue: any }): Spec_FormSpec$1<Spec_FieldType_$union> => {
449
+ return fold_1<{ fieldKey: string, objectValue: any }, Spec_FormSpec$1<Spec_FieldType_$union>>((spec_1: Spec_FormSpec$1<Spec_FieldType_$union>, input_2: { fieldKey: string, objectValue: any }): Spec_FormSpec$1<Spec_FieldType_$union> => {
417
450
  const baseKey: string = substring(input_2.fieldKey, 0, input_2.fieldKey.length - 4);
418
451
  const matchValue_3: Option<Spec_FormField$1<Spec_FieldType_$union>> = findFieldByKey(spec_1, baseKey);
419
452
  if (matchValue_3 == null) {
@@ -426,7 +459,7 @@ export function buildFormSpecWithValues(formSpec: Spec_FormSpec$1<Spec_FieldType
426
459
  const docOpt: Option<string> = isNullOrEmpty(docStr) ? undefined : docStr;
427
460
  return defaultArg_1(map_1<int32, Spec_FormSpec$1<Spec_FieldType_$union>>((stepIdx_1: int32): Spec_FormSpec$1<Spec_FieldType_$union> => updateFieldDocumentation<Spec_FieldType_$union>(spec_1, field_2.FieldKey, docOpt, stepIdx_1), findStepIndexForField<Spec_FieldType_$union>(spec_1, field_2.FieldKey)), spec_1);
428
461
  }
429
- }, fold<[Spec_FormField$1<Spec_FieldType_$union>, FieldDetails$1<Spec_FieldType_$union>], Spec_FormSpec$1<Spec_FieldType_$union>>((spec: Spec_FormSpec$1<Spec_FieldType_$union>, tupledArg: [Spec_FormField$1<Spec_FieldType_$union>, FieldDetails$1<Spec_FieldType_$union>]): Spec_FormSpec$1<Spec_FieldType_$union> => {
462
+ }, fold_1<[Spec_FormField$1<Spec_FieldType_$union>, FieldDetails$1<Spec_FieldType_$union>], Spec_FormSpec$1<Spec_FieldType_$union>>((spec: Spec_FormSpec$1<Spec_FieldType_$union>, tupledArg: [Spec_FormField$1<Spec_FieldType_$union>, FieldDetails$1<Spec_FieldType_$union>]): Spec_FormSpec$1<Spec_FieldType_$union> => {
430
463
  const field_1: Spec_FormField$1<Spec_FieldType_$union> = tupledArg[0];
431
464
  return defaultArg_1(map_1<int32, Spec_FormSpec$1<Spec_FieldType_$union>>((stepIdx: int32): Spec_FormSpec$1<Spec_FieldType_$union> => updateField<Spec_FieldType_$union>(spec, field_1.FieldKey, tupledArg[1].FieldValue, stepIdx), findStepIndexForField<Spec_FieldType_$union>(spec, field_1.FieldKey)), spec);
432
465
  }, formSpec, ofSeq<[Spec_FormField$1<Spec_FieldType_$union>, FieldDetails$1<Spec_FieldType_$union>]>(choose<{ fieldKey: string, objectValue: any }, [Spec_FormField$1<Spec_FieldType_$union>, FieldDetails$1<Spec_FieldType_$union>]>((input_1: { fieldKey: string, objectValue: any }): Option<[Spec_FormField$1<Spec_FieldType_$union>, FieldDetails$1<Spec_FieldType_$union>]> => {
@@ -910,7 +943,7 @@ export function extractFormValuesFromFormSpec(spec: Spec_FormSpec$1<Spec_FieldTy
910
943
  const pairs: FSharpList<[string, any]> = toList_1<[string, any]>(delay<[string, any]>((): Iterable<[string, any]> => collect_1<Spec_FormStep$1<Spec_FieldType_$union>, Iterable<[string, any]>, [string, any]>((step: Spec_FormStep$1<Spec_FieldType_$union>): Iterable<[string, any]> => collect_1<Spec_FormField$1<Spec_FieldType_$union>, Iterable<[string, any]>, [string, any]>((field: Spec_FormField$1<Spec_FieldType_$union>): Iterable<[string, any]> => {
911
944
  let matchValue: Option<Shared_FieldValue_$union>, fv: Shared_FieldValue_$union, arr: string[], ma: Shared_MatrixAnswer, dict: IMap<string, string>, enumerator: IEnumerator<[Shared_MatrixItemKey, string]>, arr_1: FSharpList<any>;
912
945
  const keyStr: string = getFieldKeyString(field.FieldKey);
913
- return append_1<[string, any]>((matchValue = field.Value, (matchValue == null) ? (empty_1<[string, any]>()) : ((fv = value_11(matchValue), singleton_1<[string, any]>([keyStr, (fv.tag === /* Multiple */ 1) ? ((arr = map<Shared_FieldAnswer, string>((fa_1: Shared_FieldAnswer): string => fa_1.Value, toArray<Shared_FieldAnswer>(fv.fields[0])), Array.from(arr))) : ((fv.tag === /* Matrix */ 2) ? ((ma = fv.fields[0], (dict = (new Map<string, string>([])), ((enumerator = getEnumerator(ma.Values), (() => {
946
+ return append_1<[string, any]>((matchValue = field.Value, (matchValue == null) ? (empty_2<[string, any]>()) : ((fv = value_11(matchValue), singleton_1<[string, any]>([keyStr, (fv.tag === /* Multiple */ 1) ? ((arr = map<Shared_FieldAnswer, string>((fa_1: Shared_FieldAnswer): string => fa_1.Value, toArray<Shared_FieldAnswer>(fv.fields[0])), Array.from(arr))) : ((fv.tag === /* Matrix */ 2) ? ((ma = fv.fields[0], (dict = (new Map<string, string>([])), ((enumerator = getEnumerator(ma.Values), (() => {
914
947
  try {
915
948
  while (enumerator["System.Collections.IEnumerator.MoveNext"]()) {
916
949
  const kvp: [Shared_MatrixItemKey, string] = enumerator["System.Collections.Generic.IEnumerator`1.get_Current"]();
@@ -928,7 +961,7 @@ export function extractFormValuesFromFormSpec(spec: Spec_FormSpec$1<Spec_FieldTy
928
961
  propertyKey: p.PropertyKey.fields[0],
929
962
  unit: unwrap(p.Unit),
930
963
  value: p.Value,
931
- }), fv.fields[0]), Array.from(arr_1))) : fv.fields[0].Value))] as [string, any])))), delay<[string, any]>((): Iterable<[string, any]> => (field.NeedsDocumentation ? singleton_1<[string, any]>([keyStr + "_doc", defaultArg_1(field.Documentation, "")] as [string, any]) : empty_1<[string, any]>())));
964
+ }), fv.fields[0]), Array.from(arr_1))) : fv.fields[0].Value))] as [string, any])))), delay<[string, any]>((): Iterable<[string, any]> => (field.NeedsDocumentation ? singleton_1<[string, any]>([keyStr + "_doc", defaultArg_1(field.Documentation, "")] as [string, any]) : empty_2<[string, any]>())));
932
965
  }, step.Fields), spec.Steps)));
933
966
  if (isEmpty(pairs)) {
934
967
  return {};
@@ -0,0 +1,158 @@
1
+ import { Spec_FormSpec$1, Spec_FormStep$1, Spec_FieldType_$union, Spec_FormField$1, Shared_FieldKey } from "../FormSpec.js";
2
+ import { int32, float64 } from "@fable-org/fable-library-js/Int32.js";
3
+ import { equals } from "@fable-org/fable-library-js/BigInt.js";
4
+ import { empty as empty_1, singleton as singleton_1, append as append_1, toList, enumerateFromFunctions, map, delay, exists } from "@fable-org/fable-library-js/Seq.js";
5
+ import { IEnumerator, getEnumerator } from "@fable-org/fable-library-js/Util.js";
6
+ import { ValidationError } from "./ValidationTypes.js";
7
+ import { isEmpty, collect, append, FSharpList, singleton, empty } from "@fable-org/fable-library-js/List.js";
8
+ import { FSharpMap, tryFind } from "@fable-org/fable-library-js/Map.js";
9
+ import { map as map_1, defaultArg, value as value_1, Option } from "@fable-org/fable-library-js/Option.js";
10
+ import { printf, toText, isNullOrWhiteSpace } from "@fable-org/fable-library-js/String.js";
11
+ import { toString } from "@fable-org/fable-library-js/Types.js";
12
+ import { FSharpResult$2_$union, FSharpResult$2_Error, FSharpResult$2_Ok } from "@fable-org/fable-library-js/Result.js";
13
+
14
+ function FilledForm_getFieldKeyString(fieldKey: Shared_FieldKey): string {
15
+ return fieldKey.fields[0];
16
+ }
17
+
18
+ function FilledForm_isTruthyValue(v: any): boolean {
19
+ if (v == null) {
20
+ return false;
21
+ }
22
+ else if (typeof v === "string") {
23
+ const s: string = v;
24
+ const t: string = s.trim().toLowerCase();
25
+ if ((t === "yes") ? true : (t === "true")) {
26
+ return true;
27
+ }
28
+ else {
29
+ return t === "1";
30
+ }
31
+ }
32
+ else if (typeof v === "boolean") {
33
+ return v;
34
+ }
35
+ else if (typeof v === "number") {
36
+ return v === 1;
37
+ }
38
+ else if (typeof v === "number") {
39
+ const f: float64 = v;
40
+ return Math.abs(f - 1) < 0.001;
41
+ }
42
+ else if (typeof v === "bigint") {
43
+ return equals(v, 1n);
44
+ }
45
+ else {
46
+ const arr = v as Iterable<any>;
47
+ if (arr == null) {
48
+ return false;
49
+ }
50
+ else {
51
+ return exists<any>(FilledForm_isTruthyValue, delay<any>((): Iterable<any> => map<any, any>((x: any): any => x, enumerateFromFunctions<IEnumerator<any>, any>((): IEnumerator<any> => getEnumerator(arr), (enumerator: IEnumerator<any>): boolean => enumerator["System.Collections.IEnumerator.MoveNext"](), (enumerator_1: IEnumerator<any>): any => enumerator_1["System.Collections.IEnumerator.get_Current"]()))));
52
+ }
53
+ }
54
+ }
55
+
56
+ /**
57
+ * If field.NeedsDocumentation and value is truthy (yes/true/1) and filledFormData[fieldKey_doc] is empty -> error
58
+ */
59
+ export function FilledForm_validateNeedsDocumentation(field: Spec_FormField$1<Spec_FieldType_$union>, filledFormData: FSharpMap<string, any>): FSharpList<ValidationError> {
60
+ let s: string, x: any;
61
+ if (!field.NeedsDocumentation) {
62
+ return empty<ValidationError>();
63
+ }
64
+ else {
65
+ const keyStr: string = FilledForm_getFieldKeyString(field.FieldKey);
66
+ const value: Option<any> = tryFind<string, any>(keyStr, filledFormData);
67
+ if (value != null) {
68
+ if (!FilledForm_isTruthyValue(value_1(value))) {
69
+ const v_1: any = value_1(value);
70
+ return empty<ValidationError>();
71
+ }
72
+ else {
73
+ const docVal: Option<any> = tryFind<string, any>(keyStr + "_doc", filledFormData);
74
+ if (isNullOrWhiteSpace((docVal != null) ? ((typeof value_1(docVal) === "string") ? ((s = (value_1(docVal) as string), s.trim())) : ((x = value_1(docVal), toString(x)))) : "")) {
75
+ return singleton(new ValidationError(keyStr, field.Label, "NEEDS_DOCUMENTATION", toText(printf("Field \'%s\' requires documentation when value is \'yes\' or similar."))(field.Label)));
76
+ }
77
+ else {
78
+ return empty<ValidationError>();
79
+ }
80
+ }
81
+ }
82
+ else {
83
+ return empty<ValidationError>();
84
+ }
85
+ }
86
+ }
87
+
88
+ /**
89
+ * FieldKey must be non-empty GUID. Reuses logic from FormSpecHelpers.validateFormDataFieldKeys.
90
+ */
91
+ export function FilledForm_validateFieldKeys(field: Spec_FormField$1<Spec_FieldType_$union>): FSharpList<ValidationError> {
92
+ if (field.FieldKey.fields[0] === "00000000-0000-0000-0000-000000000000") {
93
+ return singleton(new ValidationError("", field.Label, "INVALID_FIELD_KEY", toText(printf("Field \'%s\' has empty GUID field key."))(field.Label)));
94
+ }
95
+ else {
96
+ return empty<ValidationError>();
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Field-level: compose primitives (validateNeedsDocumentation, validateFieldKeys).
102
+ */
103
+ export function FilledForm_validateFilledFormFieldValue(field: Spec_FormField$1<Spec_FieldType_$union>, filledFormData: FSharpMap<string, any>): FSharpList<ValidationError> {
104
+ return append(FilledForm_validateFieldKeys(field), FilledForm_validateNeedsDocumentation(field, filledFormData));
105
+ }
106
+
107
+ /**
108
+ * Step-level: iterate fields, collect errors.
109
+ */
110
+ export function FilledForm_validateFilledFormStep(step: Spec_FormStep$1<Spec_FieldType_$union>, filledFormData: FSharpMap<string, any>): FSharpList<ValidationError> {
111
+ return collect<Spec_FormField$1<Spec_FieldType_$union>, ValidationError>((field: Spec_FormField$1<Spec_FieldType_$union>): FSharpList<ValidationError> => FilledForm_validateFilledFormFieldValue(field, filledFormData), step.Fields);
112
+ }
113
+
114
+ /**
115
+ * Top-level: validate FormSpec + filledFormData. Returns Result<unit, ValidationError list>.
116
+ * Takes typed Map - no guessing. Callers convert at boundary.
117
+ */
118
+ export function FilledForm_validateFilledFormData(formSpec: Spec_FormSpec$1<Spec_FieldType_$union>, filledFormData: FSharpMap<string, any>): FSharpResult$2_$union<void, FSharpList<ValidationError>> {
119
+ const errors: FSharpList<ValidationError> = collect<Spec_FormStep$1<Spec_FieldType_$union>, ValidationError>((step: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<ValidationError> => FilledForm_validateFilledFormStep(step, filledFormData), formSpec.Steps);
120
+ if (isEmpty(errors)) {
121
+ return FSharpResult$2_Ok<void, FSharpList<ValidationError>>(undefined);
122
+ }
123
+ else {
124
+ return FSharpResult$2_Error<void, FSharpList<ValidationError>>(errors);
125
+ }
126
+ }
127
+
128
+ function Blueprint_getFieldKeyString(fieldKey: Shared_FieldKey): string {
129
+ return fieldKey.fields[0];
130
+ }
131
+
132
+ export function Blueprint_validateBlueprintFieldType(stepOrder: int32, fieldOrder: int32, field: Spec_FormField$1<Spec_FieldType_$union>, relaxForImport: boolean): FSharpList<ValidationError> {
133
+ if (relaxForImport) {
134
+ return empty<ValidationError>();
135
+ }
136
+ else if (isNullOrWhiteSpace(field.Label)) {
137
+ return singleton(new ValidationError(Blueprint_getFieldKeyString(field.FieldKey), field.Label, "BLANK_FIELD_LABEL", toText(printf("Field label is required (step %d, field %d)"))(stepOrder)(fieldOrder)));
138
+ }
139
+ else {
140
+ return empty<ValidationError>();
141
+ }
142
+ }
143
+
144
+ export function Blueprint_validateBlueprintFormStep(step: Spec_FormStep$1<Spec_FieldType_$union>, relaxForImport: boolean): FSharpList<ValidationError> {
145
+ return append(relaxForImport ? empty<ValidationError>() : (isNullOrWhiteSpace(step.StepLabel) ? singleton(new ValidationError(toText(printf("step-%d"))(step.StepOrder), step.StepLabel, "BLANK_STEP_LABEL", toText(printf("Step %d label is required"))(step.StepOrder))) : empty<ValidationError>()), collect<Spec_FormField$1<Spec_FieldType_$union>, ValidationError>((f: Spec_FormField$1<Spec_FieldType_$union>): FSharpList<ValidationError> => Blueprint_validateBlueprintFieldType(step.StepOrder, f.FieldOrder, f, relaxForImport), step.Fields));
146
+ }
147
+
148
+ export function Blueprint_validateBlueprint(spec: Spec_FormSpec$1<Spec_FieldType_$union>, relaxForImport: boolean): FSharpResult$2_$union<void, FSharpList<ValidationError>> {
149
+ const allErrors: FSharpList<ValidationError> = append(toList<ValidationError>(delay<ValidationError>((): Iterable<ValidationError> => append_1<ValidationError>(isNullOrWhiteSpace(spec.Title) ? singleton_1<ValidationError>(new ValidationError("", "", "BLUEPRINT_TITLE_REQUIRED", "Title is required")) : empty_1<ValidationError>(), delay<ValidationError>((): Iterable<ValidationError> => append_1<ValidationError>(!defaultArg(map_1<string, boolean>((c: string): boolean => !isNullOrWhiteSpace(c), spec.Code), false) ? singleton_1<ValidationError>(new ValidationError("", "", "BLUEPRINT_CODE_REQUIRED", "Code is required")) : empty_1<ValidationError>(), delay<ValidationError>((): Iterable<ValidationError> => append_1<ValidationError>(isNullOrWhiteSpace((spec.Version == null) ? "" : spec.Version.trim()) ? singleton_1<ValidationError>(new ValidationError("", "", "BLUEPRINT_VERSION_REQUIRED", "Version is required")) : empty_1<ValidationError>(), delay<ValidationError>((): Iterable<ValidationError> => (isEmpty(spec.Steps) ? singleton_1<ValidationError>(new ValidationError("", "", "BLUEPRINT_STEPS_REQUIRED", "At least one step is required")) : empty_1<ValidationError>()))))))))), collect<Spec_FormStep$1<Spec_FieldType_$union>, ValidationError>((s: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<ValidationError> => Blueprint_validateBlueprintFormStep(s, relaxForImport), spec.Steps));
150
+ if (isEmpty(allErrors)) {
151
+ return FSharpResult$2_Ok<void, FSharpList<ValidationError>>(undefined);
152
+ }
153
+ else {
154
+ return FSharpResult$2_Error<void, FSharpList<ValidationError>>(allErrors);
155
+ }
156
+ }
157
+
158
+ //# sourceMappingURL=Validation.FilledForm.ts.map
@@ -0,0 +1,23 @@
1
+ import { Record } from "@fable-org/fable-library-js/Types.js";
2
+ import { IComparable, IEquatable } from "@fable-org/fable-library-js/Util.js";
3
+ import { record_type, string_type, TypeInfo } from "@fable-org/fable-library-js/Reflection.js";
4
+
5
+ export class ValidationError extends Record implements IEquatable<ValidationError>, IComparable<ValidationError> {
6
+ readonly FieldKey: string;
7
+ readonly Label: string;
8
+ readonly Code: string;
9
+ readonly Message: string;
10
+ constructor(FieldKey: string, Label: string, Code: string, Message: string) {
11
+ super();
12
+ this.FieldKey = FieldKey;
13
+ this.Label = Label;
14
+ this.Code = Code;
15
+ this.Message = Message;
16
+ }
17
+ }
18
+
19
+ export function ValidationError_$reflection(): TypeInfo {
20
+ return record_type("F1.Studio.ValidationTypes.ValidationError", [], ValidationError, () => [["FieldKey", string_type], ["Label", string_type], ["Code", string_type], ["Message", string_type]]);
21
+ }
22
+
23
+ //# sourceMappingURL=ValidationTypes.ts.map