@kumwe/studio-core 0.1.0-alpha.3 → 0.1.0-alpha.5
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/commands.d.ts +8 -2
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +121 -1
- package/dist/commands.js.map +1 -1
- package/dist/extension-sdk.d.ts +46 -0
- package/dist/extension-sdk.d.ts.map +1 -0
- package/dist/extension-sdk.js +188 -0
- package/dist/extension-sdk.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/modes.d.ts +47 -0
- package/dist/modes.d.ts.map +1 -0
- package/dist/modes.js +266 -0
- package/dist/modes.js.map +1 -0
- package/dist/profile-validator.d.ts +47 -0
- package/dist/profile-validator.d.ts.map +1 -0
- package/dist/profile-validator.js +783 -0
- package/dist/profile-validator.js.map +1 -0
- package/dist/schema-profile.d.ts.map +1 -1
- package/dist/schema-profile.js +5 -2
- package/dist/schema-profile.js.map +1 -1
- package/dist/session.d.ts +37 -4
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +75 -10
- package/dist/session.js.map +1 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +14 -14
- package/dist/validation.js.map +1 -1
- package/package.json +2 -3
package/dist/modes.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { BlueprintCommand, BlueprintDocument, StudioCommand, StudioConfiguration, StudioSessionMode } from '@kumwe/studio-protocol';
|
|
2
|
+
/**
|
|
3
|
+
* Every session mode, in stable sorted order. The permitted-command table is
|
|
4
|
+
* total over exactly this set.
|
|
5
|
+
*/
|
|
6
|
+
export declare const STUDIO_SESSION_MODES: readonly StudioSessionMode[];
|
|
7
|
+
/** Every canonical command type addressable by the mode table. */
|
|
8
|
+
export type StudioCommandType = StudioCommand['type'];
|
|
9
|
+
/**
|
|
10
|
+
* The deterministic mode-to-permitted-command table: one immutable set per
|
|
11
|
+
* session mode, shared across calls, so UIs derive disabled affordances from
|
|
12
|
+
* the same source the session enforces. The table is type-level only; the
|
|
13
|
+
* hybrid entries additionally require every affected collection to stay
|
|
14
|
+
* inside a structural authoring region, which the session enforces per
|
|
15
|
+
* command target.
|
|
16
|
+
*/
|
|
17
|
+
export declare function permittedCommandTypes(mode: StudioSessionMode): ReadonlySet<StudioCommandType>;
|
|
18
|
+
/**
|
|
19
|
+
* Flattens a configuration's editing mode, composite, and session state into
|
|
20
|
+
* the single session mode fixed at session creation: a read-only session
|
|
21
|
+
* state always flattens to `read-only`, the hybrid composite flattens to
|
|
22
|
+
* `hybrid`, and every other session keeps its authoring mode. The hybrid
|
|
23
|
+
* composite is invalid with Model mode, mirroring the configuration schema.
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveSessionMode(configuration: Pick<StudioConfiguration, 'composite' | 'mode' | 'sessionState'>): StudioSessionMode;
|
|
26
|
+
/**
|
|
27
|
+
* Fails closed with the stable `mode-forbidden` code when the command type is
|
|
28
|
+
* outside the active mode's permitted set.
|
|
29
|
+
*/
|
|
30
|
+
export declare function assertModePermitsCommandType(mode: StudioSessionMode, type: StudioCommandType): void;
|
|
31
|
+
/**
|
|
32
|
+
* Enforces the bounded-composition rule for one hybrid structure command:
|
|
33
|
+
* every collection the command inserts into, removes from, moves across, or
|
|
34
|
+
* reorders must be a named slot of a node whose authoring policy mode is
|
|
35
|
+
* `structural`; inserted block types must satisfy the structural node's
|
|
36
|
+
* `allowedBlocks` when declared; subtrees containing a `locked` node are
|
|
37
|
+
* never inserted, removed, moved, or duplicated; and document roots are
|
|
38
|
+
* never in bounds. Batch operations are evaluated sequentially against a
|
|
39
|
+
* trial state so later operations may compose nodes earlier operations
|
|
40
|
+
* introduced. A violation fails closed with `mode-forbidden`; a reference
|
|
41
|
+
* the gate cannot resolve is left for the reducer's canonical failure code.
|
|
42
|
+
*
|
|
43
|
+
* The passed document is consumed as trial scratch state and may be mutated;
|
|
44
|
+
* callers pass a clone.
|
|
45
|
+
*/
|
|
46
|
+
export declare function assertHybridCommandInBounds(document: BlueprintDocument, command: BlueprintCommand): void;
|
|
47
|
+
//# sourceMappingURL=modes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modes.d.ts","sourceRoot":"","sources":["../src/modes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAChB,iBAAiB,EAIjB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAGhC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,iBAAiB,EAM3D,CAAC;AAEH,kEAAkE;AAClE,MAAM,MAAM,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;AAoDtD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAE7F;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,GAAG,MAAM,GAAG,cAAc,CAAC,GAC9E,iBAAiB,CAWnB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,iBAAiB,GACtB,IAAI,CAON;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAyCN"}
|
package/dist/modes.js
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { applyOperation, StudioCommandError } from './commands.js';
|
|
2
|
+
/**
|
|
3
|
+
* Every session mode, in stable sorted order. The permitted-command table is
|
|
4
|
+
* total over exactly this set.
|
|
5
|
+
*/
|
|
6
|
+
export const STUDIO_SESSION_MODES = Object.freeze([
|
|
7
|
+
'blueprint',
|
|
8
|
+
'content',
|
|
9
|
+
'hybrid',
|
|
10
|
+
'model',
|
|
11
|
+
'read-only',
|
|
12
|
+
]);
|
|
13
|
+
const BLUEPRINT_STRUCTURE_COMMAND_TYPES = [
|
|
14
|
+
'studio.command/apply-pattern',
|
|
15
|
+
'studio.command/batch',
|
|
16
|
+
'studio.command/duplicate-node',
|
|
17
|
+
'studio.command/insert-node',
|
|
18
|
+
'studio.command/move-node',
|
|
19
|
+
'studio.command/remove-binding',
|
|
20
|
+
'studio.command/remove-node',
|
|
21
|
+
'studio.command/reorder-children',
|
|
22
|
+
'studio.command/reset-inherited-property',
|
|
23
|
+
'studio.command/restore-node',
|
|
24
|
+
'studio.command/set-binding',
|
|
25
|
+
'studio.command/set-property',
|
|
26
|
+
'studio.command/set-size-role',
|
|
27
|
+
'studio.command/unset-property',
|
|
28
|
+
'studio.command/unset-size-role',
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* The structure commands hybrid composition may dispatch when every affected
|
|
32
|
+
* collection stays inside a structural authoring region. Property, binding,
|
|
33
|
+
* size-role, inheritance-reset, and pattern commands remain Blueprint-mode
|
|
34
|
+
* vocabulary.
|
|
35
|
+
*/
|
|
36
|
+
const HYBRID_STRUCTURE_OPERATION_TYPES = [
|
|
37
|
+
'studio.command/duplicate-node',
|
|
38
|
+
'studio.command/insert-node',
|
|
39
|
+
'studio.command/move-node',
|
|
40
|
+
'studio.command/remove-node',
|
|
41
|
+
'studio.command/reorder-children',
|
|
42
|
+
'studio.command/restore-node',
|
|
43
|
+
];
|
|
44
|
+
const PERMITTED_COMMAND_TYPES = Object.freeze({
|
|
45
|
+
blueprint: immutableCommandTypeSet(BLUEPRINT_STRUCTURE_COMMAND_TYPES),
|
|
46
|
+
content: immutableCommandTypeSet(['studio.command/set-field-value']),
|
|
47
|
+
hybrid: immutableCommandTypeSet([
|
|
48
|
+
'studio.command/batch',
|
|
49
|
+
...HYBRID_STRUCTURE_OPERATION_TYPES,
|
|
50
|
+
'studio.command/set-field-value',
|
|
51
|
+
]),
|
|
52
|
+
model: immutableCommandTypeSet(['studio.command/add-model-field']),
|
|
53
|
+
'read-only': immutableCommandTypeSet([]),
|
|
54
|
+
});
|
|
55
|
+
const HYBRID_BATCHABLE_OPERATION_TYPES = immutableCommandTypeSet(HYBRID_STRUCTURE_OPERATION_TYPES);
|
|
56
|
+
/**
|
|
57
|
+
* The deterministic mode-to-permitted-command table: one immutable set per
|
|
58
|
+
* session mode, shared across calls, so UIs derive disabled affordances from
|
|
59
|
+
* the same source the session enforces. The table is type-level only; the
|
|
60
|
+
* hybrid entries additionally require every affected collection to stay
|
|
61
|
+
* inside a structural authoring region, which the session enforces per
|
|
62
|
+
* command target.
|
|
63
|
+
*/
|
|
64
|
+
export function permittedCommandTypes(mode) {
|
|
65
|
+
return PERMITTED_COMMAND_TYPES[mode];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Flattens a configuration's editing mode, composite, and session state into
|
|
69
|
+
* the single session mode fixed at session creation: a read-only session
|
|
70
|
+
* state always flattens to `read-only`, the hybrid composite flattens to
|
|
71
|
+
* `hybrid`, and every other session keeps its authoring mode. The hybrid
|
|
72
|
+
* composite is invalid with Model mode, mirroring the configuration schema.
|
|
73
|
+
*/
|
|
74
|
+
export function resolveSessionMode(configuration) {
|
|
75
|
+
if (configuration.sessionState === 'read-only') {
|
|
76
|
+
return 'read-only';
|
|
77
|
+
}
|
|
78
|
+
if (configuration.composite === 'hybrid') {
|
|
79
|
+
if (configuration.mode === 'model') {
|
|
80
|
+
throw new RangeError('The hybrid composite is invalid with the model editing mode.');
|
|
81
|
+
}
|
|
82
|
+
return 'hybrid';
|
|
83
|
+
}
|
|
84
|
+
return configuration.mode;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Fails closed with the stable `mode-forbidden` code when the command type is
|
|
88
|
+
* outside the active mode's permitted set.
|
|
89
|
+
*/
|
|
90
|
+
export function assertModePermitsCommandType(mode, type) {
|
|
91
|
+
if (!PERMITTED_COMMAND_TYPES[mode].has(type)) {
|
|
92
|
+
throw new StudioCommandError('mode-forbidden', `Command type ${type} is not permitted in ${mode} mode.`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Enforces the bounded-composition rule for one hybrid structure command:
|
|
97
|
+
* every collection the command inserts into, removes from, moves across, or
|
|
98
|
+
* reorders must be a named slot of a node whose authoring policy mode is
|
|
99
|
+
* `structural`; inserted block types must satisfy the structural node's
|
|
100
|
+
* `allowedBlocks` when declared; subtrees containing a `locked` node are
|
|
101
|
+
* never inserted, removed, moved, or duplicated; and document roots are
|
|
102
|
+
* never in bounds. Batch operations are evaluated sequentially against a
|
|
103
|
+
* trial state so later operations may compose nodes earlier operations
|
|
104
|
+
* introduced. A violation fails closed with `mode-forbidden`; a reference
|
|
105
|
+
* the gate cannot resolve is left for the reducer's canonical failure code.
|
|
106
|
+
*
|
|
107
|
+
* The passed document is consumed as trial scratch state and may be mutated;
|
|
108
|
+
* callers pass a clone.
|
|
109
|
+
*/
|
|
110
|
+
export function assertHybridCommandInBounds(document, command) {
|
|
111
|
+
switch (command.type) {
|
|
112
|
+
case 'studio.command/batch': {
|
|
113
|
+
for (const operation of command.payload.operations) {
|
|
114
|
+
const type = operation.type;
|
|
115
|
+
if (type === 'studio.command/batch' ||
|
|
116
|
+
type === 'studio.command/apply-pattern' ||
|
|
117
|
+
type === 'studio.command/reset-inherited-property') {
|
|
118
|
+
// Never legal inside a batch; the reducer's canonical
|
|
119
|
+
// invalid-batch rejection resurfaces when the command executes.
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (!HYBRID_BATCHABLE_OPERATION_TYPES.has(operation.type)) {
|
|
123
|
+
throw new StudioCommandError('mode-forbidden', `Batch operation type ${operation.type} is not permitted in hybrid mode.`);
|
|
124
|
+
}
|
|
125
|
+
assertHybridOperationInBounds(document, operation);
|
|
126
|
+
try {
|
|
127
|
+
applyOperation(document, operation);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// The trial cannot advance past this operation; the reducer's
|
|
131
|
+
// canonical failure code resurfaces when the command executes.
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
case 'studio.command/apply-pattern':
|
|
138
|
+
case 'studio.command/reset-inherited-property':
|
|
139
|
+
// Unreachable behind the type gate; kept for fail-closed defence.
|
|
140
|
+
throw new StudioCommandError('mode-forbidden', `Command type ${command.type} is not permitted in hybrid mode.`);
|
|
141
|
+
default:
|
|
142
|
+
assertHybridOperationInBounds(document, command);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function assertHybridOperationInBounds(document, operation) {
|
|
146
|
+
switch (operation.type) {
|
|
147
|
+
case 'studio.command/insert-node':
|
|
148
|
+
case 'studio.command/restore-node': {
|
|
149
|
+
assertSubtreeUnlocked(operation.payload.node);
|
|
150
|
+
assertComposableDestination(document, operation.payload.destination, operation.payload.node);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
case 'studio.command/remove-node': {
|
|
154
|
+
const location = locateNode(document.roots, operation.payload.nodeId);
|
|
155
|
+
if (location === undefined) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
assertSubtreeUnlocked(location.node);
|
|
159
|
+
assertComposableParent(location.parent);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
case 'studio.command/move-node': {
|
|
163
|
+
const location = locateNode(document.roots, operation.payload.nodeId);
|
|
164
|
+
if (location === undefined) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
assertSubtreeUnlocked(location.node);
|
|
168
|
+
assertComposableParent(location.parent);
|
|
169
|
+
assertComposableDestination(document, operation.payload.destination, location.node);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
case 'studio.command/duplicate-node': {
|
|
173
|
+
const location = locateNode(document.roots, operation.payload.nodeId);
|
|
174
|
+
if (location === undefined) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
assertSubtreeUnlocked(location.node);
|
|
178
|
+
if (operation.payload.destination === undefined) {
|
|
179
|
+
assertComposableParent(location.parent);
|
|
180
|
+
if (location.parent !== undefined) {
|
|
181
|
+
assertAllowedBlock(location.parent, location.node);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
assertComposableDestination(document, operation.payload.destination, location.node);
|
|
186
|
+
}
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
case 'studio.command/reorder-children': {
|
|
190
|
+
if (operation.payload.parentNodeId === undefined) {
|
|
191
|
+
throw rootsOutOfBounds();
|
|
192
|
+
}
|
|
193
|
+
assertComposableParent(locateNode(document.roots, operation.payload.parentNodeId)?.node);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
default:
|
|
197
|
+
// Unreachable behind the type gate; kept for fail-closed defence.
|
|
198
|
+
throw new StudioCommandError('mode-forbidden', `Batch operation type ${operation.type} is not permitted in hybrid mode.`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function locateNode(nodes, nodeId, parent) {
|
|
202
|
+
for (const node of nodes) {
|
|
203
|
+
if (node.id === nodeId) {
|
|
204
|
+
return parent === undefined ? { node } : { node, parent };
|
|
205
|
+
}
|
|
206
|
+
for (const children of Object.values(node.slots)) {
|
|
207
|
+
const nested = locateNode(children, nodeId, node);
|
|
208
|
+
if (nested !== undefined) {
|
|
209
|
+
return nested;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
function assertComposableDestination(document, destination, node) {
|
|
216
|
+
if (destination.parentNodeId === undefined) {
|
|
217
|
+
throw rootsOutOfBounds();
|
|
218
|
+
}
|
|
219
|
+
const parent = locateNode(document.roots, destination.parentNodeId)?.node;
|
|
220
|
+
if (parent === undefined) {
|
|
221
|
+
// The reducer's canonical parent-not-found rejection resurfaces.
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
assertComposableParent(parent);
|
|
225
|
+
assertAllowedBlock(parent, node);
|
|
226
|
+
}
|
|
227
|
+
function assertComposableParent(parent) {
|
|
228
|
+
if (parent === undefined) {
|
|
229
|
+
throw rootsOutOfBounds();
|
|
230
|
+
}
|
|
231
|
+
if (parent.authoring.mode !== 'structural') {
|
|
232
|
+
throw new StudioCommandError('mode-forbidden', `Hybrid composition is bounded to structural slots; node ${parent.id} does not declare structural authoring.`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function assertAllowedBlock(parent, node) {
|
|
236
|
+
const allowedBlocks = parent.authoring.allowedBlocks;
|
|
237
|
+
if (allowedBlocks !== undefined && !allowedBlocks.includes(node.type)) {
|
|
238
|
+
throw new StudioCommandError('mode-forbidden', `Block type ${node.type} is not an allowed block inside structural node ${parent.id}.`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function assertSubtreeUnlocked(node) {
|
|
242
|
+
const stack = [node];
|
|
243
|
+
while (stack.length > 0) {
|
|
244
|
+
const current = stack.pop();
|
|
245
|
+
if (current === undefined) {
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
if (current.authoring.mode === 'locked') {
|
|
249
|
+
throw new StudioCommandError('mode-forbidden', `Node ${current.id} is locked and never changes through hybrid composition.`);
|
|
250
|
+
}
|
|
251
|
+
for (const children of Object.values(current.slots)) {
|
|
252
|
+
stack.push(...children);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function rootsOutOfBounds() {
|
|
257
|
+
return new StudioCommandError('mode-forbidden', 'Hybrid composition is bounded to structural slots; the document roots are out of bounds.');
|
|
258
|
+
}
|
|
259
|
+
function immutableCommandTypeSet(types) {
|
|
260
|
+
const set = new Set(types);
|
|
261
|
+
const forbidMutation = () => {
|
|
262
|
+
throw new TypeError('The permitted command-type table is immutable.');
|
|
263
|
+
};
|
|
264
|
+
return Object.freeze(Object.assign(set, { add: forbidMutation, clear: forbidMutation, delete: forbidMutation }));
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=modes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modes.js","sourceRoot":"","sources":["../src/modes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { JsonSchema } from '@kumwe/studio-protocol';
|
|
2
|
+
/** One validation failure, in the shape core diagnostics consume. */
|
|
3
|
+
export interface SchemaValidationError {
|
|
4
|
+
/** JSON Pointer to the failing instance location (`''` is the root). */
|
|
5
|
+
instancePath: string;
|
|
6
|
+
/** The schema keyword that failed. */
|
|
7
|
+
keyword: string;
|
|
8
|
+
/** A human-readable default message. */
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
export interface CompileSchemaOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Additional schema documents addressable through their root `$id` for
|
|
14
|
+
* cross-document `$ref` targets. This is the in-memory registry the
|
|
15
|
+
* profile contract describes; runtime network retrieval never happens.
|
|
16
|
+
*/
|
|
17
|
+
schemas?: readonly JsonSchema[];
|
|
18
|
+
}
|
|
19
|
+
type SchemaNode = Record<string, unknown>;
|
|
20
|
+
type Subschema = SchemaNode | boolean;
|
|
21
|
+
interface CompiledProgram {
|
|
22
|
+
patterns: WeakMap<SchemaNode, RegExp>;
|
|
23
|
+
references: WeakMap<SchemaNode, Subschema>;
|
|
24
|
+
root: SchemaNode;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A compiled (pre-walked, pre-resolved) profile schema. `validate` mirrors
|
|
28
|
+
* the verdict-plus-`errors` shape of the code-generating validator it
|
|
29
|
+
* replaces: `errors` is `null` after a passing run and carries the failures
|
|
30
|
+
* of the most recent failing run otherwise.
|
|
31
|
+
*/
|
|
32
|
+
export declare class CompiledSchemaValidator {
|
|
33
|
+
#private;
|
|
34
|
+
errors: SchemaValidationError[] | null;
|
|
35
|
+
constructor(program: CompiledProgram);
|
|
36
|
+
validate(instance: unknown): boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Compiles a schema for interpretation: validates every keyword against the
|
|
40
|
+
* profile's closed allowlist and operand grammar, compiles bounded lexical
|
|
41
|
+
* patterns, and resolves every `$ref` against the in-memory registry. All
|
|
42
|
+
* structural errors surface here, at compile time, so validation itself is
|
|
43
|
+
* total. Throws `TypeError`/`RangeError` on any schema outside the profile.
|
|
44
|
+
*/
|
|
45
|
+
export declare function compileProfileSchema(schema: JsonSchema, options?: CompileSchemaOptions): CompiledSchemaValidator;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=profile-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-validator.d.ts","sourceRoot":"","sources":["../src/profile-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAwFzD,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CACjC;AAED,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC1C,KAAK,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAgBtC,UAAU,eAAe;IACvB,QAAQ,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAC3C,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;;;;GAKG;AACH,qBAAa,uBAAuB;;IAC3B,MAAM,EAAE,qBAAqB,EAAE,GAAG,IAAI,CAAQ;gBAGlC,OAAO,EAAE,eAAe;IAIpC,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO;CAM5C;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,oBAAyB,GACjC,uBAAuB,CA6CzB"}
|