@makehq/forman-schema 1.11.1 → 1.12.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/dist/index.cjs +13 -6
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +13 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1056,6 +1056,9 @@ function processNestedDirective(field, nested, domain, result, context) {
|
|
|
1056
1056
|
}
|
|
1057
1057
|
|
|
1058
1058
|
// src/validator.ts
|
|
1059
|
+
function fieldAllowsCustomValue(field) {
|
|
1060
|
+
return field.mappable === true || field.editable === true;
|
|
1061
|
+
}
|
|
1059
1062
|
function hasPlaceholderNested(field) {
|
|
1060
1063
|
if (!isObject(field.options)) return false;
|
|
1061
1064
|
const placeholder = field.options.placeholder;
|
|
@@ -1158,6 +1161,7 @@ async function validateFormanWithDomainsInternal(domains, options) {
|
|
|
1158
1161
|
seenFields: /* @__PURE__ */ new Set(),
|
|
1159
1162
|
fieldStates: [],
|
|
1160
1163
|
schemaFields: [],
|
|
1164
|
+
allowDynamicValues: domains[domain].allowDynamicValues ?? options?.allowDynamicValues ?? false,
|
|
1161
1165
|
validateFields: (fields, context) => {
|
|
1162
1166
|
return validateFormanValue(
|
|
1163
1167
|
domains[domain].values,
|
|
@@ -1308,7 +1312,7 @@ async function validateFormanValue(value, field, context) {
|
|
|
1308
1312
|
};
|
|
1309
1313
|
}
|
|
1310
1314
|
if (containsIMLExpression(value)) {
|
|
1311
|
-
if (normalizedField.mappable === false) {
|
|
1315
|
+
if (normalizedField.mappable === false || !context.roots[context.domain].allowDynamicValues) {
|
|
1312
1316
|
return {
|
|
1313
1317
|
valid: false,
|
|
1314
1318
|
errors: [
|
|
@@ -1677,7 +1681,7 @@ async function handlePathType(value, field, context) {
|
|
|
1677
1681
|
});
|
|
1678
1682
|
const selectedOption = selectableOptions.find((candidate) => candidate.value === levelSelectedValue);
|
|
1679
1683
|
if (!selectedOption) {
|
|
1680
|
-
if (optionsFromRPC) {
|
|
1684
|
+
if (optionsFromRPC && (context.roots[context.domain].allowDynamicValues || fieldAllowsCustomValue(field))) {
|
|
1681
1685
|
warnings.push({
|
|
1682
1686
|
domain: context.domain,
|
|
1683
1687
|
path: context.path.join("."),
|
|
@@ -1783,7 +1787,7 @@ async function handleSelectType(value, field, context) {
|
|
|
1783
1787
|
optionsOrGroups
|
|
1784
1788
|
);
|
|
1785
1789
|
if (!found) {
|
|
1786
|
-
(optionsFromRPC ? warnings : errors).push({
|
|
1790
|
+
(optionsFromRPC && (context.roots[context.domain].allowDynamicValues || fieldAllowsCustomValue(field)) ? warnings : errors).push({
|
|
1787
1791
|
domain: context.domain,
|
|
1788
1792
|
path: context.path.join("."),
|
|
1789
1793
|
message: `Value '${singleValue}' not found in options.`
|
|
@@ -1791,7 +1795,7 @@ async function handleSelectType(value, field, context) {
|
|
|
1791
1795
|
hasUnresolvedValue = true;
|
|
1792
1796
|
}
|
|
1793
1797
|
}
|
|
1794
|
-
if (optionsFromRPC && hasUnresolvedValue) {
|
|
1798
|
+
if (optionsFromRPC && (context.roots[context.domain].allowDynamicValues || fieldAllowsCustomValue(field)) && hasUnresolvedValue) {
|
|
1795
1799
|
context.roots[context.domain].fieldStates.push({
|
|
1796
1800
|
path: context.path,
|
|
1797
1801
|
state: { mode: "edit" }
|
|
@@ -1828,7 +1832,7 @@ async function handleSelectType(value, field, context) {
|
|
|
1828
1832
|
} else {
|
|
1829
1833
|
const item = findValueInSelectOptions(field, value, optionsOrGroups);
|
|
1830
1834
|
if (!item) {
|
|
1831
|
-
if (optionsFromRPC) {
|
|
1835
|
+
if (optionsFromRPC && (context.roots[context.domain].allowDynamicValues || fieldAllowsCustomValue(field))) {
|
|
1832
1836
|
warnings.push({
|
|
1833
1837
|
domain: context.domain,
|
|
1834
1838
|
path: context.path.join("."),
|
|
@@ -2158,7 +2162,10 @@ function validateFormanWithDomains(domains, options) {
|
|
|
2158
2162
|
return validateFormanWithDomainsInternal(domains, options);
|
|
2159
2163
|
}
|
|
2160
2164
|
function validateForman(values, schema, options, restoreExtras) {
|
|
2161
|
-
return validateFormanWithDomains(
|
|
2165
|
+
return validateFormanWithDomains(
|
|
2166
|
+
{ default: { values, schema, restoreExtras, allowDynamicValues: options?.allowDynamicValues } },
|
|
2167
|
+
options
|
|
2168
|
+
);
|
|
2162
2169
|
}
|
|
2163
2170
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2164
2171
|
0 && (module.exports = {
|
package/dist/index.d.cts
CHANGED
|
@@ -53,6 +53,8 @@ type FormanSchemaField = {
|
|
|
53
53
|
disabled?: boolean;
|
|
54
54
|
/** Whether the field is mappable */
|
|
55
55
|
mappable?: boolean;
|
|
56
|
+
/** Whether the field allows custom (typed-in) values even when dynamic values are not allowed in the domain */
|
|
57
|
+
editable?: boolean;
|
|
56
58
|
/** Whether the user will be able to insert new lines in GUI (a textarea will be displayed instead of the text field) */
|
|
57
59
|
multiline?: boolean;
|
|
58
60
|
/** Whether the select field allows multiple values */
|
|
@@ -231,6 +233,10 @@ type FormanValidationOptions = {
|
|
|
231
233
|
resolveRemote?(path: string, data: Record<string, unknown>): Promise<unknown>;
|
|
232
234
|
/** Maps domain names used in nested.domain to actual domain keys passed to validateFormanWithDomains */
|
|
233
235
|
domainAliases?: Record<string, string>;
|
|
236
|
+
/** Whether to allow dynamic values (IML expressions, unresolved RPC options).
|
|
237
|
+
* When false (default), IML expressions cause errors and unresolved RPC options are treated as errors.
|
|
238
|
+
* Applies as a global default; can be overridden per-domain in validateFormanWithDomains(). */
|
|
239
|
+
allowDynamicValues?: boolean;
|
|
234
240
|
};
|
|
235
241
|
|
|
236
242
|
/**
|
|
@@ -257,6 +263,9 @@ declare function validateFormanWithDomains(domains: Record<string, {
|
|
|
257
263
|
schema: FormanSchemaField[];
|
|
258
264
|
/** Extra values injected into restore states, keyed by string path (dot notation, `[index]`, backtick-escaping). */
|
|
259
265
|
restoreExtras?: Record<string, Record<string, unknown>>;
|
|
266
|
+
/** Whether the domain allows dynamic values (IML expressions, unresolved RPC select options).
|
|
267
|
+
* Defaults to false. When false, IML expressions cause errors and unresolved RPC options are treated as errors. */
|
|
268
|
+
allowDynamicValues?: boolean;
|
|
260
269
|
}>, options?: FormanValidationOptions): Promise<FormanValidationResult>;
|
|
261
270
|
/**
|
|
262
271
|
* Validates a simple Forman values against a schema
|
package/dist/index.d.ts
CHANGED
|
@@ -53,6 +53,8 @@ type FormanSchemaField = {
|
|
|
53
53
|
disabled?: boolean;
|
|
54
54
|
/** Whether the field is mappable */
|
|
55
55
|
mappable?: boolean;
|
|
56
|
+
/** Whether the field allows custom (typed-in) values even when dynamic values are not allowed in the domain */
|
|
57
|
+
editable?: boolean;
|
|
56
58
|
/** Whether the user will be able to insert new lines in GUI (a textarea will be displayed instead of the text field) */
|
|
57
59
|
multiline?: boolean;
|
|
58
60
|
/** Whether the select field allows multiple values */
|
|
@@ -231,6 +233,10 @@ type FormanValidationOptions = {
|
|
|
231
233
|
resolveRemote?(path: string, data: Record<string, unknown>): Promise<unknown>;
|
|
232
234
|
/** Maps domain names used in nested.domain to actual domain keys passed to validateFormanWithDomains */
|
|
233
235
|
domainAliases?: Record<string, string>;
|
|
236
|
+
/** Whether to allow dynamic values (IML expressions, unresolved RPC options).
|
|
237
|
+
* When false (default), IML expressions cause errors and unresolved RPC options are treated as errors.
|
|
238
|
+
* Applies as a global default; can be overridden per-domain in validateFormanWithDomains(). */
|
|
239
|
+
allowDynamicValues?: boolean;
|
|
234
240
|
};
|
|
235
241
|
|
|
236
242
|
/**
|
|
@@ -257,6 +263,9 @@ declare function validateFormanWithDomains(domains: Record<string, {
|
|
|
257
263
|
schema: FormanSchemaField[];
|
|
258
264
|
/** Extra values injected into restore states, keyed by string path (dot notation, `[index]`, backtick-escaping). */
|
|
259
265
|
restoreExtras?: Record<string, Record<string, unknown>>;
|
|
266
|
+
/** Whether the domain allows dynamic values (IML expressions, unresolved RPC select options).
|
|
267
|
+
* Defaults to false. When false, IML expressions cause errors and unresolved RPC options are treated as errors. */
|
|
268
|
+
allowDynamicValues?: boolean;
|
|
260
269
|
}>, options?: FormanValidationOptions): Promise<FormanValidationResult>;
|
|
261
270
|
/**
|
|
262
271
|
* Validates a simple Forman values against a schema
|
package/dist/index.js
CHANGED
|
@@ -1027,6 +1027,9 @@ function processNestedDirective(field, nested, domain, result, context) {
|
|
|
1027
1027
|
}
|
|
1028
1028
|
|
|
1029
1029
|
// src/validator.ts
|
|
1030
|
+
function fieldAllowsCustomValue(field) {
|
|
1031
|
+
return field.mappable === true || field.editable === true;
|
|
1032
|
+
}
|
|
1030
1033
|
function hasPlaceholderNested(field) {
|
|
1031
1034
|
if (!isObject(field.options)) return false;
|
|
1032
1035
|
const placeholder = field.options.placeholder;
|
|
@@ -1129,6 +1132,7 @@ async function validateFormanWithDomainsInternal(domains, options) {
|
|
|
1129
1132
|
seenFields: /* @__PURE__ */ new Set(),
|
|
1130
1133
|
fieldStates: [],
|
|
1131
1134
|
schemaFields: [],
|
|
1135
|
+
allowDynamicValues: domains[domain].allowDynamicValues ?? options?.allowDynamicValues ?? false,
|
|
1132
1136
|
validateFields: (fields, context) => {
|
|
1133
1137
|
return validateFormanValue(
|
|
1134
1138
|
domains[domain].values,
|
|
@@ -1279,7 +1283,7 @@ async function validateFormanValue(value, field, context) {
|
|
|
1279
1283
|
};
|
|
1280
1284
|
}
|
|
1281
1285
|
if (containsIMLExpression(value)) {
|
|
1282
|
-
if (normalizedField.mappable === false) {
|
|
1286
|
+
if (normalizedField.mappable === false || !context.roots[context.domain].allowDynamicValues) {
|
|
1283
1287
|
return {
|
|
1284
1288
|
valid: false,
|
|
1285
1289
|
errors: [
|
|
@@ -1648,7 +1652,7 @@ async function handlePathType(value, field, context) {
|
|
|
1648
1652
|
});
|
|
1649
1653
|
const selectedOption = selectableOptions.find((candidate) => candidate.value === levelSelectedValue);
|
|
1650
1654
|
if (!selectedOption) {
|
|
1651
|
-
if (optionsFromRPC) {
|
|
1655
|
+
if (optionsFromRPC && (context.roots[context.domain].allowDynamicValues || fieldAllowsCustomValue(field))) {
|
|
1652
1656
|
warnings.push({
|
|
1653
1657
|
domain: context.domain,
|
|
1654
1658
|
path: context.path.join("."),
|
|
@@ -1754,7 +1758,7 @@ async function handleSelectType(value, field, context) {
|
|
|
1754
1758
|
optionsOrGroups
|
|
1755
1759
|
);
|
|
1756
1760
|
if (!found) {
|
|
1757
|
-
(optionsFromRPC ? warnings : errors).push({
|
|
1761
|
+
(optionsFromRPC && (context.roots[context.domain].allowDynamicValues || fieldAllowsCustomValue(field)) ? warnings : errors).push({
|
|
1758
1762
|
domain: context.domain,
|
|
1759
1763
|
path: context.path.join("."),
|
|
1760
1764
|
message: `Value '${singleValue}' not found in options.`
|
|
@@ -1762,7 +1766,7 @@ async function handleSelectType(value, field, context) {
|
|
|
1762
1766
|
hasUnresolvedValue = true;
|
|
1763
1767
|
}
|
|
1764
1768
|
}
|
|
1765
|
-
if (optionsFromRPC && hasUnresolvedValue) {
|
|
1769
|
+
if (optionsFromRPC && (context.roots[context.domain].allowDynamicValues || fieldAllowsCustomValue(field)) && hasUnresolvedValue) {
|
|
1766
1770
|
context.roots[context.domain].fieldStates.push({
|
|
1767
1771
|
path: context.path,
|
|
1768
1772
|
state: { mode: "edit" }
|
|
@@ -1799,7 +1803,7 @@ async function handleSelectType(value, field, context) {
|
|
|
1799
1803
|
} else {
|
|
1800
1804
|
const item = findValueInSelectOptions(field, value, optionsOrGroups);
|
|
1801
1805
|
if (!item) {
|
|
1802
|
-
if (optionsFromRPC) {
|
|
1806
|
+
if (optionsFromRPC && (context.roots[context.domain].allowDynamicValues || fieldAllowsCustomValue(field))) {
|
|
1803
1807
|
warnings.push({
|
|
1804
1808
|
domain: context.domain,
|
|
1805
1809
|
path: context.path.join("."),
|
|
@@ -2129,7 +2133,10 @@ function validateFormanWithDomains(domains, options) {
|
|
|
2129
2133
|
return validateFormanWithDomainsInternal(domains, options);
|
|
2130
2134
|
}
|
|
2131
2135
|
function validateForman(values, schema, options, restoreExtras) {
|
|
2132
|
-
return validateFormanWithDomains(
|
|
2136
|
+
return validateFormanWithDomains(
|
|
2137
|
+
{ default: { values, schema, restoreExtras, allowDynamicValues: options?.allowDynamicValues } },
|
|
2138
|
+
options
|
|
2139
|
+
);
|
|
2133
2140
|
}
|
|
2134
2141
|
export {
|
|
2135
2142
|
toFormanSchema,
|