@makehq/forman-schema 1.2.2 → 1.2.3
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 +41 -27
- package/dist/index.d.cts +52 -2
- package/dist/index.d.ts +52 -2
- package/dist/index.js +41 -27
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,9 @@ function noEmpty(text) {
|
|
|
32
32
|
function isObject(value) {
|
|
33
33
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
34
34
|
}
|
|
35
|
+
function isOptionGroup(value) {
|
|
36
|
+
return "options" in value && Array.isArray(value.options);
|
|
37
|
+
}
|
|
35
38
|
|
|
36
39
|
// src/forman.ts
|
|
37
40
|
var SchemaConversionError = class extends Error {
|
|
@@ -241,41 +244,52 @@ function handleArrayType(field, result, context) {
|
|
|
241
244
|
return result;
|
|
242
245
|
}
|
|
243
246
|
function handleSelectType(field, result, context) {
|
|
244
|
-
const
|
|
247
|
+
const optionsOrGroups = isObject(field.options) ? field.options.store : field.options;
|
|
245
248
|
const nested = isObject(field.options) ? isObject(field.options.nested) ? field.options.nested.store : field.options.nested : void 0;
|
|
246
249
|
const domain = isObject(field.options) ? isObject(field.options.nested) && field.options.nested.domain ? field.options.nested.domain : void 0 : void 0;
|
|
247
|
-
if (typeof
|
|
250
|
+
if (typeof optionsOrGroups === "string") {
|
|
248
251
|
Object.defineProperty(result, "x-fetch", {
|
|
249
252
|
configurable: true,
|
|
250
253
|
enumerable: true,
|
|
251
254
|
writable: true,
|
|
252
|
-
value: appendQueryString(
|
|
253
|
-
});
|
|
254
|
-
} else if (options?.some((option) => option.label || option.nested)) {
|
|
255
|
-
result.oneOf = (options || []).map((option) => {
|
|
256
|
-
const localNested = (isObject(option.nested) ? option.nested.store : option.nested) || nested;
|
|
257
|
-
const localDomain = (isObject(option.nested) && option.nested.domain ? option.nested.domain : domain) || context.domain;
|
|
258
|
-
if (localNested) {
|
|
259
|
-
context.addConditionalFields(
|
|
260
|
-
field.name,
|
|
261
|
-
option.value,
|
|
262
|
-
typeof localNested === "string" ? appendQueryString(localNested, localDomain, [...context.tail, field.name]) : toJSONSchemaInternal(
|
|
263
|
-
{ type: "collection", spec: localNested },
|
|
264
|
-
{
|
|
265
|
-
...context,
|
|
266
|
-
domain: localDomain,
|
|
267
|
-
tail: [...context.tail, field.name]
|
|
268
|
-
}
|
|
269
|
-
)
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
return {
|
|
273
|
-
title: noEmpty(option.label),
|
|
274
|
-
const: option.value
|
|
275
|
-
};
|
|
255
|
+
value: appendQueryString(optionsOrGroups, context.domain, context.tail)
|
|
276
256
|
});
|
|
277
257
|
} else {
|
|
278
|
-
|
|
258
|
+
const options = optionsOrGroups?.some(isOptionGroup) ? optionsOrGroups.flatMap(
|
|
259
|
+
(group) => group.options.map((option) => ({
|
|
260
|
+
...option,
|
|
261
|
+
label: `${group.label}: ${option.label || option.value}`
|
|
262
|
+
}))
|
|
263
|
+
) : optionsOrGroups || [];
|
|
264
|
+
if (options?.some((option) => {
|
|
265
|
+
if (isOptionGroup(option)) return option.options.some((option2) => option2.label || option2.nested);
|
|
266
|
+
return option.label || option.nested;
|
|
267
|
+
})) {
|
|
268
|
+
result.oneOf = (options || []).map((option) => {
|
|
269
|
+
const localNested = (isObject(option.nested) ? option.nested.store : option.nested) || nested;
|
|
270
|
+
const localDomain = (isObject(option.nested) && option.nested.domain ? option.nested.domain : domain) || context.domain;
|
|
271
|
+
if (localNested) {
|
|
272
|
+
context.addConditionalFields(
|
|
273
|
+
field.name,
|
|
274
|
+
option.value,
|
|
275
|
+
typeof localNested === "string" ? appendQueryString(localNested, localDomain, [...context.tail, field.name]) : toJSONSchemaInternal(
|
|
276
|
+
{ type: "collection", spec: localNested },
|
|
277
|
+
{
|
|
278
|
+
...context,
|
|
279
|
+
domain: localDomain,
|
|
280
|
+
tail: [...context.tail, field.name]
|
|
281
|
+
}
|
|
282
|
+
)
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
title: noEmpty(option.label),
|
|
287
|
+
const: option.value
|
|
288
|
+
};
|
|
289
|
+
});
|
|
290
|
+
} else {
|
|
291
|
+
result.enum = (options || []).map((option) => option.value);
|
|
292
|
+
}
|
|
279
293
|
}
|
|
280
294
|
if (nested && domain && domain !== context.domain) {
|
|
281
295
|
if (typeof nested === "string") {
|
package/dist/index.d.cts
CHANGED
|
@@ -34,7 +34,7 @@ type FormanSchemaField = {
|
|
|
34
34
|
/** Default value for the field */
|
|
35
35
|
default?: FormanSchemaValue;
|
|
36
36
|
/** Available options for select type fields */
|
|
37
|
-
options?: FormanSchemaOption[] | FormanSchemaExtendedOptions | string;
|
|
37
|
+
options?: FormanSchemaOption[] | FormanSchemaOptionGroup[] | FormanSchemaExtendedOptions | string;
|
|
38
38
|
/** Help text or description for the field */
|
|
39
39
|
help?: string;
|
|
40
40
|
/** Sub-fields specification for collection or array types */
|
|
@@ -47,7 +47,46 @@ type FormanSchemaField = {
|
|
|
47
47
|
nested?: FormanSchemaNested;
|
|
48
48
|
/** Validation rules */
|
|
49
49
|
validate?: FormanSchemaValidation;
|
|
50
|
+
/** Whether the field is disabled (`false` by default) */
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
/** Whether the field is mappable */
|
|
53
|
+
mappable?: boolean;
|
|
54
|
+
/** Whether the user will be able to insert new lines in GUI (a textarea will be displayed instead of the text field) */
|
|
55
|
+
multiline?: boolean;
|
|
56
|
+
/** Specifies how to treat HTML tags in the field (text only) */
|
|
57
|
+
tags?: 'strip' | 'stripall' | 'escape';
|
|
58
|
+
/** Allowed extension or array of allowed extensions. (filename only) */
|
|
59
|
+
extension?: string | string[];
|
|
60
|
+
/** Semantic type for the field */
|
|
61
|
+
semantic?: string;
|
|
62
|
+
/** Whether to allow time selection (date only, `true` by default) */
|
|
63
|
+
time?: boolean;
|
|
64
|
+
/** Whether the properties of the object will be in the same order as they are defined in the spec (collection only) */
|
|
65
|
+
sequence?: boolean;
|
|
66
|
+
/** Codepage for the field (buffer only) */
|
|
67
|
+
codepage?: string;
|
|
68
|
+
/** Whether the field is grouped (select only) */
|
|
69
|
+
grouped?: boolean;
|
|
70
|
+
/** Whether a mapped value in the select should be validated against the option values. If true, the value is treated as a dynamic and validation is disabled. The value is set to `true` automatically if select options are generated using RPC. */
|
|
71
|
+
dynamic?: boolean;
|
|
72
|
+
/** Mode for the field (select only) */
|
|
73
|
+
mode?: 'edit' | 'choose';
|
|
74
|
+
/** Sort order for the field (select only) */
|
|
75
|
+
sort?: string;
|
|
76
|
+
/** Adds an extra button to the field which opens an extra form. When the form is submitted, a specified RPC is called and the result is set as a new value of the parameter. */
|
|
77
|
+
rpc?: FormanSchemaRPCButton;
|
|
50
78
|
} & Record<`x-${string}`, unknown>;
|
|
79
|
+
/**
|
|
80
|
+
* RPC button allows for dynamic value retrieval from an external source
|
|
81
|
+
*/
|
|
82
|
+
type FormanSchemaRPCButton = {
|
|
83
|
+
/** RPC button label */
|
|
84
|
+
label: string;
|
|
85
|
+
/** RPC button URL */
|
|
86
|
+
url: string;
|
|
87
|
+
/** RPC button parameters */
|
|
88
|
+
parameters: FormanSchemaField[];
|
|
89
|
+
};
|
|
51
90
|
/**
|
|
52
91
|
* Valid Forman Schema values
|
|
53
92
|
*/
|
|
@@ -60,15 +99,26 @@ type FormanSchemaOption = {
|
|
|
60
99
|
value: FormanSchemaValue;
|
|
61
100
|
/** Option label */
|
|
62
101
|
label?: string;
|
|
102
|
+
/** Whether the option is the default */
|
|
103
|
+
default?: boolean;
|
|
63
104
|
/** Nested fields for this option */
|
|
64
105
|
nested?: FormanSchemaNested;
|
|
65
106
|
};
|
|
107
|
+
/**
|
|
108
|
+
* Option group for a select field
|
|
109
|
+
*/
|
|
110
|
+
type FormanSchemaOptionGroup = {
|
|
111
|
+
/** Group label */
|
|
112
|
+
label: string;
|
|
113
|
+
/** Group options */
|
|
114
|
+
options: FormanSchemaOption[];
|
|
115
|
+
};
|
|
66
116
|
/**
|
|
67
117
|
* Extended options for a select field
|
|
68
118
|
*/
|
|
69
119
|
type FormanSchemaExtendedOptions = {
|
|
70
120
|
/** Store for the options */
|
|
71
|
-
store: FormanSchemaOption[] | string;
|
|
121
|
+
store: FormanSchemaOption[] | FormanSchemaOptionGroup[] | string;
|
|
72
122
|
/** Nested fields for every option */
|
|
73
123
|
nested?: FormanSchemaNested;
|
|
74
124
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ type FormanSchemaField = {
|
|
|
34
34
|
/** Default value for the field */
|
|
35
35
|
default?: FormanSchemaValue;
|
|
36
36
|
/** Available options for select type fields */
|
|
37
|
-
options?: FormanSchemaOption[] | FormanSchemaExtendedOptions | string;
|
|
37
|
+
options?: FormanSchemaOption[] | FormanSchemaOptionGroup[] | FormanSchemaExtendedOptions | string;
|
|
38
38
|
/** Help text or description for the field */
|
|
39
39
|
help?: string;
|
|
40
40
|
/** Sub-fields specification for collection or array types */
|
|
@@ -47,7 +47,46 @@ type FormanSchemaField = {
|
|
|
47
47
|
nested?: FormanSchemaNested;
|
|
48
48
|
/** Validation rules */
|
|
49
49
|
validate?: FormanSchemaValidation;
|
|
50
|
+
/** Whether the field is disabled (`false` by default) */
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
/** Whether the field is mappable */
|
|
53
|
+
mappable?: boolean;
|
|
54
|
+
/** Whether the user will be able to insert new lines in GUI (a textarea will be displayed instead of the text field) */
|
|
55
|
+
multiline?: boolean;
|
|
56
|
+
/** Specifies how to treat HTML tags in the field (text only) */
|
|
57
|
+
tags?: 'strip' | 'stripall' | 'escape';
|
|
58
|
+
/** Allowed extension or array of allowed extensions. (filename only) */
|
|
59
|
+
extension?: string | string[];
|
|
60
|
+
/** Semantic type for the field */
|
|
61
|
+
semantic?: string;
|
|
62
|
+
/** Whether to allow time selection (date only, `true` by default) */
|
|
63
|
+
time?: boolean;
|
|
64
|
+
/** Whether the properties of the object will be in the same order as they are defined in the spec (collection only) */
|
|
65
|
+
sequence?: boolean;
|
|
66
|
+
/** Codepage for the field (buffer only) */
|
|
67
|
+
codepage?: string;
|
|
68
|
+
/** Whether the field is grouped (select only) */
|
|
69
|
+
grouped?: boolean;
|
|
70
|
+
/** Whether a mapped value in the select should be validated against the option values. If true, the value is treated as a dynamic and validation is disabled. The value is set to `true` automatically if select options are generated using RPC. */
|
|
71
|
+
dynamic?: boolean;
|
|
72
|
+
/** Mode for the field (select only) */
|
|
73
|
+
mode?: 'edit' | 'choose';
|
|
74
|
+
/** Sort order for the field (select only) */
|
|
75
|
+
sort?: string;
|
|
76
|
+
/** Adds an extra button to the field which opens an extra form. When the form is submitted, a specified RPC is called and the result is set as a new value of the parameter. */
|
|
77
|
+
rpc?: FormanSchemaRPCButton;
|
|
50
78
|
} & Record<`x-${string}`, unknown>;
|
|
79
|
+
/**
|
|
80
|
+
* RPC button allows for dynamic value retrieval from an external source
|
|
81
|
+
*/
|
|
82
|
+
type FormanSchemaRPCButton = {
|
|
83
|
+
/** RPC button label */
|
|
84
|
+
label: string;
|
|
85
|
+
/** RPC button URL */
|
|
86
|
+
url: string;
|
|
87
|
+
/** RPC button parameters */
|
|
88
|
+
parameters: FormanSchemaField[];
|
|
89
|
+
};
|
|
51
90
|
/**
|
|
52
91
|
* Valid Forman Schema values
|
|
53
92
|
*/
|
|
@@ -60,15 +99,26 @@ type FormanSchemaOption = {
|
|
|
60
99
|
value: FormanSchemaValue;
|
|
61
100
|
/** Option label */
|
|
62
101
|
label?: string;
|
|
102
|
+
/** Whether the option is the default */
|
|
103
|
+
default?: boolean;
|
|
63
104
|
/** Nested fields for this option */
|
|
64
105
|
nested?: FormanSchemaNested;
|
|
65
106
|
};
|
|
107
|
+
/**
|
|
108
|
+
* Option group for a select field
|
|
109
|
+
*/
|
|
110
|
+
type FormanSchemaOptionGroup = {
|
|
111
|
+
/** Group label */
|
|
112
|
+
label: string;
|
|
113
|
+
/** Group options */
|
|
114
|
+
options: FormanSchemaOption[];
|
|
115
|
+
};
|
|
66
116
|
/**
|
|
67
117
|
* Extended options for a select field
|
|
68
118
|
*/
|
|
69
119
|
type FormanSchemaExtendedOptions = {
|
|
70
120
|
/** Store for the options */
|
|
71
|
-
store: FormanSchemaOption[] | string;
|
|
121
|
+
store: FormanSchemaOption[] | FormanSchemaOptionGroup[] | string;
|
|
72
122
|
/** Nested fields for every option */
|
|
73
123
|
nested?: FormanSchemaNested;
|
|
74
124
|
};
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,9 @@ function noEmpty(text) {
|
|
|
5
5
|
function isObject(value) {
|
|
6
6
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7
7
|
}
|
|
8
|
+
function isOptionGroup(value) {
|
|
9
|
+
return "options" in value && Array.isArray(value.options);
|
|
10
|
+
}
|
|
8
11
|
|
|
9
12
|
// src/forman.ts
|
|
10
13
|
var SchemaConversionError = class extends Error {
|
|
@@ -214,41 +217,52 @@ function handleArrayType(field, result, context) {
|
|
|
214
217
|
return result;
|
|
215
218
|
}
|
|
216
219
|
function handleSelectType(field, result, context) {
|
|
217
|
-
const
|
|
220
|
+
const optionsOrGroups = isObject(field.options) ? field.options.store : field.options;
|
|
218
221
|
const nested = isObject(field.options) ? isObject(field.options.nested) ? field.options.nested.store : field.options.nested : void 0;
|
|
219
222
|
const domain = isObject(field.options) ? isObject(field.options.nested) && field.options.nested.domain ? field.options.nested.domain : void 0 : void 0;
|
|
220
|
-
if (typeof
|
|
223
|
+
if (typeof optionsOrGroups === "string") {
|
|
221
224
|
Object.defineProperty(result, "x-fetch", {
|
|
222
225
|
configurable: true,
|
|
223
226
|
enumerable: true,
|
|
224
227
|
writable: true,
|
|
225
|
-
value: appendQueryString(
|
|
226
|
-
});
|
|
227
|
-
} else if (options?.some((option) => option.label || option.nested)) {
|
|
228
|
-
result.oneOf = (options || []).map((option) => {
|
|
229
|
-
const localNested = (isObject(option.nested) ? option.nested.store : option.nested) || nested;
|
|
230
|
-
const localDomain = (isObject(option.nested) && option.nested.domain ? option.nested.domain : domain) || context.domain;
|
|
231
|
-
if (localNested) {
|
|
232
|
-
context.addConditionalFields(
|
|
233
|
-
field.name,
|
|
234
|
-
option.value,
|
|
235
|
-
typeof localNested === "string" ? appendQueryString(localNested, localDomain, [...context.tail, field.name]) : toJSONSchemaInternal(
|
|
236
|
-
{ type: "collection", spec: localNested },
|
|
237
|
-
{
|
|
238
|
-
...context,
|
|
239
|
-
domain: localDomain,
|
|
240
|
-
tail: [...context.tail, field.name]
|
|
241
|
-
}
|
|
242
|
-
)
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
return {
|
|
246
|
-
title: noEmpty(option.label),
|
|
247
|
-
const: option.value
|
|
248
|
-
};
|
|
228
|
+
value: appendQueryString(optionsOrGroups, context.domain, context.tail)
|
|
249
229
|
});
|
|
250
230
|
} else {
|
|
251
|
-
|
|
231
|
+
const options = optionsOrGroups?.some(isOptionGroup) ? optionsOrGroups.flatMap(
|
|
232
|
+
(group) => group.options.map((option) => ({
|
|
233
|
+
...option,
|
|
234
|
+
label: `${group.label}: ${option.label || option.value}`
|
|
235
|
+
}))
|
|
236
|
+
) : optionsOrGroups || [];
|
|
237
|
+
if (options?.some((option) => {
|
|
238
|
+
if (isOptionGroup(option)) return option.options.some((option2) => option2.label || option2.nested);
|
|
239
|
+
return option.label || option.nested;
|
|
240
|
+
})) {
|
|
241
|
+
result.oneOf = (options || []).map((option) => {
|
|
242
|
+
const localNested = (isObject(option.nested) ? option.nested.store : option.nested) || nested;
|
|
243
|
+
const localDomain = (isObject(option.nested) && option.nested.domain ? option.nested.domain : domain) || context.domain;
|
|
244
|
+
if (localNested) {
|
|
245
|
+
context.addConditionalFields(
|
|
246
|
+
field.name,
|
|
247
|
+
option.value,
|
|
248
|
+
typeof localNested === "string" ? appendQueryString(localNested, localDomain, [...context.tail, field.name]) : toJSONSchemaInternal(
|
|
249
|
+
{ type: "collection", spec: localNested },
|
|
250
|
+
{
|
|
251
|
+
...context,
|
|
252
|
+
domain: localDomain,
|
|
253
|
+
tail: [...context.tail, field.name]
|
|
254
|
+
}
|
|
255
|
+
)
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
title: noEmpty(option.label),
|
|
260
|
+
const: option.value
|
|
261
|
+
};
|
|
262
|
+
});
|
|
263
|
+
} else {
|
|
264
|
+
result.enum = (options || []).map((option) => option.value);
|
|
265
|
+
}
|
|
252
266
|
}
|
|
253
267
|
if (nested && domain && domain !== context.domain) {
|
|
254
268
|
if (typeof nested === "string") {
|