@makehq/forman-schema 1.12.1 → 1.13.1
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 +2 -0
- package/dist/index.cjs +67 -3
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +67 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -185,6 +185,7 @@ const result = await validateFormanWithDomains(
|
|
|
185
185
|
- email → string
|
|
186
186
|
- file → string
|
|
187
187
|
- filename → string
|
|
188
|
+
- filestorage → array (of UUID strings)
|
|
188
189
|
- filter → array
|
|
189
190
|
- folder → string
|
|
190
191
|
- hidden → string
|
|
@@ -196,6 +197,7 @@ const result = await validateFormanWithDomains(
|
|
|
196
197
|
- path → string
|
|
197
198
|
- pkey → string
|
|
198
199
|
- port → number
|
|
200
|
+
- scenario → string
|
|
199
201
|
- select → string with enum
|
|
200
202
|
- text → string
|
|
201
203
|
- time → string
|
package/dist/index.cjs
CHANGED
|
@@ -93,13 +93,20 @@ function normalizeFormanFieldType(field) {
|
|
|
93
93
|
}
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
|
+
function valuesMatch(a, b) {
|
|
97
|
+
if (a === b) return true;
|
|
98
|
+
if (isObject(a) && isObject(b)) return JSON.stringify(a) === JSON.stringify(b);
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
96
101
|
function findValueInSelectOptions(field, value, optionsAndGroups) {
|
|
97
102
|
if (!optionsAndGroups) return void 0;
|
|
103
|
+
const valueKey = isObject(field.options) && field.options.value ? field.options.value : "value";
|
|
104
|
+
const matches = (option) => valuesMatch(option[valueKey], value);
|
|
98
105
|
if (field.grouped) {
|
|
99
|
-
const found2 = optionsAndGroups.flatMap((group) => "options" in group ? group.options : []).find(
|
|
106
|
+
const found2 = optionsAndGroups.flatMap((group) => "options" in group ? group.options : []).find(matches);
|
|
100
107
|
if (found2) return found2;
|
|
101
108
|
}
|
|
102
|
-
const found = optionsAndGroups.find((option) =>
|
|
109
|
+
const found = optionsAndGroups.find((option) => valueKey in option && matches(option));
|
|
103
110
|
return found;
|
|
104
111
|
}
|
|
105
112
|
function pathToString(path) {
|
|
@@ -560,6 +567,7 @@ var FORMAN_TYPE_MAP = {
|
|
|
560
567
|
email: "string",
|
|
561
568
|
filename: "string",
|
|
562
569
|
file: "string",
|
|
570
|
+
filestorage: "array",
|
|
563
571
|
filter: "array",
|
|
564
572
|
folder: "string",
|
|
565
573
|
hidden: void 0,
|
|
@@ -569,6 +577,9 @@ var FORMAN_TYPE_MAP = {
|
|
|
569
577
|
path: "string",
|
|
570
578
|
pkey: "string",
|
|
571
579
|
port: "number",
|
|
580
|
+
list: "string",
|
|
581
|
+
radio: "string",
|
|
582
|
+
scenario: "string",
|
|
572
583
|
select: "string",
|
|
573
584
|
udttype: "string",
|
|
574
585
|
udtspec: "array",
|
|
@@ -658,7 +669,10 @@ function toJSONSchemaInternal(field, context) {
|
|
|
658
669
|
case "dynamicCollection":
|
|
659
670
|
return handleCollectionType(normalizedField, result, context);
|
|
660
671
|
case "array":
|
|
672
|
+
case "filestorage":
|
|
661
673
|
return handleArrayType(normalizedField, result, context);
|
|
674
|
+
case "list":
|
|
675
|
+
case "radio":
|
|
662
676
|
case "select":
|
|
663
677
|
case "account":
|
|
664
678
|
case "hook":
|
|
@@ -666,6 +680,7 @@ function toJSONSchemaInternal(field, context) {
|
|
|
666
680
|
case "keychain":
|
|
667
681
|
case "datastore":
|
|
668
682
|
case "aiagent":
|
|
683
|
+
case "scenario":
|
|
669
684
|
case "file":
|
|
670
685
|
case "folder":
|
|
671
686
|
return handleSelectOrPathType(normalizedField, result, context);
|
|
@@ -734,7 +749,15 @@ function handleCollectionType(field, result, context) {
|
|
|
734
749
|
return result;
|
|
735
750
|
}
|
|
736
751
|
function handleArrayType(field, result, context) {
|
|
737
|
-
if (field.
|
|
752
|
+
if (field.type === "filestorage") {
|
|
753
|
+
result.items = { type: "string" };
|
|
754
|
+
Object.defineProperty(result, "x-filestorage", {
|
|
755
|
+
configurable: true,
|
|
756
|
+
enumerable: false,
|
|
757
|
+
writable: true,
|
|
758
|
+
value: true
|
|
759
|
+
});
|
|
760
|
+
} else if (field.spec) {
|
|
738
761
|
result.items = toJSONSchemaInternal(
|
|
739
762
|
Array.isArray(field.spec) ? { type: "collection", spec: field.spec } : field.spec,
|
|
740
763
|
{
|
|
@@ -873,6 +896,32 @@ function handleSelectOrPathType(field, result, context) {
|
|
|
873
896
|
writable: true,
|
|
874
897
|
value: appendQueryString(optionsOrGroups, context.domain, context.tail)
|
|
875
898
|
});
|
|
899
|
+
const xFetchOptions = {};
|
|
900
|
+
if (isObject(field.options)) {
|
|
901
|
+
for (const transferKey of ["label", "value"]) {
|
|
902
|
+
const transferValue = field.options[transferKey];
|
|
903
|
+
if (transferValue) xFetchOptions[transferKey] = transferValue;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if (![
|
|
907
|
+
// Reference Types are distinguished by the Loader Tool Name directly
|
|
908
|
+
...FORMAN_REFERENCE_TYPES,
|
|
909
|
+
// Select is default
|
|
910
|
+
"select",
|
|
911
|
+
// File and Folder are distinguished by the x-path metadata, so we don't need to append it here
|
|
912
|
+
"file",
|
|
913
|
+
"folder"
|
|
914
|
+
].includes(field.type)) {
|
|
915
|
+
xFetchOptions["type"] = field.type;
|
|
916
|
+
}
|
|
917
|
+
if (Object.keys(xFetchOptions).length) {
|
|
918
|
+
Object.defineProperty(result, "x-fetch-options", {
|
|
919
|
+
configurable: true,
|
|
920
|
+
enumerable: true,
|
|
921
|
+
writable: true,
|
|
922
|
+
value: xFetchOptions
|
|
923
|
+
});
|
|
924
|
+
}
|
|
876
925
|
} else {
|
|
877
926
|
let options = optionsOrGroups?.flatMap((optionOrGroup) => {
|
|
878
927
|
if (isOptionGroup(optionOrGroup)) {
|
|
@@ -1141,6 +1190,8 @@ var FORMAN_TYPE_MAP2 = {
|
|
|
1141
1190
|
path: "string",
|
|
1142
1191
|
pkey: "string",
|
|
1143
1192
|
port: "number",
|
|
1193
|
+
list: void 0,
|
|
1194
|
+
radio: void 0,
|
|
1144
1195
|
select: void 0,
|
|
1145
1196
|
udttype: "string",
|
|
1146
1197
|
udtspec: "array",
|
|
@@ -1148,6 +1199,8 @@ var FORMAN_TYPE_MAP2 = {
|
|
|
1148
1199
|
timestamp: "string",
|
|
1149
1200
|
timezone: "string",
|
|
1150
1201
|
upload: "array",
|
|
1202
|
+
filestorage: "array",
|
|
1203
|
+
scenario: "string",
|
|
1151
1204
|
url: "string",
|
|
1152
1205
|
uuid: "string",
|
|
1153
1206
|
any: void 0
|
|
@@ -1351,7 +1404,10 @@ async function validateFormanValue(value, field, context) {
|
|
|
1351
1404
|
case "collection":
|
|
1352
1405
|
return handleCollectionType2(value, normalizedField, context);
|
|
1353
1406
|
case "array":
|
|
1407
|
+
case "filestorage":
|
|
1354
1408
|
return handleArrayType2(value, normalizedField, context);
|
|
1409
|
+
case "list":
|
|
1410
|
+
case "radio":
|
|
1355
1411
|
case "select":
|
|
1356
1412
|
case "account":
|
|
1357
1413
|
case "hook":
|
|
@@ -2043,6 +2099,14 @@ function toFormanSchema(field) {
|
|
|
2043
2099
|
spec
|
|
2044
2100
|
};
|
|
2045
2101
|
case "array":
|
|
2102
|
+
const filestorageMarker = Object.getOwnPropertyDescriptor(field, "x-filestorage");
|
|
2103
|
+
if (filestorageMarker) {
|
|
2104
|
+
return {
|
|
2105
|
+
type: "filestorage",
|
|
2106
|
+
label: noEmpty(field.title),
|
|
2107
|
+
help: noEmpty(field.description)
|
|
2108
|
+
};
|
|
2109
|
+
}
|
|
2046
2110
|
const filterLogic = Object.getOwnPropertyDescriptor(field, "x-filter");
|
|
2047
2111
|
if (filterLogic) {
|
|
2048
2112
|
return {
|
package/dist/index.d.cts
CHANGED
|
@@ -3,7 +3,7 @@ import { JSONSchema7 } from 'json-schema';
|
|
|
3
3
|
/**
|
|
4
4
|
* Valid Forman Schema field types
|
|
5
5
|
*/
|
|
6
|
-
type FormanSchemaFieldType = 'aiagent' | 'account' | 'hook' | 'device' | 'keychain' | 'datastore' | 'udt' | 'scenario' | 'array' | 'collection' | 'text' | 'number' | 'boolean' | 'checkbox' | 'date' | 'json' | 'buffer' | 'cert' | 'color' | 'email' | 'filename' | 'file' | 'filter' | 'folder' | 'hidden' | 'integer' | 'uinteger' | 'path' | 'pkey' | 'port' | 'select' | 'time' | 'timestamp' | 'timezone' | 'url' | 'uuid' | `account:${string}` | `hook:${string}` | `keychain:${string}` | `device:${string}` | 'banner' | 'markdown' | 'html' | 'separator' | string;
|
|
6
|
+
type FormanSchemaFieldType = 'aiagent' | 'account' | 'hook' | 'device' | 'keychain' | 'datastore' | 'udt' | 'scenario' | 'array' | 'collection' | 'text' | 'number' | 'boolean' | 'checkbox' | 'date' | 'json' | 'buffer' | 'cert' | 'color' | 'email' | 'filename' | 'file' | 'filter' | 'filestorage' | 'folder' | 'hidden' | 'integer' | 'uinteger' | 'path' | 'pkey' | 'port' | 'list' | 'radio' | 'select' | 'time' | 'timestamp' | 'timezone' | 'url' | 'uuid' | `account:${string}` | `hook:${string}` | `keychain:${string}` | `device:${string}` | 'banner' | 'markdown' | 'html' | 'separator' | string;
|
|
7
7
|
/**
|
|
8
8
|
* Validation configuration for Forman Schema fields
|
|
9
9
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { JSONSchema7 } from 'json-schema';
|
|
|
3
3
|
/**
|
|
4
4
|
* Valid Forman Schema field types
|
|
5
5
|
*/
|
|
6
|
-
type FormanSchemaFieldType = 'aiagent' | 'account' | 'hook' | 'device' | 'keychain' | 'datastore' | 'udt' | 'scenario' | 'array' | 'collection' | 'text' | 'number' | 'boolean' | 'checkbox' | 'date' | 'json' | 'buffer' | 'cert' | 'color' | 'email' | 'filename' | 'file' | 'filter' | 'folder' | 'hidden' | 'integer' | 'uinteger' | 'path' | 'pkey' | 'port' | 'select' | 'time' | 'timestamp' | 'timezone' | 'url' | 'uuid' | `account:${string}` | `hook:${string}` | `keychain:${string}` | `device:${string}` | 'banner' | 'markdown' | 'html' | 'separator' | string;
|
|
6
|
+
type FormanSchemaFieldType = 'aiagent' | 'account' | 'hook' | 'device' | 'keychain' | 'datastore' | 'udt' | 'scenario' | 'array' | 'collection' | 'text' | 'number' | 'boolean' | 'checkbox' | 'date' | 'json' | 'buffer' | 'cert' | 'color' | 'email' | 'filename' | 'file' | 'filter' | 'filestorage' | 'folder' | 'hidden' | 'integer' | 'uinteger' | 'path' | 'pkey' | 'port' | 'list' | 'radio' | 'select' | 'time' | 'timestamp' | 'timezone' | 'url' | 'uuid' | `account:${string}` | `hook:${string}` | `keychain:${string}` | `device:${string}` | 'banner' | 'markdown' | 'html' | 'separator' | string;
|
|
7
7
|
/**
|
|
8
8
|
* Validation configuration for Forman Schema fields
|
|
9
9
|
*/
|
package/dist/index.js
CHANGED
|
@@ -64,13 +64,20 @@ function normalizeFormanFieldType(field) {
|
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
|
+
function valuesMatch(a, b) {
|
|
68
|
+
if (a === b) return true;
|
|
69
|
+
if (isObject(a) && isObject(b)) return JSON.stringify(a) === JSON.stringify(b);
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
67
72
|
function findValueInSelectOptions(field, value, optionsAndGroups) {
|
|
68
73
|
if (!optionsAndGroups) return void 0;
|
|
74
|
+
const valueKey = isObject(field.options) && field.options.value ? field.options.value : "value";
|
|
75
|
+
const matches = (option) => valuesMatch(option[valueKey], value);
|
|
69
76
|
if (field.grouped) {
|
|
70
|
-
const found2 = optionsAndGroups.flatMap((group) => "options" in group ? group.options : []).find(
|
|
77
|
+
const found2 = optionsAndGroups.flatMap((group) => "options" in group ? group.options : []).find(matches);
|
|
71
78
|
if (found2) return found2;
|
|
72
79
|
}
|
|
73
|
-
const found = optionsAndGroups.find((option) =>
|
|
80
|
+
const found = optionsAndGroups.find((option) => valueKey in option && matches(option));
|
|
74
81
|
return found;
|
|
75
82
|
}
|
|
76
83
|
function pathToString(path) {
|
|
@@ -531,6 +538,7 @@ var FORMAN_TYPE_MAP = {
|
|
|
531
538
|
email: "string",
|
|
532
539
|
filename: "string",
|
|
533
540
|
file: "string",
|
|
541
|
+
filestorage: "array",
|
|
534
542
|
filter: "array",
|
|
535
543
|
folder: "string",
|
|
536
544
|
hidden: void 0,
|
|
@@ -540,6 +548,9 @@ var FORMAN_TYPE_MAP = {
|
|
|
540
548
|
path: "string",
|
|
541
549
|
pkey: "string",
|
|
542
550
|
port: "number",
|
|
551
|
+
list: "string",
|
|
552
|
+
radio: "string",
|
|
553
|
+
scenario: "string",
|
|
543
554
|
select: "string",
|
|
544
555
|
udttype: "string",
|
|
545
556
|
udtspec: "array",
|
|
@@ -629,7 +640,10 @@ function toJSONSchemaInternal(field, context) {
|
|
|
629
640
|
case "dynamicCollection":
|
|
630
641
|
return handleCollectionType(normalizedField, result, context);
|
|
631
642
|
case "array":
|
|
643
|
+
case "filestorage":
|
|
632
644
|
return handleArrayType(normalizedField, result, context);
|
|
645
|
+
case "list":
|
|
646
|
+
case "radio":
|
|
633
647
|
case "select":
|
|
634
648
|
case "account":
|
|
635
649
|
case "hook":
|
|
@@ -637,6 +651,7 @@ function toJSONSchemaInternal(field, context) {
|
|
|
637
651
|
case "keychain":
|
|
638
652
|
case "datastore":
|
|
639
653
|
case "aiagent":
|
|
654
|
+
case "scenario":
|
|
640
655
|
case "file":
|
|
641
656
|
case "folder":
|
|
642
657
|
return handleSelectOrPathType(normalizedField, result, context);
|
|
@@ -705,7 +720,15 @@ function handleCollectionType(field, result, context) {
|
|
|
705
720
|
return result;
|
|
706
721
|
}
|
|
707
722
|
function handleArrayType(field, result, context) {
|
|
708
|
-
if (field.
|
|
723
|
+
if (field.type === "filestorage") {
|
|
724
|
+
result.items = { type: "string" };
|
|
725
|
+
Object.defineProperty(result, "x-filestorage", {
|
|
726
|
+
configurable: true,
|
|
727
|
+
enumerable: false,
|
|
728
|
+
writable: true,
|
|
729
|
+
value: true
|
|
730
|
+
});
|
|
731
|
+
} else if (field.spec) {
|
|
709
732
|
result.items = toJSONSchemaInternal(
|
|
710
733
|
Array.isArray(field.spec) ? { type: "collection", spec: field.spec } : field.spec,
|
|
711
734
|
{
|
|
@@ -844,6 +867,32 @@ function handleSelectOrPathType(field, result, context) {
|
|
|
844
867
|
writable: true,
|
|
845
868
|
value: appendQueryString(optionsOrGroups, context.domain, context.tail)
|
|
846
869
|
});
|
|
870
|
+
const xFetchOptions = {};
|
|
871
|
+
if (isObject(field.options)) {
|
|
872
|
+
for (const transferKey of ["label", "value"]) {
|
|
873
|
+
const transferValue = field.options[transferKey];
|
|
874
|
+
if (transferValue) xFetchOptions[transferKey] = transferValue;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
if (![
|
|
878
|
+
// Reference Types are distinguished by the Loader Tool Name directly
|
|
879
|
+
...FORMAN_REFERENCE_TYPES,
|
|
880
|
+
// Select is default
|
|
881
|
+
"select",
|
|
882
|
+
// File and Folder are distinguished by the x-path metadata, so we don't need to append it here
|
|
883
|
+
"file",
|
|
884
|
+
"folder"
|
|
885
|
+
].includes(field.type)) {
|
|
886
|
+
xFetchOptions["type"] = field.type;
|
|
887
|
+
}
|
|
888
|
+
if (Object.keys(xFetchOptions).length) {
|
|
889
|
+
Object.defineProperty(result, "x-fetch-options", {
|
|
890
|
+
configurable: true,
|
|
891
|
+
enumerable: true,
|
|
892
|
+
writable: true,
|
|
893
|
+
value: xFetchOptions
|
|
894
|
+
});
|
|
895
|
+
}
|
|
847
896
|
} else {
|
|
848
897
|
let options = optionsOrGroups?.flatMap((optionOrGroup) => {
|
|
849
898
|
if (isOptionGroup(optionOrGroup)) {
|
|
@@ -1112,6 +1161,8 @@ var FORMAN_TYPE_MAP2 = {
|
|
|
1112
1161
|
path: "string",
|
|
1113
1162
|
pkey: "string",
|
|
1114
1163
|
port: "number",
|
|
1164
|
+
list: void 0,
|
|
1165
|
+
radio: void 0,
|
|
1115
1166
|
select: void 0,
|
|
1116
1167
|
udttype: "string",
|
|
1117
1168
|
udtspec: "array",
|
|
@@ -1119,6 +1170,8 @@ var FORMAN_TYPE_MAP2 = {
|
|
|
1119
1170
|
timestamp: "string",
|
|
1120
1171
|
timezone: "string",
|
|
1121
1172
|
upload: "array",
|
|
1173
|
+
filestorage: "array",
|
|
1174
|
+
scenario: "string",
|
|
1122
1175
|
url: "string",
|
|
1123
1176
|
uuid: "string",
|
|
1124
1177
|
any: void 0
|
|
@@ -1322,7 +1375,10 @@ async function validateFormanValue(value, field, context) {
|
|
|
1322
1375
|
case "collection":
|
|
1323
1376
|
return handleCollectionType2(value, normalizedField, context);
|
|
1324
1377
|
case "array":
|
|
1378
|
+
case "filestorage":
|
|
1325
1379
|
return handleArrayType2(value, normalizedField, context);
|
|
1380
|
+
case "list":
|
|
1381
|
+
case "radio":
|
|
1326
1382
|
case "select":
|
|
1327
1383
|
case "account":
|
|
1328
1384
|
case "hook":
|
|
@@ -2014,6 +2070,14 @@ function toFormanSchema(field) {
|
|
|
2014
2070
|
spec
|
|
2015
2071
|
};
|
|
2016
2072
|
case "array":
|
|
2073
|
+
const filestorageMarker = Object.getOwnPropertyDescriptor(field, "x-filestorage");
|
|
2074
|
+
if (filestorageMarker) {
|
|
2075
|
+
return {
|
|
2076
|
+
type: "filestorage",
|
|
2077
|
+
label: noEmpty(field.title),
|
|
2078
|
+
help: noEmpty(field.description)
|
|
2079
|
+
};
|
|
2080
|
+
}
|
|
2017
2081
|
const filterLogic = Object.getOwnPropertyDescriptor(field, "x-filter");
|
|
2018
2082
|
if (filterLogic) {
|
|
2019
2083
|
return {
|