@versionzero/schema 1.0.1 → 1.1.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
CHANGED
package/src/schema-resolver.js
CHANGED
|
@@ -51,6 +51,8 @@ export function registerCoreLibrary(libraryFn) {
|
|
|
51
51
|
/** @import { SchemaData } from './types.js' */
|
|
52
52
|
/** @import { ValueProcessorDefinition, ValueProcessorSpec, ValueProcessorBuilder, ValueProcessorFunction, ValueProcessorArgs, ValueProcessorParameter, KeywordValueProcessorSpec } from './value-processor/value-processor.js' */
|
|
53
53
|
|
|
54
|
+
/** @typedef {{name:string, namespace?:string, schema:Schema}} RegisteredSchemaInfo */
|
|
55
|
+
|
|
54
56
|
/**
|
|
55
57
|
* The SchemaResolver uses its internal registries of named schemas and value processor keywords to
|
|
56
58
|
* convert Schemas containing unresolved references into resolved Schemas that are fully self-contained.
|
|
@@ -58,7 +60,7 @@ export function registerCoreLibrary(libraryFn) {
|
|
|
58
60
|
export class SchemaResolver
|
|
59
61
|
{
|
|
60
62
|
/**
|
|
61
|
-
* @type {Map<string,
|
|
63
|
+
* @type {Map<string,RegisteredSchemaInfo>}
|
|
62
64
|
*/
|
|
63
65
|
#schemaMap = new Map();
|
|
64
66
|
/**
|
|
@@ -85,7 +87,7 @@ export class SchemaResolver
|
|
|
85
87
|
throw new ResolverError(`Registry can only store Schema instances`);
|
|
86
88
|
}
|
|
87
89
|
const registryName = toKebabCase(name);
|
|
88
|
-
this.#schemaMap.set(registryName, schema);
|
|
90
|
+
this.#schemaMap.set(registryName, {name: registryName, schema});
|
|
89
91
|
return this;
|
|
90
92
|
}
|
|
91
93
|
|
|
@@ -96,11 +98,11 @@ export class SchemaResolver
|
|
|
96
98
|
*/
|
|
97
99
|
getSchema(name) {
|
|
98
100
|
const registryName = toKebabCase(name);
|
|
99
|
-
const
|
|
100
|
-
if (!
|
|
101
|
+
const schemaInfo = this.#schemaMap.get(registryName);
|
|
102
|
+
if (!schemaInfo) {
|
|
101
103
|
throw new ResolverError(`Unable to resolve "${name}"`);
|
|
102
104
|
}
|
|
103
|
-
return schema;
|
|
105
|
+
return schemaInfo.schema;
|
|
104
106
|
}
|
|
105
107
|
|
|
106
108
|
/**
|
|
@@ -113,6 +115,14 @@ export class SchemaResolver
|
|
|
113
115
|
return this.#schemaMap.has(registryName);
|
|
114
116
|
}
|
|
115
117
|
|
|
118
|
+
/**
|
|
119
|
+
* return all registered schemas
|
|
120
|
+
* @returns {RegisteredSchemaInfo[]}
|
|
121
|
+
*/
|
|
122
|
+
listRegisteredSchemas() {
|
|
123
|
+
return [...this.#schemaMap.values()];
|
|
124
|
+
}
|
|
125
|
+
|
|
116
126
|
/**
|
|
117
127
|
* Register a value processor definition
|
|
118
128
|
* @param {ValueProcessorDefinition} definition
|
|
@@ -121,20 +131,24 @@ export class SchemaResolver
|
|
|
121
131
|
registerValueProcessorDefinition(definition) {
|
|
122
132
|
const {keyword, process, description, build} = definition;
|
|
123
133
|
|
|
124
|
-
if (!keyword) {
|
|
134
|
+
if (!keyword || typeof keyword !== 'string') {
|
|
125
135
|
throw new ResolverError('Missing keyword in processor definition');
|
|
126
136
|
}
|
|
127
137
|
|
|
128
138
|
if (process && build) {
|
|
129
|
-
throw new ResolverError(`Processor definition for '
|
|
139
|
+
throw new ResolverError(`Processor definition for '$${keyword}' cannot define both process and build functions`);
|
|
130
140
|
}
|
|
131
141
|
|
|
132
142
|
if (!process && !build) {
|
|
133
|
-
throw new ResolverError(`Processor definition for '
|
|
143
|
+
throw new ResolverError(`Processor definition for '$${keyword}' must have define a process or build function`);
|
|
134
144
|
}
|
|
135
145
|
|
|
136
146
|
if (description && typeof description !== 'string') {
|
|
137
|
-
throw new ResolverError(`Processor definition description for '
|
|
147
|
+
throw new ResolverError(`Processor definition description for '$${keyword}' must be a string`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (this.#constantKeywordProcessors[`${keyword}`]) {
|
|
151
|
+
throw new ResolverError(`Processor keyword conflict with builtin literal '$${keyword}'`)
|
|
138
152
|
}
|
|
139
153
|
|
|
140
154
|
this.#processorMap.set(keyword, definition);
|
|
@@ -176,6 +190,24 @@ export class SchemaResolver
|
|
|
176
190
|
});
|
|
177
191
|
}
|
|
178
192
|
|
|
193
|
+
/**
|
|
194
|
+
* List all registered value processors (and reserved builtins)
|
|
195
|
+
*
|
|
196
|
+
* @returns {ValueProcessorDefinition[]}
|
|
197
|
+
*/
|
|
198
|
+
listValueProcessorDefinitions() {
|
|
199
|
+
|
|
200
|
+
return [
|
|
201
|
+
...Object.entries(this.#constantKeywordProcessors).map(([k,v]) => ({
|
|
202
|
+
keyword: k,
|
|
203
|
+
build: (() => v),
|
|
204
|
+
spec: `$${k}`,
|
|
205
|
+
reserved: true
|
|
206
|
+
})),
|
|
207
|
+
...this.#processorMap.values()
|
|
208
|
+
];
|
|
209
|
+
}
|
|
210
|
+
|
|
179
211
|
|
|
180
212
|
/**
|
|
181
213
|
* Load a library of schemas and/or value processors.
|
|
@@ -209,13 +241,11 @@ export class SchemaResolver
|
|
|
209
241
|
|
|
210
242
|
}
|
|
211
243
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
$true: TRUE_EXECUTOR,
|
|
218
|
-
$false: FALSE_EXECUTOR
|
|
244
|
+
#constantKeywordProcessors = {
|
|
245
|
+
'null': new ComposedValueProcessor(NULL_EXECUTOR, '$null'),
|
|
246
|
+
'undefined': new ComposedValueProcessor(UNDEFINED_EXECUTOR, '$undefined'),
|
|
247
|
+
'true': new ComposedValueProcessor(TRUE_EXECUTOR, '$true'),
|
|
248
|
+
'false': new ComposedValueProcessor(FALSE_EXECUTOR, '$false')
|
|
219
249
|
}
|
|
220
250
|
|
|
221
251
|
/**
|
|
@@ -230,8 +260,8 @@ export class SchemaResolver
|
|
|
230
260
|
}
|
|
231
261
|
const [keyword, rawArgs] = extractKeywordValueProcessorSpec(spec);
|
|
232
262
|
|
|
233
|
-
if (this
|
|
234
|
-
return
|
|
263
|
+
if (this.#constantKeywordProcessors[keyword]) {
|
|
264
|
+
return this.#constantKeywordProcessors[keyword];
|
|
235
265
|
}
|
|
236
266
|
|
|
237
267
|
if (keyword === 'literal') {
|
|
@@ -44,11 +44,13 @@ import { SchemaLocation } from '../schema-location.js';
|
|
|
44
44
|
/**
|
|
45
45
|
* @typedef {object} ValueProcessorDefinition
|
|
46
46
|
* @property {string} keyword
|
|
47
|
+
* @property {string} [namespace]
|
|
47
48
|
* @property {ValueProcessorFunction} [process]
|
|
48
49
|
* @property {ValueProcessorParameter[]} [parameters]
|
|
49
50
|
* @property {string} [description]
|
|
50
51
|
* @property {ValueProcessorBuilder} [build]
|
|
51
52
|
* @property {ValueProcessorDescriber} [describe]
|
|
53
|
+
* @property {boolean} [reserved]
|
|
52
54
|
*/
|
|
53
55
|
|
|
54
56
|
|
|
@@ -9,6 +9,7 @@ export function registerCoreLibrary(libraryFn: (resolver: SchemaResolver, option
|
|
|
9
9
|
/** @typedef {{name:string, [key:string]:any}} SchemaResolverLibraryOptions */
|
|
10
10
|
/** @import { SchemaData } from './types.js' */
|
|
11
11
|
/** @import { ValueProcessorDefinition, ValueProcessorSpec, ValueProcessorBuilder, ValueProcessorFunction, ValueProcessorArgs, ValueProcessorParameter, KeywordValueProcessorSpec } from './value-processor/value-processor.js' */
|
|
12
|
+
/** @typedef {{name:string, namespace?:string, schema:Schema}} RegisteredSchemaInfo */
|
|
12
13
|
/**
|
|
13
14
|
* The SchemaResolver uses its internal registries of named schemas and value processor keywords to
|
|
14
15
|
* convert Schemas containing unresolved references into resolved Schemas that are fully self-contained.
|
|
@@ -33,6 +34,11 @@ export class SchemaResolver {
|
|
|
33
34
|
* @returns {boolean}
|
|
34
35
|
*/
|
|
35
36
|
hasSchema(name: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* return all registered schemas
|
|
39
|
+
* @returns {RegisteredSchemaInfo[]}
|
|
40
|
+
*/
|
|
41
|
+
listRegisteredSchemas(): RegisteredSchemaInfo[];
|
|
36
42
|
/**
|
|
37
43
|
* Register a value processor definition
|
|
38
44
|
* @param {ValueProcessorDefinition} definition
|
|
@@ -54,6 +60,12 @@ export class SchemaResolver {
|
|
|
54
60
|
* @returns {SchemaResolver}
|
|
55
61
|
*/
|
|
56
62
|
registerValueProcessorBuilder(keyword: string, build: ValueProcessorBuilder): SchemaResolver;
|
|
63
|
+
/**
|
|
64
|
+
* List all registered value processors (and reserved builtins)
|
|
65
|
+
*
|
|
66
|
+
* @returns {ValueProcessorDefinition[]}
|
|
67
|
+
*/
|
|
68
|
+
listValueProcessorDefinitions(): ValueProcessorDefinition[];
|
|
57
69
|
/**
|
|
58
70
|
* Load a library of schemas and/or value processors.
|
|
59
71
|
*
|
|
@@ -68,12 +80,6 @@ export class SchemaResolver {
|
|
|
68
80
|
* @returns {Promise<void>}
|
|
69
81
|
*/
|
|
70
82
|
use(libraryFunction: (resolver: SchemaResolver, options: object) => Promise<void> | void, options?: object): Promise<void>;
|
|
71
|
-
_constantKeywords: {
|
|
72
|
-
$null: ConstantExecutor;
|
|
73
|
-
$undefined: ConstantExecutor;
|
|
74
|
-
$true: ConstantExecutor;
|
|
75
|
-
$false: ConstantExecutor;
|
|
76
|
-
};
|
|
77
83
|
/**
|
|
78
84
|
* @param {SchemaCompiler} compiler
|
|
79
85
|
* @param {KeywordValueProcessorSpec} spec
|
|
@@ -131,11 +137,15 @@ export type SchemaResolverLibraryOptions = {
|
|
|
131
137
|
name: string;
|
|
132
138
|
[key: string]: any;
|
|
133
139
|
};
|
|
140
|
+
export type RegisteredSchemaInfo = {
|
|
141
|
+
name: string;
|
|
142
|
+
namespace?: string;
|
|
143
|
+
schema: Schema;
|
|
144
|
+
};
|
|
134
145
|
import { Schema } from './schema.js';
|
|
135
146
|
import type { ValueProcessorDefinition } from './value-processor/value-processor.js';
|
|
136
147
|
import type { ValueProcessorFunction } from './value-processor/value-processor.js';
|
|
137
148
|
import type { ValueProcessorBuilder } from './value-processor/value-processor.js';
|
|
138
|
-
import { ConstantExecutor } from './executor/executor.js';
|
|
139
149
|
import { SchemaCompiler } from './schema-compiler.js';
|
|
140
150
|
import type { KeywordValueProcessorSpec } from './value-processor/value-processor.js';
|
|
141
151
|
import { ValueProcessor } from './value-processor/value-processor.js';
|
|
@@ -31,11 +31,13 @@
|
|
|
31
31
|
/**
|
|
32
32
|
* @typedef {object} ValueProcessorDefinition
|
|
33
33
|
* @property {string} keyword
|
|
34
|
+
* @property {string} [namespace]
|
|
34
35
|
* @property {ValueProcessorFunction} [process]
|
|
35
36
|
* @property {ValueProcessorParameter[]} [parameters]
|
|
36
37
|
* @property {string} [description]
|
|
37
38
|
* @property {ValueProcessorBuilder} [build]
|
|
38
39
|
* @property {ValueProcessorDescriber} [describe]
|
|
40
|
+
* @property {boolean} [reserved]
|
|
39
41
|
*/
|
|
40
42
|
/**
|
|
41
43
|
* @augments {Executor<any>}
|
|
@@ -82,11 +84,13 @@ export type ValueProcessorDescriber = (args: {
|
|
|
82
84
|
} | ValueProcessor[] | undefined) => string | undefined;
|
|
83
85
|
export type ValueProcessorDefinition = {
|
|
84
86
|
keyword: string;
|
|
87
|
+
namespace?: string | undefined;
|
|
85
88
|
process?: ValueProcessorFunction | undefined;
|
|
86
89
|
parameters?: ValueProcessorParameter[] | undefined;
|
|
87
90
|
description?: string | undefined;
|
|
88
91
|
build?: ValueProcessorBuilder | undefined;
|
|
89
92
|
describe?: ValueProcessorDescriber | undefined;
|
|
93
|
+
reserved?: boolean | undefined;
|
|
90
94
|
};
|
|
91
95
|
import { Executor } from '../executor/executor.js';
|
|
92
96
|
import { SchemaLocation } from '../schema-location.js';
|