@livon/schema 0.27.0-rc.1
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/PROMPT.md +21 -0
- package/README.md +13 -0
- package/SCHEMA.md +13 -0
- package/dist/SchemaValidationError.cjs +41 -0
- package/dist/SchemaValidationError.d.ts +20 -0
- package/dist/SchemaValidationError.js +7 -0
- package/dist/SchemaValidationError.spec.cjs +65 -0
- package/dist/SchemaValidationError.spec.d.ts +1 -0
- package/dist/SchemaValidationError.spec.js +59 -0
- package/dist/after.cjs +36 -0
- package/dist/after.d.ts +30 -0
- package/dist/after.js +2 -0
- package/dist/after.spec.cjs +54 -0
- package/dist/after.spec.d.ts +1 -0
- package/dist/after.spec.js +48 -0
- package/dist/and.cjs +36 -0
- package/dist/and.d.ts +26 -0
- package/dist/and.js +2 -0
- package/dist/and.spec.cjs +57 -0
- package/dist/and.spec.d.ts +1 -0
- package/dist/and.spec.js +51 -0
- package/dist/api.cjs +317 -0
- package/dist/api.d.ts +107 -0
- package/dist/api.js +277 -0
- package/dist/api.spec.cjs +512 -0
- package/dist/api.spec.d.ts +1 -0
- package/dist/api.spec.js +506 -0
- package/dist/array.cjs +74 -0
- package/dist/array.d.ts +25 -0
- package/dist/array.js +40 -0
- package/dist/array.spec.cjs +167 -0
- package/dist/array.spec.d.ts +1 -0
- package/dist/array.spec.js +161 -0
- package/dist/before.cjs +36 -0
- package/dist/before.d.ts +30 -0
- package/dist/before.js +2 -0
- package/dist/before.spec.cjs +54 -0
- package/dist/before.spec.d.ts +1 -0
- package/dist/before.spec.js +48 -0
- package/dist/binary.cjs +53 -0
- package/dist/binary.d.ts +24 -0
- package/dist/binary.js +19 -0
- package/dist/binary.spec.cjs +107 -0
- package/dist/binary.spec.d.ts +1 -0
- package/dist/binary.spec.js +101 -0
- package/dist/boolean.cjs +53 -0
- package/dist/boolean.d.ts +24 -0
- package/dist/boolean.js +19 -0
- package/dist/boolean.spec.cjs +96 -0
- package/dist/boolean.spec.d.ts +1 -0
- package/dist/boolean.spec.js +90 -0
- package/dist/context.cjs +125 -0
- package/dist/context.d.ts +101 -0
- package/dist/context.js +76 -0
- package/dist/context.spec.cjs +244 -0
- package/dist/context.spec.d.ts +1 -0
- package/dist/context.spec.js +238 -0
- package/dist/date.cjs +53 -0
- package/dist/date.d.ts +24 -0
- package/dist/date.js +19 -0
- package/dist/date.spec.cjs +97 -0
- package/dist/date.spec.d.ts +1 -0
- package/dist/date.spec.js +91 -0
- package/dist/doc.cjs +54 -0
- package/dist/doc.d.ts +25 -0
- package/dist/doc.js +17 -0
- package/dist/doc.spec.cjs +99 -0
- package/dist/doc.spec.d.ts +1 -0
- package/dist/doc.spec.js +93 -0
- package/dist/enumeration.cjs +74 -0
- package/dist/enumeration.d.ts +50 -0
- package/dist/enumeration.js +40 -0
- package/dist/enumeration.spec.cjs +110 -0
- package/dist/enumeration.spec.d.ts +1 -0
- package/dist/enumeration.spec.js +104 -0
- package/dist/hydrate.cjs +18 -0
- package/dist/hydrate.d.ts +1 -0
- package/dist/hydrate.js +0 -0
- package/dist/index.cjs +145 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +24 -0
- package/dist/index.spec.cjs +43 -0
- package/dist/index.spec.d.ts +1 -0
- package/dist/index.spec.js +37 -0
- package/dist/literal.cjs +55 -0
- package/dist/literal.d.ts +25 -0
- package/dist/literal.js +21 -0
- package/dist/literal.spec.cjs +93 -0
- package/dist/literal.spec.d.ts +1 -0
- package/dist/literal.spec.js +87 -0
- package/dist/number.cjs +89 -0
- package/dist/number.d.ts +84 -0
- package/dist/number.js +55 -0
- package/dist/number.spec.cjs +155 -0
- package/dist/number.spec.d.ts +1 -0
- package/dist/number.spec.js +149 -0
- package/dist/object.cjs +66 -0
- package/dist/object.d.ts +37 -0
- package/dist/object.js +32 -0
- package/dist/object.spec.cjs +171 -0
- package/dist/object.spec.d.ts +1 -0
- package/dist/object.spec.js +165 -0
- package/dist/operation.cjs +182 -0
- package/dist/operation.d.ts +197 -0
- package/dist/operation.js +133 -0
- package/dist/operation.spec.cjs +454 -0
- package/dist/operation.spec.d.ts +1 -0
- package/dist/operation.spec.js +448 -0
- package/dist/or.cjs +85 -0
- package/dist/or.d.ts +37 -0
- package/dist/or.js +51 -0
- package/dist/or.spec.cjs +204 -0
- package/dist/or.spec.d.ts +1 -0
- package/dist/or.spec.js +198 -0
- package/dist/schema.cjs +285 -0
- package/dist/schema.d.ts +132 -0
- package/dist/schema.js +233 -0
- package/dist/schema.spec.cjs +587 -0
- package/dist/schema.spec.d.ts +1 -0
- package/dist/schema.spec.js +581 -0
- package/dist/schemaFactory.cjs +125 -0
- package/dist/schemaFactory.d.ts +97 -0
- package/dist/schemaFactory.js +88 -0
- package/dist/schemaFactory.spec.cjs +197 -0
- package/dist/schemaFactory.spec.d.ts +1 -0
- package/dist/schemaFactory.spec.js +191 -0
- package/dist/schemaModule.cjs +280 -0
- package/dist/schemaModule.d.ts +97 -0
- package/dist/schemaModule.js +243 -0
- package/dist/schemaModule.spec.cjs +355 -0
- package/dist/schemaModule.spec.d.ts +1 -0
- package/dist/schemaModule.spec.js +349 -0
- package/dist/string.cjs +93 -0
- package/dist/string.d.ts +85 -0
- package/dist/string.js +59 -0
- package/dist/string.spec.cjs +158 -0
- package/dist/string.spec.d.ts +1 -0
- package/dist/string.spec.js +152 -0
- package/dist/testing/mocks/assertions.mock.cjs +48 -0
- package/dist/testing/mocks/assertions.mock.d.ts +5 -0
- package/dist/testing/mocks/assertions.mock.js +14 -0
- package/dist/testing/mocks/index.cjs +52 -0
- package/dist/testing/mocks/index.d.ts +4 -0
- package/dist/testing/mocks/index.js +3 -0
- package/dist/testing/mocks/schema.mock.cjs +120 -0
- package/dist/testing/mocks/schema.mock.d.ts +37 -0
- package/dist/testing/mocks/schema.mock.js +74 -0
- package/dist/tuple.cjs +58 -0
- package/dist/tuple.d.ts +33 -0
- package/dist/tuple.js +24 -0
- package/dist/tuple.spec.cjs +162 -0
- package/dist/tuple.spec.d.ts +1 -0
- package/dist/tuple.spec.js +156 -0
- package/dist/typeGuards.cjs +60 -0
- package/dist/typeGuards.d.ts +93 -0
- package/dist/typeGuards.js +8 -0
- package/dist/typeGuards.spec.cjs +101 -0
- package/dist/typeGuards.spec.d.ts +1 -0
- package/dist/typeGuards.spec.js +95 -0
- package/dist/types.cjs +18 -0
- package/dist/types.d.ts +289 -0
- package/dist/types.js +0 -0
- package/dist/union.cjs +74 -0
- package/dist/union.d.ts +33 -0
- package/dist/union.js +40 -0
- package/dist/union.spec.cjs +159 -0
- package/dist/union.spec.d.ts +1 -0
- package/dist/union.spec.js +153 -0
- package/package.json +47 -0
package/dist/or.spec.cjs
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_exports__ = {};
|
|
3
|
+
const external_vitest_namespaceObject = require("vitest");
|
|
4
|
+
const external_or_cjs_namespaceObject = require("./or.cjs");
|
|
5
|
+
const external_schemaFactory_cjs_namespaceObject = require("./schemaFactory.cjs");
|
|
6
|
+
const index_cjs_namespaceObject = require("./testing/mocks/index.cjs");
|
|
7
|
+
external_vitest_namespaceObject.vi.mock('./schemaFactory.js', ()=>({
|
|
8
|
+
schemaFactory: external_vitest_namespaceObject.vi.fn()
|
|
9
|
+
}));
|
|
10
|
+
const schemaFactoryMock = external_vitest_namespaceObject.vi.mocked(external_schemaFactory_cjs_namespaceObject.schemaFactory);
|
|
11
|
+
const schemaFactoryImplementation = (0, index_cjs_namespaceObject.createSchemaFactoryMock)();
|
|
12
|
+
const buildContextMock = {
|
|
13
|
+
buildId: 'build-or',
|
|
14
|
+
builder: {
|
|
15
|
+
add: external_vitest_namespaceObject.vi.fn((node)=>node),
|
|
16
|
+
getAll: external_vitest_namespaceObject.vi.fn(()=>[])
|
|
17
|
+
},
|
|
18
|
+
schemaPath: [],
|
|
19
|
+
buildOptions: {}
|
|
20
|
+
};
|
|
21
|
+
const schemaContextMock = (0, index_cjs_namespaceObject.createSchemaContextMock)({
|
|
22
|
+
buildContext: buildContextMock
|
|
23
|
+
});
|
|
24
|
+
const firstOptionMock = (0, index_cjs_namespaceObject.createBaseSchemaMock)({
|
|
25
|
+
name: 'firstOption',
|
|
26
|
+
parse: external_vitest_namespaceObject.vi.fn(()=>{
|
|
27
|
+
throw {
|
|
28
|
+
code: 'first.fail'
|
|
29
|
+
};
|
|
30
|
+
}),
|
|
31
|
+
ast: external_vitest_namespaceObject.vi.fn(()=>({
|
|
32
|
+
type: 'string',
|
|
33
|
+
name: 'FirstOption'
|
|
34
|
+
}))
|
|
35
|
+
});
|
|
36
|
+
const secondOptionMock = (0, index_cjs_namespaceObject.createBaseSchemaMock)({
|
|
37
|
+
name: 'secondOption',
|
|
38
|
+
parse: external_vitest_namespaceObject.vi.fn(()=>2),
|
|
39
|
+
ast: external_vitest_namespaceObject.vi.fn(()=>({
|
|
40
|
+
type: 'number',
|
|
41
|
+
name: 'SecondOption'
|
|
42
|
+
}))
|
|
43
|
+
});
|
|
44
|
+
const unknownOptionMock = (0, index_cjs_namespaceObject.createBaseSchemaMock)({
|
|
45
|
+
name: 'unknownOption',
|
|
46
|
+
parse: external_vitest_namespaceObject.vi.fn(()=>'unknown'),
|
|
47
|
+
ast: external_vitest_namespaceObject.vi.fn(()=>({
|
|
48
|
+
type: 'string',
|
|
49
|
+
name: 'UnknownOption'
|
|
50
|
+
}))
|
|
51
|
+
});
|
|
52
|
+
const getFactoryInput = ()=>{
|
|
53
|
+
const call = schemaFactoryMock.mock.calls[0];
|
|
54
|
+
if (!call) throw new Error('schemaFactory should be called once before reading input');
|
|
55
|
+
return call[0];
|
|
56
|
+
};
|
|
57
|
+
(0, external_vitest_namespaceObject.describe)('or()', ()=>{
|
|
58
|
+
(0, external_vitest_namespaceObject.beforeAll)(()=>{
|
|
59
|
+
schemaFactoryMock.mockImplementation(schemaFactoryImplementation);
|
|
60
|
+
});
|
|
61
|
+
(0, external_vitest_namespaceObject.beforeEach)(()=>{
|
|
62
|
+
schemaFactoryMock.mockClear();
|
|
63
|
+
schemaFactoryImplementation.mockClear();
|
|
64
|
+
external_vitest_namespaceObject.vi.mocked(firstOptionMock.parse).mockReset();
|
|
65
|
+
external_vitest_namespaceObject.vi.mocked(firstOptionMock.parse).mockImplementation(()=>{
|
|
66
|
+
throw {
|
|
67
|
+
code: 'first.fail'
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
external_vitest_namespaceObject.vi.mocked(firstOptionMock.ast).mockClear();
|
|
71
|
+
external_vitest_namespaceObject.vi.mocked(secondOptionMock.parse).mockReset();
|
|
72
|
+
external_vitest_namespaceObject.vi.mocked(secondOptionMock.parse).mockReturnValue(2);
|
|
73
|
+
external_vitest_namespaceObject.vi.mocked(secondOptionMock.ast).mockClear();
|
|
74
|
+
external_vitest_namespaceObject.vi.mocked(unknownOptionMock.parse).mockClear();
|
|
75
|
+
external_vitest_namespaceObject.vi.mocked(unknownOptionMock.ast).mockClear();
|
|
76
|
+
});
|
|
77
|
+
(0, external_vitest_namespaceObject.afterEach)(()=>{
|
|
78
|
+
external_vitest_namespaceObject.vi.mocked(firstOptionMock.parse).mockClear();
|
|
79
|
+
external_vitest_namespaceObject.vi.mocked(secondOptionMock.parse).mockClear();
|
|
80
|
+
});
|
|
81
|
+
(0, external_vitest_namespaceObject.afterAll)(()=>{
|
|
82
|
+
schemaFactoryMock.mockReset();
|
|
83
|
+
schemaFactoryImplementation.mockReset();
|
|
84
|
+
});
|
|
85
|
+
(0, external_vitest_namespaceObject.describe)('happy', ()=>{
|
|
86
|
+
(0, external_vitest_namespaceObject.it)('should delegate to schemaFactory when or schema is created', ()=>{
|
|
87
|
+
const result = (0, external_or_cjs_namespaceObject.or)({
|
|
88
|
+
name: 'Selector',
|
|
89
|
+
options: [
|
|
90
|
+
firstOptionMock,
|
|
91
|
+
secondOptionMock
|
|
92
|
+
]
|
|
93
|
+
});
|
|
94
|
+
(0, external_vitest_namespaceObject.expect)(schemaFactoryMock).toHaveBeenCalledTimes(1);
|
|
95
|
+
const factoryInput = getFactoryInput();
|
|
96
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.name).toBe('Selector');
|
|
97
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.type).toBe('or');
|
|
98
|
+
(0, external_vitest_namespaceObject.expect)(result).toBe(schemaFactoryMock.mock.results[0]?.value);
|
|
99
|
+
});
|
|
100
|
+
(0, external_vitest_namespaceObject.it)('should build ast from options when build context is available', ()=>{
|
|
101
|
+
(0, external_or_cjs_namespaceObject.or)({
|
|
102
|
+
name: 'Selector',
|
|
103
|
+
options: [
|
|
104
|
+
firstOptionMock,
|
|
105
|
+
secondOptionMock
|
|
106
|
+
]
|
|
107
|
+
});
|
|
108
|
+
const factoryInput = getFactoryInput();
|
|
109
|
+
const ast = factoryInput.ast(schemaContextMock);
|
|
110
|
+
(0, external_vitest_namespaceObject.expect)(ast).toEqual({
|
|
111
|
+
type: 'union',
|
|
112
|
+
name: 'Selector',
|
|
113
|
+
children: [
|
|
114
|
+
{
|
|
115
|
+
type: 'string',
|
|
116
|
+
name: 'FirstOption'
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
type: 'number',
|
|
120
|
+
name: 'SecondOption'
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
});
|
|
124
|
+
(0, external_vitest_namespaceObject.expect)(firstOptionMock.ast).toHaveBeenCalledWith(buildContextMock);
|
|
125
|
+
(0, external_vitest_namespaceObject.expect)(secondOptionMock.ast).toHaveBeenCalledWith(buildContextMock);
|
|
126
|
+
});
|
|
127
|
+
(0, external_vitest_namespaceObject.it)('should fall back to option matching when discriminator is missing', ()=>{
|
|
128
|
+
(0, external_or_cjs_namespaceObject.or)({
|
|
129
|
+
name: 'Selector',
|
|
130
|
+
options: [
|
|
131
|
+
firstOptionMock,
|
|
132
|
+
secondOptionMock
|
|
133
|
+
]
|
|
134
|
+
});
|
|
135
|
+
const factoryInput = getFactoryInput();
|
|
136
|
+
const parsed = factoryInput.validate('input', schemaContextMock);
|
|
137
|
+
(0, external_vitest_namespaceObject.expect)(parsed).toBe(2);
|
|
138
|
+
(0, external_vitest_namespaceObject.expect)(firstOptionMock.parse).toHaveBeenCalledWith('input', schemaContextMock);
|
|
139
|
+
(0, external_vitest_namespaceObject.expect)(secondOptionMock.parse).toHaveBeenCalledWith('input', schemaContextMock);
|
|
140
|
+
});
|
|
141
|
+
(0, external_vitest_namespaceObject.it)('should use discriminator option when discriminator returns known schema', ()=>{
|
|
142
|
+
const discriminator = external_vitest_namespaceObject.vi.fn(()=>secondOptionMock);
|
|
143
|
+
(0, external_or_cjs_namespaceObject.or)({
|
|
144
|
+
name: 'Selector',
|
|
145
|
+
options: [
|
|
146
|
+
firstOptionMock,
|
|
147
|
+
secondOptionMock
|
|
148
|
+
],
|
|
149
|
+
discriminator
|
|
150
|
+
});
|
|
151
|
+
const factoryInput = getFactoryInput();
|
|
152
|
+
const parsed = factoryInput.validate('input', schemaContextMock);
|
|
153
|
+
(0, external_vitest_namespaceObject.expect)(parsed).toBe(2);
|
|
154
|
+
(0, external_vitest_namespaceObject.expect)(discriminator).toHaveBeenCalledWith('input', schemaContextMock);
|
|
155
|
+
(0, external_vitest_namespaceObject.expect)(firstOptionMock.parse).not.toHaveBeenCalled();
|
|
156
|
+
(0, external_vitest_namespaceObject.expect)(secondOptionMock.parse).toHaveBeenCalledWith('input', schemaContextMock);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
(0, external_vitest_namespaceObject.describe)('sad', ()=>{
|
|
160
|
+
(0, external_vitest_namespaceObject.it)('should throw or.discriminator when discriminator returns unknown schema', ()=>{
|
|
161
|
+
const discriminator = external_vitest_namespaceObject.vi.fn(()=>unknownOptionMock);
|
|
162
|
+
(0, external_or_cjs_namespaceObject.or)({
|
|
163
|
+
name: 'Selector',
|
|
164
|
+
options: [
|
|
165
|
+
firstOptionMock,
|
|
166
|
+
secondOptionMock
|
|
167
|
+
],
|
|
168
|
+
discriminator
|
|
169
|
+
});
|
|
170
|
+
const factoryInput = getFactoryInput();
|
|
171
|
+
const thrown = (0, index_cjs_namespaceObject.captureThrow)(()=>factoryInput.validate('input', schemaContextMock));
|
|
172
|
+
(0, external_vitest_namespaceObject.expect)(thrown.threw).toBe(true);
|
|
173
|
+
(0, external_vitest_namespaceObject.expect)(thrown.value).toEqual({
|
|
174
|
+
message: 'Discriminator selected an unknown schema option.',
|
|
175
|
+
code: 'or.discriminator'
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
(0, external_vitest_namespaceObject.it)('should throw union.match when no option matches', ()=>{
|
|
179
|
+
external_vitest_namespaceObject.vi.mocked(secondOptionMock.parse).mockImplementation(()=>{
|
|
180
|
+
throw {
|
|
181
|
+
code: 'second.fail'
|
|
182
|
+
};
|
|
183
|
+
});
|
|
184
|
+
(0, external_or_cjs_namespaceObject.or)({
|
|
185
|
+
name: 'Selector',
|
|
186
|
+
options: [
|
|
187
|
+
firstOptionMock,
|
|
188
|
+
secondOptionMock
|
|
189
|
+
]
|
|
190
|
+
});
|
|
191
|
+
const factoryInput = getFactoryInput();
|
|
192
|
+
const thrown = (0, index_cjs_namespaceObject.captureThrow)(()=>factoryInput.validate('input', schemaContextMock));
|
|
193
|
+
(0, external_vitest_namespaceObject.expect)(thrown.threw).toBe(true);
|
|
194
|
+
(0, external_vitest_namespaceObject.expect)(thrown.value).toEqual({
|
|
195
|
+
message: 'No union match',
|
|
196
|
+
code: 'union.match'
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
202
|
+
Object.defineProperty(exports, '__esModule', {
|
|
203
|
+
value: true
|
|
204
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/or.spec.js
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { or } from "./or.js";
|
|
3
|
+
import { schemaFactory } from "./schemaFactory.js";
|
|
4
|
+
import { captureThrow, createBaseSchemaMock, createSchemaContextMock, createSchemaFactoryMock } from "./testing/mocks/index.js";
|
|
5
|
+
vi.mock('./schemaFactory.js', ()=>({
|
|
6
|
+
schemaFactory: vi.fn()
|
|
7
|
+
}));
|
|
8
|
+
const schemaFactoryMock = vi.mocked(schemaFactory);
|
|
9
|
+
const schemaFactoryImplementation = createSchemaFactoryMock();
|
|
10
|
+
const buildContextMock = {
|
|
11
|
+
buildId: 'build-or',
|
|
12
|
+
builder: {
|
|
13
|
+
add: vi.fn((node)=>node),
|
|
14
|
+
getAll: vi.fn(()=>[])
|
|
15
|
+
},
|
|
16
|
+
schemaPath: [],
|
|
17
|
+
buildOptions: {}
|
|
18
|
+
};
|
|
19
|
+
const schemaContextMock = createSchemaContextMock({
|
|
20
|
+
buildContext: buildContextMock
|
|
21
|
+
});
|
|
22
|
+
const firstOptionMock = createBaseSchemaMock({
|
|
23
|
+
name: 'firstOption',
|
|
24
|
+
parse: vi.fn(()=>{
|
|
25
|
+
throw {
|
|
26
|
+
code: 'first.fail'
|
|
27
|
+
};
|
|
28
|
+
}),
|
|
29
|
+
ast: vi.fn(()=>({
|
|
30
|
+
type: 'string',
|
|
31
|
+
name: 'FirstOption'
|
|
32
|
+
}))
|
|
33
|
+
});
|
|
34
|
+
const secondOptionMock = createBaseSchemaMock({
|
|
35
|
+
name: 'secondOption',
|
|
36
|
+
parse: vi.fn(()=>2),
|
|
37
|
+
ast: vi.fn(()=>({
|
|
38
|
+
type: 'number',
|
|
39
|
+
name: 'SecondOption'
|
|
40
|
+
}))
|
|
41
|
+
});
|
|
42
|
+
const unknownOptionMock = createBaseSchemaMock({
|
|
43
|
+
name: 'unknownOption',
|
|
44
|
+
parse: vi.fn(()=>'unknown'),
|
|
45
|
+
ast: vi.fn(()=>({
|
|
46
|
+
type: 'string',
|
|
47
|
+
name: 'UnknownOption'
|
|
48
|
+
}))
|
|
49
|
+
});
|
|
50
|
+
const getFactoryInput = ()=>{
|
|
51
|
+
const call = schemaFactoryMock.mock.calls[0];
|
|
52
|
+
if (!call) throw new Error('schemaFactory should be called once before reading input');
|
|
53
|
+
return call[0];
|
|
54
|
+
};
|
|
55
|
+
describe('or()', ()=>{
|
|
56
|
+
beforeAll(()=>{
|
|
57
|
+
schemaFactoryMock.mockImplementation(schemaFactoryImplementation);
|
|
58
|
+
});
|
|
59
|
+
beforeEach(()=>{
|
|
60
|
+
schemaFactoryMock.mockClear();
|
|
61
|
+
schemaFactoryImplementation.mockClear();
|
|
62
|
+
vi.mocked(firstOptionMock.parse).mockReset();
|
|
63
|
+
vi.mocked(firstOptionMock.parse).mockImplementation(()=>{
|
|
64
|
+
throw {
|
|
65
|
+
code: 'first.fail'
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
vi.mocked(firstOptionMock.ast).mockClear();
|
|
69
|
+
vi.mocked(secondOptionMock.parse).mockReset();
|
|
70
|
+
vi.mocked(secondOptionMock.parse).mockReturnValue(2);
|
|
71
|
+
vi.mocked(secondOptionMock.ast).mockClear();
|
|
72
|
+
vi.mocked(unknownOptionMock.parse).mockClear();
|
|
73
|
+
vi.mocked(unknownOptionMock.ast).mockClear();
|
|
74
|
+
});
|
|
75
|
+
afterEach(()=>{
|
|
76
|
+
vi.mocked(firstOptionMock.parse).mockClear();
|
|
77
|
+
vi.mocked(secondOptionMock.parse).mockClear();
|
|
78
|
+
});
|
|
79
|
+
afterAll(()=>{
|
|
80
|
+
schemaFactoryMock.mockReset();
|
|
81
|
+
schemaFactoryImplementation.mockReset();
|
|
82
|
+
});
|
|
83
|
+
describe('happy', ()=>{
|
|
84
|
+
it('should delegate to schemaFactory when or schema is created', ()=>{
|
|
85
|
+
const result = or({
|
|
86
|
+
name: 'Selector',
|
|
87
|
+
options: [
|
|
88
|
+
firstOptionMock,
|
|
89
|
+
secondOptionMock
|
|
90
|
+
]
|
|
91
|
+
});
|
|
92
|
+
expect(schemaFactoryMock).toHaveBeenCalledTimes(1);
|
|
93
|
+
const factoryInput = getFactoryInput();
|
|
94
|
+
expect(factoryInput.name).toBe('Selector');
|
|
95
|
+
expect(factoryInput.type).toBe('or');
|
|
96
|
+
expect(result).toBe(schemaFactoryMock.mock.results[0]?.value);
|
|
97
|
+
});
|
|
98
|
+
it('should build ast from options when build context is available', ()=>{
|
|
99
|
+
or({
|
|
100
|
+
name: 'Selector',
|
|
101
|
+
options: [
|
|
102
|
+
firstOptionMock,
|
|
103
|
+
secondOptionMock
|
|
104
|
+
]
|
|
105
|
+
});
|
|
106
|
+
const factoryInput = getFactoryInput();
|
|
107
|
+
const ast = factoryInput.ast(schemaContextMock);
|
|
108
|
+
expect(ast).toEqual({
|
|
109
|
+
type: 'union',
|
|
110
|
+
name: 'Selector',
|
|
111
|
+
children: [
|
|
112
|
+
{
|
|
113
|
+
type: 'string',
|
|
114
|
+
name: 'FirstOption'
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: 'number',
|
|
118
|
+
name: 'SecondOption'
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
});
|
|
122
|
+
expect(firstOptionMock.ast).toHaveBeenCalledWith(buildContextMock);
|
|
123
|
+
expect(secondOptionMock.ast).toHaveBeenCalledWith(buildContextMock);
|
|
124
|
+
});
|
|
125
|
+
it('should fall back to option matching when discriminator is missing', ()=>{
|
|
126
|
+
or({
|
|
127
|
+
name: 'Selector',
|
|
128
|
+
options: [
|
|
129
|
+
firstOptionMock,
|
|
130
|
+
secondOptionMock
|
|
131
|
+
]
|
|
132
|
+
});
|
|
133
|
+
const factoryInput = getFactoryInput();
|
|
134
|
+
const parsed = factoryInput.validate('input', schemaContextMock);
|
|
135
|
+
expect(parsed).toBe(2);
|
|
136
|
+
expect(firstOptionMock.parse).toHaveBeenCalledWith('input', schemaContextMock);
|
|
137
|
+
expect(secondOptionMock.parse).toHaveBeenCalledWith('input', schemaContextMock);
|
|
138
|
+
});
|
|
139
|
+
it('should use discriminator option when discriminator returns known schema', ()=>{
|
|
140
|
+
const discriminator = vi.fn(()=>secondOptionMock);
|
|
141
|
+
or({
|
|
142
|
+
name: 'Selector',
|
|
143
|
+
options: [
|
|
144
|
+
firstOptionMock,
|
|
145
|
+
secondOptionMock
|
|
146
|
+
],
|
|
147
|
+
discriminator
|
|
148
|
+
});
|
|
149
|
+
const factoryInput = getFactoryInput();
|
|
150
|
+
const parsed = factoryInput.validate('input', schemaContextMock);
|
|
151
|
+
expect(parsed).toBe(2);
|
|
152
|
+
expect(discriminator).toHaveBeenCalledWith('input', schemaContextMock);
|
|
153
|
+
expect(firstOptionMock.parse).not.toHaveBeenCalled();
|
|
154
|
+
expect(secondOptionMock.parse).toHaveBeenCalledWith('input', schemaContextMock);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
describe('sad', ()=>{
|
|
158
|
+
it('should throw or.discriminator when discriminator returns unknown schema', ()=>{
|
|
159
|
+
const discriminator = vi.fn(()=>unknownOptionMock);
|
|
160
|
+
or({
|
|
161
|
+
name: 'Selector',
|
|
162
|
+
options: [
|
|
163
|
+
firstOptionMock,
|
|
164
|
+
secondOptionMock
|
|
165
|
+
],
|
|
166
|
+
discriminator
|
|
167
|
+
});
|
|
168
|
+
const factoryInput = getFactoryInput();
|
|
169
|
+
const thrown = captureThrow(()=>factoryInput.validate('input', schemaContextMock));
|
|
170
|
+
expect(thrown.threw).toBe(true);
|
|
171
|
+
expect(thrown.value).toEqual({
|
|
172
|
+
message: 'Discriminator selected an unknown schema option.',
|
|
173
|
+
code: 'or.discriminator'
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
it('should throw union.match when no option matches', ()=>{
|
|
177
|
+
vi.mocked(secondOptionMock.parse).mockImplementation(()=>{
|
|
178
|
+
throw {
|
|
179
|
+
code: 'second.fail'
|
|
180
|
+
};
|
|
181
|
+
});
|
|
182
|
+
or({
|
|
183
|
+
name: 'Selector',
|
|
184
|
+
options: [
|
|
185
|
+
firstOptionMock,
|
|
186
|
+
secondOptionMock
|
|
187
|
+
]
|
|
188
|
+
});
|
|
189
|
+
const factoryInput = getFactoryInput();
|
|
190
|
+
const thrown = captureThrow(()=>factoryInput.validate('input', schemaContextMock));
|
|
191
|
+
expect(thrown.threw).toBe(true);
|
|
192
|
+
expect(thrown.value).toEqual({
|
|
193
|
+
message: 'No union match',
|
|
194
|
+
code: 'union.match'
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
});
|
package/dist/schema.cjs
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
fail: ()=>fail,
|
|
28
|
+
createPrimitiveSchema: ()=>createPrimitiveSchema,
|
|
29
|
+
createIssueForPath: ()=>createIssueForPath,
|
|
30
|
+
ok: ()=>ok,
|
|
31
|
+
createGuardSchema: ()=>createGuardSchema,
|
|
32
|
+
createSchema: ()=>createSchema,
|
|
33
|
+
ensureSchemaContext: ()=>ensureSchemaContext
|
|
34
|
+
});
|
|
35
|
+
const external_SchemaValidationError_cjs_namespaceObject = require("./SchemaValidationError.cjs");
|
|
36
|
+
const external_context_cjs_namespaceObject = require("./context.cjs");
|
|
37
|
+
const external_doc_cjs_namespaceObject = require("./doc.cjs");
|
|
38
|
+
const createIssueForPath = ({ path, message, code, context })=>({
|
|
39
|
+
path,
|
|
40
|
+
message,
|
|
41
|
+
code,
|
|
42
|
+
context
|
|
43
|
+
});
|
|
44
|
+
const ok = ({ value })=>({
|
|
45
|
+
ok: true,
|
|
46
|
+
value
|
|
47
|
+
});
|
|
48
|
+
const fail = ({ issues, meta })=>({
|
|
49
|
+
ok: false,
|
|
50
|
+
issues,
|
|
51
|
+
meta
|
|
52
|
+
});
|
|
53
|
+
const ensureSchemaContext = (ctx)=>{
|
|
54
|
+
if (ctx) return ctx;
|
|
55
|
+
const request = (0, external_context_cjs_namespaceObject.normalizeRequestContext)();
|
|
56
|
+
return (0, external_context_cjs_namespaceObject.createSchemaContext)({
|
|
57
|
+
request
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
const createSchema = ({ name, type, ast, validate })=>{
|
|
61
|
+
const validateWithContext = (input, ctx)=>{
|
|
62
|
+
const context = ensureSchemaContext(ctx);
|
|
63
|
+
if (!context.getRequestContext()) context.setRequestContext((0, external_context_cjs_namespaceObject.normalizeRequestContext)());
|
|
64
|
+
const build = context.getBuildContext();
|
|
65
|
+
const request = context.getRequestContext();
|
|
66
|
+
const meta = {
|
|
67
|
+
build,
|
|
68
|
+
request,
|
|
69
|
+
type,
|
|
70
|
+
name
|
|
71
|
+
};
|
|
72
|
+
const result = validate(input, context);
|
|
73
|
+
return result.ok ? result : fail({
|
|
74
|
+
issues: result.issues,
|
|
75
|
+
meta
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
const parse = (input, ctx)=>{
|
|
79
|
+
const result = validateWithContext(input, ctx);
|
|
80
|
+
if (result.ok) return result.value;
|
|
81
|
+
throw (0, external_SchemaValidationError_cjs_namespaceObject.createSchemaValidationError)({
|
|
82
|
+
issues: result.issues,
|
|
83
|
+
meta: result.meta
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
const typed = (input, ctx)=>parse(input, ctx);
|
|
87
|
+
const optional = ()=>createSchema({
|
|
88
|
+
name: `${name}.optional`,
|
|
89
|
+
type: `${type}.optional`,
|
|
90
|
+
ast,
|
|
91
|
+
validate: (input, ctx)=>void 0 === input ? ok({
|
|
92
|
+
value: void 0
|
|
93
|
+
}) : validate(input, ctx)
|
|
94
|
+
});
|
|
95
|
+
const nullable = ()=>createSchema({
|
|
96
|
+
name: `${name}.nullable`,
|
|
97
|
+
type: `${type}.nullable`,
|
|
98
|
+
ast,
|
|
99
|
+
validate: (input, ctx)=>null === input ? ok({
|
|
100
|
+
value: null
|
|
101
|
+
}) : validate(input, ctx)
|
|
102
|
+
});
|
|
103
|
+
const describe = (doc)=>{
|
|
104
|
+
const nextDoc = (0, external_doc_cjs_namespaceObject.normalizeDoc)(doc);
|
|
105
|
+
return createSchema({
|
|
106
|
+
name,
|
|
107
|
+
type,
|
|
108
|
+
ast: (ctx)=>{
|
|
109
|
+
const node = ast(ctx);
|
|
110
|
+
const merged = (0, external_doc_cjs_namespaceObject.mergeDoc)(node.doc, nextDoc);
|
|
111
|
+
return merged ? {
|
|
112
|
+
...node,
|
|
113
|
+
doc: merged
|
|
114
|
+
} : node;
|
|
115
|
+
},
|
|
116
|
+
validate
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
const refine = ({ predicate, message, code })=>createSchema({
|
|
120
|
+
name: `${name}.refine`,
|
|
121
|
+
type: `${type}.refine`,
|
|
122
|
+
ast,
|
|
123
|
+
validate: (input, ctx)=>{
|
|
124
|
+
const context = ensureSchemaContext(ctx);
|
|
125
|
+
const result = validate(input, context);
|
|
126
|
+
if (!result.ok) return result;
|
|
127
|
+
return predicate(result.value, context) ? result : fail({
|
|
128
|
+
issues: [
|
|
129
|
+
createIssueForPath({
|
|
130
|
+
path: [],
|
|
131
|
+
message,
|
|
132
|
+
code
|
|
133
|
+
})
|
|
134
|
+
]
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
const before = (hook)=>createSchema({
|
|
139
|
+
name: `${name}.before`,
|
|
140
|
+
type: `${type}.before`,
|
|
141
|
+
ast,
|
|
142
|
+
validate: (input, ctx)=>{
|
|
143
|
+
const context = ensureSchemaContext(ctx);
|
|
144
|
+
const result = hook(input, context);
|
|
145
|
+
const issues = 'object' == typeof result && null !== result && 'issues' in result ? result.issues ?? [] : [];
|
|
146
|
+
if (issues.length > 0) return fail({
|
|
147
|
+
issues
|
|
148
|
+
});
|
|
149
|
+
const nextInput = 'object' == typeof result && null !== result && 'input' in result ? result.input : result;
|
|
150
|
+
return validate(nextInput, context);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
const after = (hook)=>createSchema({
|
|
154
|
+
name: `${name}.after`,
|
|
155
|
+
type: `${type}.after`,
|
|
156
|
+
ast,
|
|
157
|
+
validate: (input, ctx)=>{
|
|
158
|
+
const context = ensureSchemaContext(ctx);
|
|
159
|
+
const result = validate(input, context);
|
|
160
|
+
if (!result.ok) return result;
|
|
161
|
+
const hookResult = hook(result.value, context);
|
|
162
|
+
const issues = 'object' == typeof hookResult && null !== hookResult && 'issues' in hookResult ? hookResult.issues ?? [] : [];
|
|
163
|
+
if (issues.length > 0) return fail({
|
|
164
|
+
issues
|
|
165
|
+
});
|
|
166
|
+
const nextValue = 'object' == typeof hookResult && null !== hookResult && 'value' in hookResult ? hookResult.value : hookResult;
|
|
167
|
+
return ok({
|
|
168
|
+
value: nextValue
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
const and = (other)=>createSchema({
|
|
173
|
+
name: `${name}.and`,
|
|
174
|
+
type: `${type}.and`,
|
|
175
|
+
ast: (ctx)=>({
|
|
176
|
+
type: 'and',
|
|
177
|
+
children: [
|
|
178
|
+
ast(ctx),
|
|
179
|
+
other.ast(ctx.getBuildContext())
|
|
180
|
+
]
|
|
181
|
+
}),
|
|
182
|
+
validate: (input, ctx)=>{
|
|
183
|
+
const context = ensureSchemaContext(ctx);
|
|
184
|
+
const left = validate(input, context);
|
|
185
|
+
const right = other.validate(input, context);
|
|
186
|
+
return left.ok && right.ok ? ok({
|
|
187
|
+
value: left.value
|
|
188
|
+
}) : fail({
|
|
189
|
+
issues: [
|
|
190
|
+
...left.ok ? [] : left.issues,
|
|
191
|
+
...right.ok ? [] : right.issues
|
|
192
|
+
]
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
const resolveAst = (ctx)=>{
|
|
197
|
+
const node = ast(ctx);
|
|
198
|
+
return node.name ? node : {
|
|
199
|
+
...node,
|
|
200
|
+
name
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
return {
|
|
204
|
+
name,
|
|
205
|
+
type,
|
|
206
|
+
ast: (input)=>{
|
|
207
|
+
const build = (0, external_context_cjs_namespaceObject.normalizeBuildContext)(input ?? {});
|
|
208
|
+
const context = (0, external_context_cjs_namespaceObject.createSchemaContext)({
|
|
209
|
+
build
|
|
210
|
+
});
|
|
211
|
+
return resolveAst(context);
|
|
212
|
+
},
|
|
213
|
+
validate: validateWithContext,
|
|
214
|
+
parse,
|
|
215
|
+
typed,
|
|
216
|
+
optional,
|
|
217
|
+
nullable,
|
|
218
|
+
describe,
|
|
219
|
+
refine,
|
|
220
|
+
before,
|
|
221
|
+
after,
|
|
222
|
+
and
|
|
223
|
+
};
|
|
224
|
+
};
|
|
225
|
+
const createGuardSchema = ({ name, type, guard, message, code })=>createSchema({
|
|
226
|
+
name,
|
|
227
|
+
type,
|
|
228
|
+
ast: ()=>({
|
|
229
|
+
type,
|
|
230
|
+
constraints: {
|
|
231
|
+
kind: 'guard'
|
|
232
|
+
}
|
|
233
|
+
}),
|
|
234
|
+
validate: (input)=>guard(input) ? ok({
|
|
235
|
+
value: input
|
|
236
|
+
}) : fail({
|
|
237
|
+
issues: [
|
|
238
|
+
createIssueForPath({
|
|
239
|
+
path: [],
|
|
240
|
+
message,
|
|
241
|
+
code
|
|
242
|
+
})
|
|
243
|
+
]
|
|
244
|
+
})
|
|
245
|
+
});
|
|
246
|
+
const createPrimitiveSchema = ({ name, type, guard, message, code })=>createSchema({
|
|
247
|
+
name,
|
|
248
|
+
type,
|
|
249
|
+
ast: ()=>({
|
|
250
|
+
type,
|
|
251
|
+
constraints: {
|
|
252
|
+
kind: 'primitive'
|
|
253
|
+
}
|
|
254
|
+
}),
|
|
255
|
+
validate: (input)=>guard(input) ? ok({
|
|
256
|
+
value: input
|
|
257
|
+
}) : fail({
|
|
258
|
+
issues: [
|
|
259
|
+
createIssueForPath({
|
|
260
|
+
path: [],
|
|
261
|
+
message,
|
|
262
|
+
code
|
|
263
|
+
})
|
|
264
|
+
]
|
|
265
|
+
})
|
|
266
|
+
});
|
|
267
|
+
exports.createGuardSchema = __webpack_exports__.createGuardSchema;
|
|
268
|
+
exports.createIssueForPath = __webpack_exports__.createIssueForPath;
|
|
269
|
+
exports.createPrimitiveSchema = __webpack_exports__.createPrimitiveSchema;
|
|
270
|
+
exports.createSchema = __webpack_exports__.createSchema;
|
|
271
|
+
exports.ensureSchemaContext = __webpack_exports__.ensureSchemaContext;
|
|
272
|
+
exports.fail = __webpack_exports__.fail;
|
|
273
|
+
exports.ok = __webpack_exports__.ok;
|
|
274
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
275
|
+
"createGuardSchema",
|
|
276
|
+
"createIssueForPath",
|
|
277
|
+
"createPrimitiveSchema",
|
|
278
|
+
"createSchema",
|
|
279
|
+
"ensureSchemaContext",
|
|
280
|
+
"fail",
|
|
281
|
+
"ok"
|
|
282
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
283
|
+
Object.defineProperty(exports, '__esModule', {
|
|
284
|
+
value: true
|
|
285
|
+
});
|