@es-joy/jsoe 0.12.3 → 0.13.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/.nyc_output/out.json +11827 -11581
- package/CHANGES.md +8 -0
- package/demo/index.js +38 -29
- package/dist/formatAndTypeChoices.d.ts +11 -2
- package/dist/formatAndTypeChoices.d.ts.map +1 -1
- package/dist/formats/structuredCloning.d.ts.map +1 -1
- package/dist/formats.d.ts +52 -10
- package/dist/formats.d.ts.map +1 -1
- package/dist/fundamentalTypes/arrayType.d.ts.map +1 -1
- package/dist/fundamentalTypes/dateType.d.ts.map +1 -1
- package/dist/fundamentalTypes/errorType.d.ts.map +1 -1
- package/dist/fundamentalTypes/regexpType.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12201 -0
- package/dist/superTypes/errorsSpecialType.d.ts.map +1 -1
- package/dist/typeChoices.d.ts +4 -0
- package/dist/typeChoices.d.ts.map +1 -1
- package/dist/types.d.ts +308 -74
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/rollup.config.js +10 -0
- package/src/formatAndTypeChoices.js +20 -5
- package/src/formats/indexedDBKey.js +1 -1
- package/src/formats/json.js +1 -1
- package/src/formats/schemaAndArbitrary.js +1 -1
- package/src/formats/schemaOnly.js +1 -1
- package/src/formats/structuredCloning.js +21 -14
- package/src/formats.js +87 -26
- package/src/fundamentalTypes/arrayReferenceType.js +2 -2
- package/src/fundamentalTypes/arrayType.js +43 -23
- package/src/fundamentalTypes/dateType.js +2 -3
- package/src/fundamentalTypes/errorType.js +5 -3
- package/src/fundamentalTypes/regexpType.js +2 -3
- package/src/index.js +1 -1
- package/src/superTypes/errorsSpecialType.js +12 -5
- package/src/typeChoices.js +21 -10
- package/src/types.js +579 -527
|
@@ -32,7 +32,7 @@ const indexedDBKey = {
|
|
|
32
32
|
stateObj.format = 'indexedDBKey';
|
|
33
33
|
return structuredCloning.iterate(records, stateObj);
|
|
34
34
|
},
|
|
35
|
-
getTypesForState (state) {
|
|
35
|
+
getTypesForState (types, state) {
|
|
36
36
|
if (!state || ['array'].includes(state)) {
|
|
37
37
|
return this.types();
|
|
38
38
|
}
|
package/src/formats/json.js
CHANGED
|
@@ -41,7 +41,7 @@ const json = {
|
|
|
41
41
|
return undefined; // Todo: Fix?
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
|
-
getTypesForState (state) {
|
|
44
|
+
getTypesForState (types, state) {
|
|
45
45
|
/* istanbul ignore else -- No other states apparently */
|
|
46
46
|
if (!state || ['array', 'object'].includes(state)) {
|
|
47
47
|
return this.types();
|
|
@@ -2,8 +2,6 @@ import {
|
|
|
2
2
|
Typeson, unescapeKeyPathComponent, structuredCloningThrowing
|
|
3
3
|
} from '../vendor-imports.js';
|
|
4
4
|
|
|
5
|
-
import Formats from '../formats.js';
|
|
6
|
-
import Types from '../types.js';
|
|
7
5
|
import {buildTypeChoices} from '../typeChoices.js';
|
|
8
6
|
import {
|
|
9
7
|
typesonPathToJSONPointer
|
|
@@ -34,6 +32,8 @@ import json from './json.js';
|
|
|
34
32
|
const encapsulateObserver = (stateObj) => {
|
|
35
33
|
const {
|
|
36
34
|
typeNamespace, readonly, format: frmt, schemaContent,
|
|
35
|
+
formats,
|
|
36
|
+
types,
|
|
37
37
|
getPossibleSchemasForPathAndType
|
|
38
38
|
} = stateObj;
|
|
39
39
|
|
|
@@ -106,11 +106,13 @@ const encapsulateObserver = (stateObj) => {
|
|
|
106
106
|
newValue = typesonPathToJSONPointer(cyclicKeypath);
|
|
107
107
|
newType = type === 'array' ? 'arrayReference' : 'objectReference';
|
|
108
108
|
newType = canonicalToAvailableType(
|
|
109
|
-
format, state, newType, value
|
|
109
|
+
types, formats, format, state, newType, value
|
|
110
110
|
); // Todo (low): Add accurate state for second argument
|
|
111
111
|
} else {
|
|
112
112
|
try {
|
|
113
113
|
newType = canonicalToAvailableType(
|
|
114
|
+
types,
|
|
115
|
+
formats,
|
|
114
116
|
format,
|
|
115
117
|
state,
|
|
116
118
|
/**
|
|
@@ -147,7 +149,7 @@ const encapsulateObserver = (stateObj) => {
|
|
|
147
149
|
|
|
148
150
|
if (!stateObj.rootUI) {
|
|
149
151
|
// console.log('vvvv0', newType, newValue);
|
|
150
|
-
stateObj.rootUI =
|
|
152
|
+
stateObj.rootUI = types.getUIForModeAndType({
|
|
151
153
|
readonly,
|
|
152
154
|
typeNamespace,
|
|
153
155
|
type: newType,
|
|
@@ -245,13 +247,13 @@ const encapsulateObserver = (stateObj) => {
|
|
|
245
247
|
}
|
|
246
248
|
|
|
247
249
|
if (!readonly) {
|
|
248
|
-
|
|
250
|
+
types.setValue({
|
|
249
251
|
type: newType,
|
|
250
252
|
// eslint-disable-next-line object-shorthand -- TS
|
|
251
253
|
root: /** @type {HTMLDivElement} */ (root),
|
|
252
254
|
value: newValue
|
|
253
255
|
});
|
|
254
|
-
|
|
256
|
+
types.validate({
|
|
255
257
|
type: newType,
|
|
256
258
|
// eslint-disable-next-line object-shorthand -- TS
|
|
257
259
|
root: /** @type {HTMLDivElement} */ (root),
|
|
@@ -295,6 +297,8 @@ const replaceTypes = (originTypes, replacements) => {
|
|
|
295
297
|
};
|
|
296
298
|
|
|
297
299
|
/**
|
|
300
|
+
* @param {import('../types.js').default} types
|
|
301
|
+
* @param {import('../formats.js').default} formats
|
|
298
302
|
* @param {import('../formats.js').AvailableFormat} format
|
|
299
303
|
* @param {string} state
|
|
300
304
|
* @param {import('../types.js').AvailableType} valType
|
|
@@ -302,10 +306,12 @@ const replaceTypes = (originTypes, replacements) => {
|
|
|
302
306
|
* @throws {Error}
|
|
303
307
|
* @returns {import('../types.js').AvailableType}
|
|
304
308
|
*/
|
|
305
|
-
const canonicalToAvailableType = (
|
|
306
|
-
|
|
309
|
+
const canonicalToAvailableType = (
|
|
310
|
+
types, formats, format, state, valType, v
|
|
311
|
+
) => {
|
|
312
|
+
const frmt = formats.getAvailableFormat(format);
|
|
307
313
|
const {getTypesForState, convertFromTypeson, testInvalid} = frmt;
|
|
308
|
-
const allowableTypes = getTypesForState.call(frmt, state);
|
|
314
|
+
const allowableTypes = getTypesForState.call(frmt, types, state);
|
|
309
315
|
/* istanbul ignore if -- Guard */
|
|
310
316
|
if (!allowableTypes) {
|
|
311
317
|
throw new Error('Unexpected undefined type for state');
|
|
@@ -342,7 +348,7 @@ const canonicalToAvailableType = (format, state, valType, v) => {
|
|
|
342
348
|
allowableTypes.some((allowableType) => {
|
|
343
349
|
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
344
350
|
const typeObj = /** @type {import('../types.js').TypeObject & {childTypes: string[]}} */ (
|
|
345
|
-
|
|
351
|
+
types.getTypeObject(allowableType)
|
|
346
352
|
);
|
|
347
353
|
const {
|
|
348
354
|
valueMatch, superType, childTypes
|
|
@@ -409,12 +415,13 @@ const structuredCloning = {
|
|
|
409
415
|
}
|
|
410
416
|
});
|
|
411
417
|
},
|
|
412
|
-
getTypesForState (state) {
|
|
413
|
-
if (state &&
|
|
414
|
-
const typesForFormat = this.getTypesForState() ||
|
|
418
|
+
getTypesForState (types, state) {
|
|
419
|
+
if (state && types.getContextInfo('structuredCloning', state)) {
|
|
420
|
+
const typesForFormat = this.getTypesForState(types) ||
|
|
415
421
|
/* istanbul ignore next -- types should be an array */
|
|
416
422
|
[];
|
|
417
|
-
|
|
423
|
+
const contextInfo = types.getContextInfo('structuredCloning', state);
|
|
424
|
+
contextInfo.forEach(({type, after}) => {
|
|
418
425
|
const precedingIdx = typesForFormat.indexOf(after);
|
|
419
426
|
typesForFormat.splice(precedingIdx + 1, 0, type);
|
|
420
427
|
});
|
package/src/formats.js
CHANGED
|
@@ -7,6 +7,14 @@ import structuredCloning from './formats/structuredCloning.js';
|
|
|
7
7
|
* @typedef {any} StructuredCloneValue
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* @callback GetTypesForFormatAndState
|
|
12
|
+
* @param {import('./types.js').default} types
|
|
13
|
+
* @param {AvailableFormat} format
|
|
14
|
+
* @param {string} [state]
|
|
15
|
+
* @returns {import('./types.js').AvailableType[]|undefined}
|
|
16
|
+
*/
|
|
17
|
+
|
|
10
18
|
/* schema:
|
|
11
19
|
export const getTypeForFormatStateAndValue = ({format, state, value}) => {
|
|
12
20
|
const valType = new Typeson().register(
|
|
@@ -30,39 +38,92 @@ export const getTypeForFormatStateAndValue = ({format, state, value}) => {
|
|
|
30
38
|
* typesonType: import('./types.js').AvailableType
|
|
31
39
|
* ) => import('./types.js').AvailableType|undefined,
|
|
32
40
|
* iterate: import('./formats/structuredCloning.js').FormatIterator,
|
|
33
|
-
* getTypesForState: (
|
|
41
|
+
* getTypesForState: (
|
|
42
|
+
* types: import('./types.js').default,
|
|
43
|
+
* state?: string
|
|
44
|
+
* ) => undefined|
|
|
34
45
|
* (import('./types.js').AvailableType)[]
|
|
35
46
|
* }} Format
|
|
36
47
|
*/
|
|
37
48
|
|
|
38
|
-
// Using methods ensure we have fresh copies
|
|
39
|
-
const Formats = {
|
|
40
|
-
availableFormats: /** @type {{[key: string]: Format}} */ ({
|
|
41
|
-
indexedDBKey,
|
|
42
|
-
json,
|
|
43
|
-
// Todo (readme): these too? getTypesForState(state)
|
|
44
|
-
/* schema:
|
|
45
|
-
schemaAndArbitrary,
|
|
46
|
-
schemaOnly,
|
|
47
|
-
*/
|
|
48
|
-
structuredCloning
|
|
49
|
-
})
|
|
50
|
-
};
|
|
51
|
-
|
|
52
49
|
/**
|
|
53
|
-
*
|
|
54
|
-
* @param {StructuredCloneValue} record
|
|
55
|
-
* @param {import('./types.js').StateObject} stateObj
|
|
56
|
-
* @returns {Promise<Element>}
|
|
50
|
+
* Class for processing multiple formats.
|
|
57
51
|
*/
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
class Formats {
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
*/
|
|
56
|
+
constructor () {
|
|
57
|
+
// Can enable later (and add tests)
|
|
58
|
+
// if (formats) {
|
|
59
|
+
// this.availableFormats = {};
|
|
60
|
+
// formats.forEach((format) => {
|
|
61
|
+
// let formatValue;
|
|
62
|
+
// switch (format) {
|
|
63
|
+
// case 'indexedDBKey':
|
|
64
|
+
// formatValue = indexedDBKey;
|
|
65
|
+
// break;
|
|
66
|
+
// case 'json':
|
|
67
|
+
// formatValue = json;
|
|
68
|
+
// break;
|
|
69
|
+
// case 'structuredCloning':
|
|
70
|
+
// formatValue = structuredCloning;
|
|
71
|
+
// break;
|
|
72
|
+
// default:
|
|
73
|
+
// throw new Error('Unknown format');
|
|
74
|
+
// }
|
|
75
|
+
// this.availableFormats[format] = formatValue;
|
|
76
|
+
// });
|
|
77
|
+
// return;
|
|
78
|
+
// }
|
|
79
|
+
// Using methods ensure we have fresh copies
|
|
80
|
+
this.availableFormats = /** @type {{[key: string]: Format}} */ ({
|
|
81
|
+
indexedDBKey,
|
|
82
|
+
json,
|
|
83
|
+
// Todo (readme): these too? getTypesForState(types, state)
|
|
84
|
+
/* schema:
|
|
85
|
+
schemaAndArbitrary,
|
|
86
|
+
schemaOnly,
|
|
87
|
+
*/
|
|
88
|
+
structuredCloning
|
|
65
89
|
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param {import('./types.js').default} types
|
|
94
|
+
* @param {AvailableFormat} format
|
|
95
|
+
* @param {StructuredCloneValue} record
|
|
96
|
+
* @param {import('./types.js').StateObject} stateObj
|
|
97
|
+
* @returns {Promise<Element>}
|
|
98
|
+
*/
|
|
99
|
+
async getControlsForFormatAndValue (types, format, record, stateObj) {
|
|
100
|
+
return await this.availableFormats[format].
|
|
101
|
+
iterate(record, {
|
|
102
|
+
...stateObj,
|
|
103
|
+
types,
|
|
104
|
+
formats: this,
|
|
105
|
+
// This had been before `stateObj` but should apparently have precedence
|
|
106
|
+
// or just avoid passing `format` to this function
|
|
107
|
+
format
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @type {GetTypesForFormatAndState}
|
|
113
|
+
*/
|
|
114
|
+
getTypesForFormatAndState (
|
|
115
|
+
types, format, state
|
|
116
|
+
) {
|
|
117
|
+
return this.availableFormats[format].getTypesForState(types, state);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @param {AvailableFormat} format
|
|
122
|
+
* @returns {Format}
|
|
123
|
+
*/
|
|
124
|
+
getAvailableFormat (format) {
|
|
125
|
+
return this.availableFormats[format];
|
|
126
|
+
}
|
|
66
127
|
}
|
|
67
128
|
|
|
68
129
|
export default Formats;
|
|
@@ -176,12 +176,12 @@ const arrayReferenceType = {
|
|
|
176
176
|
valid: true
|
|
177
177
|
};
|
|
178
178
|
},
|
|
179
|
-
validateAll ({topRoot}) {
|
|
179
|
+
validateAll ({types, topRoot}) {
|
|
180
180
|
const type = /** @type {import('../types.js').AvailableType} */ (
|
|
181
181
|
`${this.type}Reference`
|
|
182
182
|
);
|
|
183
183
|
$$e(topRoot, `div[data-type="${type}"]`).forEach((root) => {
|
|
184
|
-
|
|
184
|
+
types.validate({
|
|
185
185
|
type,
|
|
186
186
|
// eslint-disable-next-line object-shorthand -- TS
|
|
187
187
|
root: /** @type {HTMLDivElement} */ (root),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {jml, nbsp} from '../vendor-imports.js';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import {getPropertyValueFromLegend} from '../types.js';
|
|
4
4
|
import {$e, U, DOM} from '../utils/templateUtils.js';
|
|
5
5
|
import dialogs from '../utils/dialogs.js';
|
|
6
6
|
import {
|
|
@@ -97,7 +97,10 @@ const arrayType = {
|
|
|
97
97
|
} = /** @type {import('../types.js').RootInfo} */ (info);
|
|
98
98
|
// eslint-disable-next-line prefer-destructuring -- TS
|
|
99
99
|
const format = /** @type {import('../types.js').RootInfo} */ (info).format;
|
|
100
|
-
|
|
100
|
+
// eslint-disable-next-line prefer-destructuring -- TS
|
|
101
|
+
const types = /** @type {import('../types.js').default} */ (
|
|
102
|
+
/** @type {import('../types.js').RootInfo} */ (info).types
|
|
103
|
+
);
|
|
101
104
|
const {sparse} = this;
|
|
102
105
|
const state = sparse
|
|
103
106
|
? 'arrayNonindexKeys'
|
|
@@ -148,7 +151,7 @@ const arrayType = {
|
|
|
148
151
|
}
|
|
149
152
|
let v, beginOnly, assign;
|
|
150
153
|
try {
|
|
151
|
-
[v, stringVal, beginOnly, assign] =
|
|
154
|
+
[v, stringVal, beginOnly, assign] = types.getValueForString(
|
|
152
155
|
stringVal,
|
|
153
156
|
{
|
|
154
157
|
firstRun: false,
|
|
@@ -205,7 +208,7 @@ const arrayType = {
|
|
|
205
208
|
stringVal = stringVal.slice(propAndColon[0].length);
|
|
206
209
|
let v, beginOnly, assign;
|
|
207
210
|
try {
|
|
208
|
-
[v, stringVal, beginOnly, assign] =
|
|
211
|
+
[v, stringVal, beginOnly, assign] = types.getValueForString(
|
|
209
212
|
stringVal,
|
|
210
213
|
{
|
|
211
214
|
firstRun: false, format, state,
|
|
@@ -234,7 +237,13 @@ const arrayType = {
|
|
|
234
237
|
parse();
|
|
235
238
|
return {value: retObj, remnant: stringVal};
|
|
236
239
|
},
|
|
237
|
-
getValue ({root, stateObj
|
|
240
|
+
getValue ({root, stateObj, currentPath = ''}) {
|
|
241
|
+
/* istanbul ignore if */
|
|
242
|
+
if (!stateObj) {
|
|
243
|
+
throw new Error('TS guard'); // TS guard
|
|
244
|
+
}
|
|
245
|
+
// eslint-disable-next-line prefer-destructuring -- TS
|
|
246
|
+
const types = /** @type {import('../types.js').default} */ (stateObj.types);
|
|
238
247
|
const top = currentPath === '';
|
|
239
248
|
const arrayItems =
|
|
240
249
|
/**
|
|
@@ -267,10 +276,10 @@ const arrayType = {
|
|
|
267
276
|
* @returns {[boolean, any?]}
|
|
268
277
|
*/
|
|
269
278
|
const getValOrRef = (root, currentPathPart) => {
|
|
270
|
-
const value =
|
|
279
|
+
const value = types.getValueForRoot(
|
|
271
280
|
root, stateObj, currentPath + '/' + currentPathPart
|
|
272
281
|
);
|
|
273
|
-
if (stateObj.handlingReference) {
|
|
282
|
+
if ('handlingReference' in stateObj && stateObj.handlingReference) {
|
|
274
283
|
// We deal with references later once object is fully constructed
|
|
275
284
|
stateObj.handlingReference = false;
|
|
276
285
|
return [false];
|
|
@@ -346,7 +355,7 @@ const arrayType = {
|
|
|
346
355
|
},
|
|
347
356
|
|
|
348
357
|
// Try to keep in sync with basic structure of `editUI`
|
|
349
|
-
viewUI ({typeNamespace, type, value, topRoot, resultType, format}) {
|
|
358
|
+
viewUI ({typeNamespace, type, types, value, topRoot, resultType, format}) {
|
|
350
359
|
// const {sparse} = this;
|
|
351
360
|
let itemIndex = -1;
|
|
352
361
|
|
|
@@ -403,7 +412,7 @@ const arrayType = {
|
|
|
403
412
|
schemaContent, schemaState
|
|
404
413
|
}) {
|
|
405
414
|
if (parentType === 'map') {
|
|
406
|
-
const root =
|
|
415
|
+
const root = types.getUIForModeAndType({
|
|
407
416
|
resultType,
|
|
408
417
|
readonly: true,
|
|
409
418
|
typeNamespace, type, topRoot,
|
|
@@ -434,7 +443,7 @@ const arrayType = {
|
|
|
434
443
|
}
|
|
435
444
|
|
|
436
445
|
const fieldset = this.$addArrayElement({propName});
|
|
437
|
-
const root =
|
|
446
|
+
const root = types.getUIForModeAndType({
|
|
438
447
|
resultType,
|
|
439
448
|
readonly: true,
|
|
440
449
|
typeNamespace, type, topRoot,
|
|
@@ -544,6 +553,7 @@ const arrayType = {
|
|
|
544
553
|
// population of the array in the callback
|
|
545
554
|
editUI ({
|
|
546
555
|
typeNamespace, buildTypeChoices, format, // resultType,
|
|
556
|
+
formats, types,
|
|
547
557
|
type, arrayState, topRoot, value, bringIntoFocus = true
|
|
548
558
|
}) {
|
|
549
559
|
const {sparse} = this;
|
|
@@ -634,7 +644,7 @@ const arrayType = {
|
|
|
634
644
|
} else {
|
|
635
645
|
group.before(swapGroup);
|
|
636
646
|
}
|
|
637
|
-
|
|
647
|
+
types.validateAllReferences({
|
|
638
648
|
// eslint-disable-next-line object-shorthand -- TS
|
|
639
649
|
topRoot: /** @type {HTMLDivElement} */ (topRoot)
|
|
640
650
|
}); // Needed
|
|
@@ -817,7 +827,7 @@ const arrayType = {
|
|
|
817
827
|
(this).$validateMapKey();
|
|
818
828
|
|
|
819
829
|
// Needed?
|
|
820
|
-
|
|
830
|
+
types.validateAllReferences({
|
|
821
831
|
// eslint-disable-next-line object-shorthand -- TS
|
|
822
832
|
topRoot: /** @type {HTMLDivElement} */ (topRoot)
|
|
823
833
|
});
|
|
@@ -902,7 +912,7 @@ const arrayType = {
|
|
|
902
912
|
/* await */ this.$validateLegend();
|
|
903
913
|
// Todo (low): We could make this more efficient by waiting
|
|
904
914
|
// until all added (when pre-populating)
|
|
905
|
-
|
|
915
|
+
types.validateAllReferences({
|
|
906
916
|
// eslint-disable-next-line object-shorthand -- TS
|
|
907
917
|
topRoot: /** @type {HTMLDivElement} */ (topRoot)
|
|
908
918
|
}); // Needed
|
|
@@ -1157,7 +1167,17 @@ const arrayType = {
|
|
|
1157
1167
|
parentTypeObject.getValue.call({
|
|
1158
1168
|
...parentTypeObject,
|
|
1159
1169
|
set: false
|
|
1160
|
-
}, {
|
|
1170
|
+
}, {
|
|
1171
|
+
root,
|
|
1172
|
+
stateObj: {
|
|
1173
|
+
types,
|
|
1174
|
+
// eslint-disable-next-line object-shorthand -- TS
|
|
1175
|
+
formats:
|
|
1176
|
+
/** @type {import('../formats.js').default} */ (
|
|
1177
|
+
formats
|
|
1178
|
+
)
|
|
1179
|
+
}
|
|
1180
|
+
})
|
|
1161
1181
|
);
|
|
1162
1182
|
// console.log('values', values);
|
|
1163
1183
|
|
|
@@ -1179,7 +1199,7 @@ const arrayType = {
|
|
|
1179
1199
|
if (!root) {
|
|
1180
1200
|
return null;
|
|
1181
1201
|
}
|
|
1182
|
-
return
|
|
1202
|
+
return types.getFormControlForRoot(root);
|
|
1183
1203
|
});
|
|
1184
1204
|
|
|
1185
1205
|
const control = controls[dupeIndex];
|
|
@@ -1281,7 +1301,7 @@ const arrayType = {
|
|
|
1281
1301
|
}
|
|
1282
1302
|
// Maybe not needed as addition (without renumbering)
|
|
1283
1303
|
// wouldn't yet add type
|
|
1284
|
-
|
|
1304
|
+
types.validateAllReferences({
|
|
1285
1305
|
// eslint-disable-next-line object-shorthand -- TS
|
|
1286
1306
|
topRoot: /** @type {HTMLDivElement} */ (topRoot)
|
|
1287
1307
|
});
|
|
@@ -1307,7 +1327,7 @@ const arrayType = {
|
|
|
1307
1327
|
});
|
|
1308
1328
|
}
|
|
1309
1329
|
// Maybe not needed as removal would remove circular
|
|
1310
|
-
|
|
1330
|
+
types.validateAllReferences({
|
|
1311
1331
|
// eslint-disable-next-line object-shorthand -- TS
|
|
1312
1332
|
topRoot: /** @type {HTMLDivElement} */ (topRoot)
|
|
1313
1333
|
});
|
|
@@ -1419,7 +1439,7 @@ const arrayType = {
|
|
|
1419
1439
|
(this).$addArrayElement({alwaysFocus: true});
|
|
1420
1440
|
// Maybe not needed as addition (without renumbering)
|
|
1421
1441
|
// wouldn't yet add type
|
|
1422
|
-
|
|
1442
|
+
types.validateAllReferences({
|
|
1423
1443
|
// eslint-disable-next-line object-shorthand -- TS
|
|
1424
1444
|
topRoot: /** @type {HTMLDivElement} */ (topRoot)
|
|
1425
1445
|
});
|
|
@@ -1471,7 +1491,7 @@ const arrayType = {
|
|
|
1471
1491
|
fieldset.remove();
|
|
1472
1492
|
});
|
|
1473
1493
|
// Maybe not needed as removal would remove circular
|
|
1474
|
-
|
|
1494
|
+
types.validateAllReferences({
|
|
1475
1495
|
// eslint-disable-next-line object-shorthand -- TS
|
|
1476
1496
|
topRoot: /** @type {HTMLDivElement} */ (topRoot)
|
|
1477
1497
|
});
|
|
@@ -1565,7 +1585,7 @@ const arrayType = {
|
|
|
1565
1585
|
).$redrawMoveArrows();
|
|
1566
1586
|
}
|
|
1567
1587
|
// Maybe not needed as removal would remove circular
|
|
1568
|
-
|
|
1588
|
+
types.validateAllReferences({
|
|
1569
1589
|
// eslint-disable-next-line object-shorthand -- TS
|
|
1570
1590
|
topRoot: /** @type {HTMLDivElement} */ (topRoot)
|
|
1571
1591
|
});
|
|
@@ -1587,7 +1607,7 @@ const arrayType = {
|
|
|
1587
1607
|
itemIndex = -1;
|
|
1588
1608
|
}
|
|
1589
1609
|
// Maybe not needed as removal would remove circular
|
|
1590
|
-
|
|
1610
|
+
types.validateAllReferences({
|
|
1591
1611
|
// eslint-disable-next-line object-shorthand -- TS
|
|
1592
1612
|
topRoot: /** @type {HTMLDivElement} */ (topRoot)
|
|
1593
1613
|
});
|
|
@@ -1642,13 +1662,13 @@ const arrayType = {
|
|
|
1642
1662
|
// from `errorsSpecialType` (and `filelistType`)
|
|
1643
1663
|
if (setAValue) {
|
|
1644
1664
|
const typeObj = /** @type {import('../types.js').TypeObject} */ (
|
|
1645
|
-
|
|
1665
|
+
types.getTypeObject(type)
|
|
1646
1666
|
);
|
|
1647
1667
|
if (typeObj.setValue) {
|
|
1648
1668
|
typeObj.setValue({root, value});
|
|
1649
1669
|
}
|
|
1650
1670
|
}
|
|
1651
|
-
|
|
1671
|
+
types.validate({type, root, topRoot});
|
|
1652
1672
|
return root;
|
|
1653
1673
|
},
|
|
1654
1674
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {jml} from '../vendor-imports.js';
|
|
2
2
|
import {$e} from '../utils/templateUtils.js';
|
|
3
|
-
import Types from '../types.js';
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* @typedef {(
|
|
@@ -94,7 +93,7 @@ const dateType = {
|
|
|
94
93
|
},
|
|
95
94
|
// Change to default to `new Date()` when can't be `NaN`
|
|
96
95
|
// value (keys)?
|
|
97
|
-
editUI ({typeNamespace, value = ''}) {
|
|
96
|
+
editUI ({typeNamespace, types, value = ''}) {
|
|
98
97
|
const notANum = this.isValueInvalid(value);
|
|
99
98
|
const invalid = this.valid
|
|
100
99
|
? ''
|
|
@@ -124,7 +123,7 @@ const dateType = {
|
|
|
124
123
|
const root = /** @type {HTMLDivElement} */ (
|
|
125
124
|
label.parentElement
|
|
126
125
|
);
|
|
127
|
-
|
|
126
|
+
types.validate({type: 'date', root});
|
|
128
127
|
}
|
|
129
128
|
},
|
|
130
129
|
$on: {
|
|
@@ -169,7 +169,7 @@ const errorType = {
|
|
|
169
169
|
return errObj;
|
|
170
170
|
},
|
|
171
171
|
viewUI (
|
|
172
|
-
{value: o, format}
|
|
172
|
+
{value: o, types, format}
|
|
173
173
|
) {
|
|
174
174
|
return /** @type {import('jamilih').JamilihArray} */ ([
|
|
175
175
|
'div', {dataset: {type: 'error'}}, [
|
|
@@ -208,7 +208,8 @@ const errorType = {
|
|
|
208
208
|
o.cause
|
|
209
209
|
? this.viewUI({
|
|
210
210
|
format,
|
|
211
|
-
value: o.cause
|
|
211
|
+
value: o.cause,
|
|
212
|
+
types
|
|
212
213
|
})
|
|
213
214
|
: ''
|
|
214
215
|
]]
|
|
@@ -216,7 +217,7 @@ const errorType = {
|
|
|
216
217
|
]
|
|
217
218
|
]);
|
|
218
219
|
},
|
|
219
|
-
editUI ({typeNamespace, value = {
|
|
220
|
+
editUI ({typeNamespace, types, value = {
|
|
220
221
|
message: '',
|
|
221
222
|
name: '',
|
|
222
223
|
fileName: '',
|
|
@@ -382,6 +383,7 @@ const errorType = {
|
|
|
382
383
|
if (!causeContents?.children.length) {
|
|
383
384
|
const editui = component.editUI({
|
|
384
385
|
typeNamespace,
|
|
386
|
+
types,
|
|
385
387
|
value: value.cause
|
|
386
388
|
});
|
|
387
389
|
jml(...editui, causeContents);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {jml} from '../vendor-imports.js';
|
|
2
2
|
import {$e} from '../utils/templateUtils.js';
|
|
3
|
-
import Types from '../types.js';
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* @type {import('../types.js').TypeObject & {allowedFlags: string[]}}
|
|
@@ -65,7 +64,7 @@ const regexpType = {
|
|
|
65
64
|
viewUI ({value}) {
|
|
66
65
|
return ['i', {dataset: {type: 'regexp'}}, [String(value)]];
|
|
67
66
|
},
|
|
68
|
-
editUI ({typeNamespace, value = {source: '', flags: ''}}) {
|
|
67
|
+
editUI ({typeNamespace, types, value = {source: '', flags: ''}}) {
|
|
69
68
|
// Todo (low): Add RegExp syntax highlighter
|
|
70
69
|
const select = /** @type {HTMLSelectElement} */ (jml(
|
|
71
70
|
'select',
|
|
@@ -107,7 +106,7 @@ const regexpType = {
|
|
|
107
106
|
// Could be disallowed flags; we might instead try in
|
|
108
107
|
// advance which will work
|
|
109
108
|
select.addEventListener('change', () => {
|
|
110
|
-
|
|
109
|
+
types.validate({type: 'regexp', root});
|
|
111
110
|
});
|
|
112
111
|
return [root];
|
|
113
112
|
}
|
package/src/index.js
CHANGED