@json-layout/vocabulary 0.9.0 → 0.10.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/package.json +3 -3
- package/src/normalize.js +31 -11
- package/src/normalized-layout/schema.js +58 -0
- package/src/normalized-layout/schema.json +33 -1
- package/src/normalized-layout/types.ts +9 -0
- package/src/normalized-layout/validate.js +1 -1
- package/src/types.ts +1 -0
- package/types/normalize.d.ts +2 -1
- package/types/normalize.d.ts.map +1 -1
- package/types/normalized-layout/schema.d.ts +36 -0
- package/types/normalized-layout/types.d.ts +9 -0
- package/types/normalized-layout/types.d.ts.map +1 -1
- package/types/normalized-layout/validate.d.ts.map +1 -1
- package/types/types.d.ts +1 -0
- package/types/types.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@json-layout/vocabulary",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Main JSON Layout vocabulary as JSON schemas and Typescript types. Also contains some small utility functions to validate and normalize annotations.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
8
8
|
"import": {
|
|
9
|
-
"
|
|
10
|
-
"
|
|
9
|
+
"types": "./types/index.d.ts",
|
|
10
|
+
"default": "./src/index.js"
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
},
|
package/src/normalize.js
CHANGED
|
@@ -209,10 +209,11 @@ const getType = (schemaFragment) => {
|
|
|
209
209
|
* @param {SchemaFragment} schemaFragment
|
|
210
210
|
* @param {string} schemaPath
|
|
211
211
|
* @param {(text: string) => string} markdown
|
|
212
|
+
* @param {string[]} optionsKeys
|
|
212
213
|
* @param {'oneOf'} [arrayChild]
|
|
213
214
|
* @returns {{normalized: CompObject, errors: string[]}}
|
|
214
215
|
*/
|
|
215
|
-
function getCompObject (layoutKeyword, schemaFragment, schemaPath, markdown, arrayChild) {
|
|
216
|
+
function getCompObject (layoutKeyword, schemaFragment, schemaPath, markdown, optionsKeys, arrayChild) {
|
|
216
217
|
/** @type {string[]} */
|
|
217
218
|
const errors = []
|
|
218
219
|
const key = schemaPath.slice(schemaPath.lastIndexOf('/') + 1)
|
|
@@ -243,14 +244,14 @@ function getCompObject (layoutKeyword, schemaFragment, schemaPath, markdown, arr
|
|
|
243
244
|
|
|
244
245
|
// @ts-ignore
|
|
245
246
|
if (compositeCompNames.includes(partial.comp)) {
|
|
246
|
-
|
|
247
|
+
if (!('title' in partial)) partial.title = schemaFragment.title ?? null
|
|
247
248
|
partial.children = getChildren(getDefaultChildren(schemaFragment), partial.children)
|
|
248
249
|
} else if (partial.comp === 'list') {
|
|
249
|
-
|
|
250
|
+
if (!('title' in partial)) partial.title = schemaFragment.title ?? key
|
|
250
251
|
partial.listEditMode = partial.listEditMode ?? (schemaFragment.items.type === 'object' ? 'inline-single' : 'inline')
|
|
251
252
|
partial.listActions = partial.listActions ?? ['add', 'edit', 'delete', 'duplicate', 'sort']
|
|
252
253
|
} else {
|
|
253
|
-
|
|
254
|
+
if (!('label' in partial)) partial.label = schemaFragment.title ?? key
|
|
254
255
|
}
|
|
255
256
|
|
|
256
257
|
if (['select', 'autocomplete', 'combobox'].includes(partial.comp) && !partial.items) {
|
|
@@ -298,6 +299,20 @@ function getCompObject (layoutKeyword, schemaFragment, schemaPath, markdown, arr
|
|
|
298
299
|
partial.defaultData = ''
|
|
299
300
|
}
|
|
300
301
|
|
|
302
|
+
// options can be set directly in layout and normalized in layout.options
|
|
303
|
+
// TODO: fetch this list from the schema ?
|
|
304
|
+
for (const optionKey of optionsKeys) {
|
|
305
|
+
if (optionKey in partial) {
|
|
306
|
+
partial.options = partial.options ?? {}
|
|
307
|
+
partial.options[optionKey] = partial[optionKey]
|
|
308
|
+
delete partial[optionKey]
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (schemaFragment.readOnly) {
|
|
312
|
+
partial.options = partial.options ?? {}
|
|
313
|
+
if (!('readOnly' in partial.options)) partial.options.readOnly = true
|
|
314
|
+
}
|
|
315
|
+
|
|
301
316
|
if (partial.getOptions !== undefined) partial.getOptions = normalizeExpression(partial.getOptions)
|
|
302
317
|
if (partial.getDefaultData !== undefined) partial.getDefaultData = normalizeExpression(partial.getDefaultData)
|
|
303
318
|
if (partial.getConstData !== undefined) partial.getConstData = normalizeExpression(partial.getConstData)
|
|
@@ -371,10 +386,11 @@ function getCompObject (layoutKeyword, schemaFragment, schemaPath, markdown, arr
|
|
|
371
386
|
* @param {SchemaFragment} schemaFragment
|
|
372
387
|
* @param {string} schemaPath
|
|
373
388
|
* @param {(text: string) => string} markdown
|
|
389
|
+
* @param {string[]} optionsKeys
|
|
374
390
|
* @param {'oneOf'} [arrayChild]
|
|
375
391
|
* @returns {{normalized: NormalizedLayout, errors: string[]}}
|
|
376
392
|
*/
|
|
377
|
-
function getNormalizedLayout (layoutKeyword, schemaFragment, schemaPath, markdown, arrayChild) {
|
|
393
|
+
function getNormalizedLayout (layoutKeyword, schemaFragment, schemaPath, markdown, optionsKeys, arrayChild) {
|
|
378
394
|
if (isPartialSwitch(layoutKeyword)) {
|
|
379
395
|
/** @type {CompObject[]} */
|
|
380
396
|
const normalizedSwitchCases = []
|
|
@@ -385,13 +401,13 @@ function getNormalizedLayout (layoutKeyword, schemaFragment, schemaPath, markdow
|
|
|
385
401
|
}
|
|
386
402
|
for (let i = 0; i < switchCases.length; i++) {
|
|
387
403
|
const switchCase = switchCases[i]
|
|
388
|
-
const compObjectResult = getCompObject(switchCase, schemaFragment, schemaPath, markdown, arrayChild)
|
|
404
|
+
const compObjectResult = getCompObject(switchCase, schemaFragment, schemaPath, markdown, optionsKeys, arrayChild)
|
|
389
405
|
normalizedSwitchCases.push(compObjectResult.normalized)
|
|
390
406
|
for (const error of compObjectResult.errors) errors.push(`switch ${i} - ${error}`)
|
|
391
407
|
}
|
|
392
408
|
return { normalized: { switch: normalizedSwitchCases }, errors: [] }
|
|
393
409
|
} else {
|
|
394
|
-
return getCompObject(layoutKeyword, schemaFragment, schemaPath, markdown, arrayChild)
|
|
410
|
+
return getCompObject(layoutKeyword, schemaFragment, schemaPath, markdown, optionsKeys, arrayChild)
|
|
395
411
|
}
|
|
396
412
|
}
|
|
397
413
|
|
|
@@ -423,14 +439,18 @@ function lighterValidationErrors (errors) {
|
|
|
423
439
|
return errors.map(e => e.message ?? e.keyword)
|
|
424
440
|
}
|
|
425
441
|
|
|
442
|
+
const defaultOptionsKeys = ['readOnly', 'summary', 'titleDepth', 'density', 'removeAdditional', 'validateOn', 'initialValidation', 'defaultOn', 'readOnlyPropertiesMode']
|
|
443
|
+
|
|
426
444
|
/**
|
|
427
445
|
* @param {SchemaFragment} schemaFragment
|
|
428
446
|
* @param {string} schemaPath
|
|
429
447
|
* @param {(text: string) => string} markdown
|
|
448
|
+
* @param {string[]} [optionsKeys]
|
|
430
449
|
* @param {'oneOf'} [arrayChild]
|
|
431
450
|
* @returns {{layout: NormalizedLayout, errors: string[]}}
|
|
432
451
|
*/
|
|
433
|
-
export function normalizeLayoutFragment (schemaFragment, schemaPath, markdown = (src) => src, arrayChild) {
|
|
452
|
+
export function normalizeLayoutFragment (schemaFragment, schemaPath, markdown = (src) => src, optionsKeys, arrayChild) {
|
|
453
|
+
optionsKeys = optionsKeys ? optionsKeys.concat(defaultOptionsKeys) : defaultOptionsKeys
|
|
434
454
|
let layoutKeyword
|
|
435
455
|
if (arrayChild === 'oneOf') {
|
|
436
456
|
layoutKeyword = schemaFragment.oneOfLayout ?? {}
|
|
@@ -440,15 +460,15 @@ export function normalizeLayoutFragment (schemaFragment, schemaPath, markdown =
|
|
|
440
460
|
if (!validateLayoutKeyword(layoutKeyword)) {
|
|
441
461
|
console.error(`layout keyword validation errors at path ${schemaPath}`, layoutKeyword, validateLayoutKeyword.errors)
|
|
442
462
|
return {
|
|
443
|
-
layout: getNormalizedLayout({}, schemaFragment, schemaPath, markdown, arrayChild).normalized,
|
|
463
|
+
layout: getNormalizedLayout({}, schemaFragment, schemaPath, markdown, optionsKeys, arrayChild).normalized,
|
|
444
464
|
errors: lighterValidationErrors(validateLayoutKeyword.errors)
|
|
445
465
|
}
|
|
446
466
|
}
|
|
447
|
-
const normalizedLayout = getNormalizedLayout(layoutKeyword, schemaFragment, schemaPath, markdown, arrayChild)
|
|
467
|
+
const normalizedLayout = getNormalizedLayout(layoutKeyword, schemaFragment, schemaPath, markdown, optionsKeys, arrayChild)
|
|
448
468
|
if (!validateNormalizedLayout(normalizedLayout.normalized)) {
|
|
449
469
|
console.error(`normalized layout validation errors at path ${schemaPath}`, normalizedLayout, validateNormalizedLayout.errors)
|
|
450
470
|
return {
|
|
451
|
-
layout: getNormalizedLayout({}, schemaFragment, schemaPath, markdown, arrayChild).normalized,
|
|
471
|
+
layout: getNormalizedLayout({}, schemaFragment, schemaPath, markdown, optionsKeys, arrayChild).normalized,
|
|
452
472
|
errors: lighterValidationErrors(validateNormalizedLayout.errors)
|
|
453
473
|
}
|
|
454
474
|
// throw new Error(`invalid layout at path ${schemaPath}`, { cause: validateNormalizedLayout.errors })
|
|
@@ -1033,7 +1033,65 @@ export default {
|
|
|
1033
1033
|
"default",
|
|
1034
1034
|
"comfortable",
|
|
1035
1035
|
"compact"
|
|
1036
|
+
],
|
|
1037
|
+
"default": "default"
|
|
1038
|
+
},
|
|
1039
|
+
"removeAdditional": {
|
|
1040
|
+
"description": "true is the same as 'unknown', false is the same as 'none'",
|
|
1041
|
+
"default": "error",
|
|
1042
|
+
"oneOf": [
|
|
1043
|
+
{
|
|
1044
|
+
"type": "boolean"
|
|
1045
|
+
},
|
|
1046
|
+
{
|
|
1047
|
+
"type": "string",
|
|
1048
|
+
"enum": [
|
|
1049
|
+
"unknown",
|
|
1050
|
+
"error",
|
|
1051
|
+
"none"
|
|
1052
|
+
]
|
|
1053
|
+
}
|
|
1036
1054
|
]
|
|
1055
|
+
},
|
|
1056
|
+
"validateOn": {
|
|
1057
|
+
"type": "string",
|
|
1058
|
+
"enum": [
|
|
1059
|
+
"input",
|
|
1060
|
+
"blur",
|
|
1061
|
+
"submit"
|
|
1062
|
+
],
|
|
1063
|
+
"default": "input"
|
|
1064
|
+
},
|
|
1065
|
+
"initialValidation": {
|
|
1066
|
+
"type": "string",
|
|
1067
|
+
"enum": [
|
|
1068
|
+
"never",
|
|
1069
|
+
"always",
|
|
1070
|
+
"withData"
|
|
1071
|
+
],
|
|
1072
|
+
"default": "withData"
|
|
1073
|
+
},
|
|
1074
|
+
"defaultOn": {
|
|
1075
|
+
"type": "string",
|
|
1076
|
+
"enum": [
|
|
1077
|
+
"missing",
|
|
1078
|
+
"empty",
|
|
1079
|
+
"never"
|
|
1080
|
+
],
|
|
1081
|
+
"default": "empty"
|
|
1082
|
+
},
|
|
1083
|
+
"autofocus": {
|
|
1084
|
+
"type": "boolean",
|
|
1085
|
+
"default": false
|
|
1086
|
+
},
|
|
1087
|
+
"readOnlyPropertiesMode": {
|
|
1088
|
+
"type": "string",
|
|
1089
|
+
"enum": [
|
|
1090
|
+
"remove",
|
|
1091
|
+
"hide",
|
|
1092
|
+
"show"
|
|
1093
|
+
],
|
|
1094
|
+
"default": "show"
|
|
1037
1095
|
}
|
|
1038
1096
|
}
|
|
1039
1097
|
}
|
|
@@ -487,7 +487,39 @@
|
|
|
487
487
|
"readOnly": {"type": "boolean", "default": false},
|
|
488
488
|
"summary": {"type": "boolean", "default": false},
|
|
489
489
|
"titleDepth": {"type": "integer", "minimum": 1, "maximum": 6, "default": 2},
|
|
490
|
-
"density": {"type": "string", "enum": ["default", "comfortable", "compact"]}
|
|
490
|
+
"density": {"type": "string", "enum": ["default", "comfortable", "compact"], "default": "default"},
|
|
491
|
+
"removeAdditional": {
|
|
492
|
+
"description": "true is the same as 'unknown', false is the same as 'none'",
|
|
493
|
+
"default": "error",
|
|
494
|
+
"oneOf": [
|
|
495
|
+
{"type": "boolean"},
|
|
496
|
+
{
|
|
497
|
+
"type": "string",
|
|
498
|
+
"enum": ["unknown", "error", "none"]
|
|
499
|
+
}
|
|
500
|
+
]
|
|
501
|
+
},
|
|
502
|
+
"validateOn": {
|
|
503
|
+
"type": "string",
|
|
504
|
+
"enum": ["input", "blur", "submit"],
|
|
505
|
+
"default": "input"
|
|
506
|
+
},
|
|
507
|
+
"initialValidation": {
|
|
508
|
+
"type": "string",
|
|
509
|
+
"enum": ["never", "always", "withData"],
|
|
510
|
+
"default": "withData"
|
|
511
|
+
},
|
|
512
|
+
"defaultOn": {
|
|
513
|
+
"type": "string",
|
|
514
|
+
"enum": ["missing", "empty", "never"],
|
|
515
|
+
"default": "empty"
|
|
516
|
+
},
|
|
517
|
+
"autofocus": {"type": "boolean", "default": false},
|
|
518
|
+
"readOnlyPropertiesMode": {
|
|
519
|
+
"type": "string",
|
|
520
|
+
"enum": ["remove", "hide", "show"],
|
|
521
|
+
"default": "show"
|
|
522
|
+
}
|
|
491
523
|
}
|
|
492
524
|
}
|
|
493
525
|
]
|
|
@@ -51,6 +51,15 @@ export type StateNodeOptionsBase = StateNodeOptionsBaseLib & {
|
|
|
51
51
|
summary?: boolean;
|
|
52
52
|
titleDepth?: number;
|
|
53
53
|
density?: "default" | "comfortable" | "compact";
|
|
54
|
+
/**
|
|
55
|
+
* true is the same as 'unknown', false is the same as 'none'
|
|
56
|
+
*/
|
|
57
|
+
removeAdditional?: boolean | ("unknown" | "error" | "none");
|
|
58
|
+
validateOn?: "input" | "blur" | "submit";
|
|
59
|
+
initialValidation?: "never" | "always" | "withData";
|
|
60
|
+
defaultOn?: "missing" | "empty" | "never";
|
|
61
|
+
autofocus?: boolean;
|
|
62
|
+
readOnlyPropertiesMode?: "remove" | "hide" | "show";
|
|
54
63
|
[k: string]: unknown;
|
|
55
64
|
};
|
|
56
65
|
export type Cols = number;
|