@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/literal.cjs
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
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
|
+
literal: ()=>literal
|
|
28
|
+
});
|
|
29
|
+
const external_schemaFactory_cjs_namespaceObject = require("./schemaFactory.cjs");
|
|
30
|
+
const literal = ({ name, value, doc })=>(0, external_schemaFactory_cjs_namespaceObject.schemaFactory)({
|
|
31
|
+
name,
|
|
32
|
+
type: `literal<${String(value)}>`,
|
|
33
|
+
doc,
|
|
34
|
+
ast: ()=>({
|
|
35
|
+
type: 'literal',
|
|
36
|
+
name,
|
|
37
|
+
constraints: {
|
|
38
|
+
value
|
|
39
|
+
}
|
|
40
|
+
}),
|
|
41
|
+
validate: (input)=>{
|
|
42
|
+
if (input !== value) throw {
|
|
43
|
+
message: `Expected ${String(value)}`,
|
|
44
|
+
code: 'literal.value'
|
|
45
|
+
};
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
exports.literal = __webpack_exports__.literal;
|
|
50
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
51
|
+
"literal"
|
|
52
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
53
|
+
Object.defineProperty(exports, '__esModule', {
|
|
54
|
+
value: true
|
|
55
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SchemaDoc } from './types.js';
|
|
2
|
+
export interface LiteralSchemaInput<T extends string | number | boolean> {
|
|
3
|
+
name: string;
|
|
4
|
+
value: T;
|
|
5
|
+
doc?: SchemaDoc;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* literal is part of the public LIVON API.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* Parameter and return types are defined in the TypeScript signature.
|
|
12
|
+
*
|
|
13
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/literal
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Creates a literal schema that accepts only the value 'ok'.
|
|
17
|
+
* const Status = literal({ name: 'status', value: 'ok' });
|
|
18
|
+
* Status.parse('ok');
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // Extends the same literal rule to also allow undefined.
|
|
22
|
+
* const MaybeStatus = literal({ name: 'status', value: 'ok' }).optional();
|
|
23
|
+
* MaybeStatus.parse(undefined);
|
|
24
|
+
*/
|
|
25
|
+
export declare const literal: <const T extends string | number | boolean>({ name, value, doc, }: LiteralSchemaInput<T>) => import("./schemaFactory.js").SchemaWithChain<T, import("./schemaFactory.js").SchemaFactoryChainDefinition<T>>;
|
package/dist/literal.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { schemaFactory } from "./schemaFactory.js";
|
|
2
|
+
const literal = ({ name, value, doc })=>schemaFactory({
|
|
3
|
+
name,
|
|
4
|
+
type: `literal<${String(value)}>`,
|
|
5
|
+
doc,
|
|
6
|
+
ast: ()=>({
|
|
7
|
+
type: 'literal',
|
|
8
|
+
name,
|
|
9
|
+
constraints: {
|
|
10
|
+
value
|
|
11
|
+
}
|
|
12
|
+
}),
|
|
13
|
+
validate: (input)=>{
|
|
14
|
+
if (input !== value) throw {
|
|
15
|
+
message: `Expected ${String(value)}`,
|
|
16
|
+
code: 'literal.value'
|
|
17
|
+
};
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
export { literal };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_exports__ = {};
|
|
3
|
+
const external_vitest_namespaceObject = require("vitest");
|
|
4
|
+
const external_literal_cjs_namespaceObject = require("./literal.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 schemaContextMock = (0, index_cjs_namespaceObject.createSchemaContextMock)();
|
|
12
|
+
const schemaFactoryImplementation = (0, index_cjs_namespaceObject.createSchemaFactoryMock)();
|
|
13
|
+
const getFactoryInput = ()=>{
|
|
14
|
+
const call = schemaFactoryMock.mock.calls[0];
|
|
15
|
+
if (!call) throw new Error('schemaFactory should be called once before reading input');
|
|
16
|
+
return call[0];
|
|
17
|
+
};
|
|
18
|
+
(0, external_vitest_namespaceObject.describe)('literal()', ()=>{
|
|
19
|
+
(0, external_vitest_namespaceObject.beforeAll)(()=>{
|
|
20
|
+
schemaFactoryMock.mockImplementation(schemaFactoryImplementation);
|
|
21
|
+
});
|
|
22
|
+
(0, external_vitest_namespaceObject.beforeEach)(()=>{
|
|
23
|
+
schemaFactoryMock.mockClear();
|
|
24
|
+
schemaFactoryImplementation.mockClear();
|
|
25
|
+
});
|
|
26
|
+
(0, external_vitest_namespaceObject.afterEach)(()=>{
|
|
27
|
+
schemaFactoryMock.mockClear();
|
|
28
|
+
});
|
|
29
|
+
(0, external_vitest_namespaceObject.afterAll)(()=>{
|
|
30
|
+
schemaFactoryMock.mockReset();
|
|
31
|
+
schemaFactoryImplementation.mockReset();
|
|
32
|
+
});
|
|
33
|
+
(0, external_vitest_namespaceObject.describe)('happy', ()=>{
|
|
34
|
+
(0, external_vitest_namespaceObject.it)('should delegate to schemaFactory when literal metadata is provided', ()=>{
|
|
35
|
+
const result = (0, external_literal_cjs_namespaceObject.literal)({
|
|
36
|
+
name: 'Room',
|
|
37
|
+
value: 'global'
|
|
38
|
+
});
|
|
39
|
+
(0, external_vitest_namespaceObject.expect)(schemaFactoryMock).toHaveBeenCalledTimes(1);
|
|
40
|
+
const factoryInput = getFactoryInput();
|
|
41
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.name).toBe('Room');
|
|
42
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.type).toBe('literal<global>');
|
|
43
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.ast(schemaContextMock)).toEqual({
|
|
44
|
+
type: 'literal',
|
|
45
|
+
name: 'Room',
|
|
46
|
+
constraints: {
|
|
47
|
+
value: 'global'
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
(0, external_vitest_namespaceObject.expect)(result).toBe(schemaFactoryMock.mock.results[0]?.value);
|
|
51
|
+
});
|
|
52
|
+
(0, external_vitest_namespaceObject.it)('should pass doc metadata to schemaFactory when doc is provided', ()=>{
|
|
53
|
+
const doc = {
|
|
54
|
+
summary: 'literal doc'
|
|
55
|
+
};
|
|
56
|
+
(0, external_literal_cjs_namespaceObject.literal)({
|
|
57
|
+
name: 'Mode',
|
|
58
|
+
value: 'fast',
|
|
59
|
+
doc
|
|
60
|
+
});
|
|
61
|
+
const factoryInput = getFactoryInput();
|
|
62
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.doc).toEqual(doc);
|
|
63
|
+
});
|
|
64
|
+
(0, external_vitest_namespaceObject.it)('should return literal value when input matches literal', ()=>{
|
|
65
|
+
(0, external_literal_cjs_namespaceObject.literal)({
|
|
66
|
+
name: 'Flag',
|
|
67
|
+
value: true
|
|
68
|
+
});
|
|
69
|
+
const factoryInput = getFactoryInput();
|
|
70
|
+
const parsed = factoryInput.validate(true, schemaContextMock);
|
|
71
|
+
(0, external_vitest_namespaceObject.expect)(parsed).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
(0, external_vitest_namespaceObject.describe)('sad', ()=>{
|
|
75
|
+
(0, external_vitest_namespaceObject.it)('should throw schema error payload when input does not match literal', ()=>{
|
|
76
|
+
(0, external_literal_cjs_namespaceObject.literal)({
|
|
77
|
+
name: 'Flag',
|
|
78
|
+
value: false
|
|
79
|
+
});
|
|
80
|
+
const factoryInput = getFactoryInput();
|
|
81
|
+
const thrown = (0, index_cjs_namespaceObject.captureThrow)(()=>factoryInput.validate(true, schemaContextMock));
|
|
82
|
+
(0, external_vitest_namespaceObject.expect)(thrown.threw).toBe(true);
|
|
83
|
+
(0, external_vitest_namespaceObject.expect)(thrown.value).toEqual({
|
|
84
|
+
message: 'Expected false',
|
|
85
|
+
code: 'literal.value'
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
91
|
+
Object.defineProperty(exports, '__esModule', {
|
|
92
|
+
value: true
|
|
93
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { literal } from "./literal.js";
|
|
3
|
+
import { schemaFactory } from "./schemaFactory.js";
|
|
4
|
+
import { captureThrow, 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 schemaContextMock = createSchemaContextMock();
|
|
10
|
+
const schemaFactoryImplementation = createSchemaFactoryMock();
|
|
11
|
+
const getFactoryInput = ()=>{
|
|
12
|
+
const call = schemaFactoryMock.mock.calls[0];
|
|
13
|
+
if (!call) throw new Error('schemaFactory should be called once before reading input');
|
|
14
|
+
return call[0];
|
|
15
|
+
};
|
|
16
|
+
describe('literal()', ()=>{
|
|
17
|
+
beforeAll(()=>{
|
|
18
|
+
schemaFactoryMock.mockImplementation(schemaFactoryImplementation);
|
|
19
|
+
});
|
|
20
|
+
beforeEach(()=>{
|
|
21
|
+
schemaFactoryMock.mockClear();
|
|
22
|
+
schemaFactoryImplementation.mockClear();
|
|
23
|
+
});
|
|
24
|
+
afterEach(()=>{
|
|
25
|
+
schemaFactoryMock.mockClear();
|
|
26
|
+
});
|
|
27
|
+
afterAll(()=>{
|
|
28
|
+
schemaFactoryMock.mockReset();
|
|
29
|
+
schemaFactoryImplementation.mockReset();
|
|
30
|
+
});
|
|
31
|
+
describe('happy', ()=>{
|
|
32
|
+
it('should delegate to schemaFactory when literal metadata is provided', ()=>{
|
|
33
|
+
const result = literal({
|
|
34
|
+
name: 'Room',
|
|
35
|
+
value: 'global'
|
|
36
|
+
});
|
|
37
|
+
expect(schemaFactoryMock).toHaveBeenCalledTimes(1);
|
|
38
|
+
const factoryInput = getFactoryInput();
|
|
39
|
+
expect(factoryInput.name).toBe('Room');
|
|
40
|
+
expect(factoryInput.type).toBe('literal<global>');
|
|
41
|
+
expect(factoryInput.ast(schemaContextMock)).toEqual({
|
|
42
|
+
type: 'literal',
|
|
43
|
+
name: 'Room',
|
|
44
|
+
constraints: {
|
|
45
|
+
value: 'global'
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
expect(result).toBe(schemaFactoryMock.mock.results[0]?.value);
|
|
49
|
+
});
|
|
50
|
+
it('should pass doc metadata to schemaFactory when doc is provided', ()=>{
|
|
51
|
+
const doc = {
|
|
52
|
+
summary: 'literal doc'
|
|
53
|
+
};
|
|
54
|
+
literal({
|
|
55
|
+
name: 'Mode',
|
|
56
|
+
value: 'fast',
|
|
57
|
+
doc
|
|
58
|
+
});
|
|
59
|
+
const factoryInput = getFactoryInput();
|
|
60
|
+
expect(factoryInput.doc).toEqual(doc);
|
|
61
|
+
});
|
|
62
|
+
it('should return literal value when input matches literal', ()=>{
|
|
63
|
+
literal({
|
|
64
|
+
name: 'Flag',
|
|
65
|
+
value: true
|
|
66
|
+
});
|
|
67
|
+
const factoryInput = getFactoryInput();
|
|
68
|
+
const parsed = factoryInput.validate(true, schemaContextMock);
|
|
69
|
+
expect(parsed).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('sad', ()=>{
|
|
73
|
+
it('should throw schema error payload when input does not match literal', ()=>{
|
|
74
|
+
literal({
|
|
75
|
+
name: 'Flag',
|
|
76
|
+
value: false
|
|
77
|
+
});
|
|
78
|
+
const factoryInput = getFactoryInput();
|
|
79
|
+
const thrown = captureThrow(()=>factoryInput.validate(true, schemaContextMock));
|
|
80
|
+
expect(thrown.threw).toBe(true);
|
|
81
|
+
expect(thrown.value).toEqual({
|
|
82
|
+
message: 'Expected false',
|
|
83
|
+
code: 'literal.value'
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
package/dist/number.cjs
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
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
|
+
number: ()=>number
|
|
28
|
+
});
|
|
29
|
+
const external_schemaFactory_cjs_namespaceObject = require("./schemaFactory.cjs");
|
|
30
|
+
const external_typeGuards_cjs_namespaceObject = require("./typeGuards.cjs");
|
|
31
|
+
const number = ({ name = 'number', doc } = {})=>(0, external_schemaFactory_cjs_namespaceObject.schemaFactory)({
|
|
32
|
+
name,
|
|
33
|
+
type: 'number',
|
|
34
|
+
doc,
|
|
35
|
+
ast: ()=>({
|
|
36
|
+
type: 'number',
|
|
37
|
+
name
|
|
38
|
+
}),
|
|
39
|
+
validate: (input)=>{
|
|
40
|
+
if (!(0, external_typeGuards_cjs_namespaceObject.isNumber)(input)) throw {
|
|
41
|
+
message: 'Data is not a number',
|
|
42
|
+
code: 'number.type'
|
|
43
|
+
};
|
|
44
|
+
return input;
|
|
45
|
+
},
|
|
46
|
+
chain: {
|
|
47
|
+
min: (data, _ctx)=>(min)=>{
|
|
48
|
+
if (data < min) throw {
|
|
49
|
+
message: `Expected number >= ${min}`,
|
|
50
|
+
code: 'number.min',
|
|
51
|
+
context: {
|
|
52
|
+
min
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
return data;
|
|
56
|
+
},
|
|
57
|
+
max: (data, _ctx)=>(max)=>{
|
|
58
|
+
if (data > max) throw {
|
|
59
|
+
message: `Expected number <= ${max}`,
|
|
60
|
+
code: 'number.max',
|
|
61
|
+
context: {
|
|
62
|
+
max
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
return data;
|
|
66
|
+
},
|
|
67
|
+
int: (data, _ctx)=>()=>{
|
|
68
|
+
if (!Number.isInteger(data)) throw {
|
|
69
|
+
message: 'Expected integer',
|
|
70
|
+
code: 'number.int'
|
|
71
|
+
};
|
|
72
|
+
return data;
|
|
73
|
+
},
|
|
74
|
+
positive: (data, _ctx)=>()=>{
|
|
75
|
+
if (data <= 0) throw {
|
|
76
|
+
message: 'Expected positive number',
|
|
77
|
+
code: 'number.positive'
|
|
78
|
+
};
|
|
79
|
+
return data;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
exports.number = __webpack_exports__.number;
|
|
84
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
85
|
+
"number"
|
|
86
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
87
|
+
Object.defineProperty(exports, '__esModule', {
|
|
88
|
+
value: true
|
|
89
|
+
});
|
package/dist/number.d.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { SchemaContext, SchemaDoc } from './types.js';
|
|
2
|
+
export interface NumberFactoryInput {
|
|
3
|
+
name?: string;
|
|
4
|
+
doc?: SchemaDoc;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Chain operation: validates minimum numeric value.
|
|
8
|
+
*
|
|
9
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/number
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // Enforces a minimum numeric value.
|
|
13
|
+
* number().min(0)
|
|
14
|
+
*/
|
|
15
|
+
export interface NumberChainMin {
|
|
16
|
+
(data: number, ctx: SchemaContext): (min: number) => number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Chain operation: validates maximum numeric value.
|
|
20
|
+
*
|
|
21
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/number
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Enforces a maximum numeric value.
|
|
25
|
+
* number().max(100)
|
|
26
|
+
*/
|
|
27
|
+
export interface NumberChainMax {
|
|
28
|
+
(data: number, ctx: SchemaContext): (max: number) => number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Chain operation: validates integer-only numbers.
|
|
32
|
+
*
|
|
33
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/number
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // Restricts accepted values to integers only.
|
|
37
|
+
* number().int()
|
|
38
|
+
*/
|
|
39
|
+
export interface NumberChainInt {
|
|
40
|
+
(data: number, ctx: SchemaContext): () => number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Chain operation: validates positive numbers.
|
|
44
|
+
*
|
|
45
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/number
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* // Restricts accepted values to positive numbers.
|
|
49
|
+
* number().positive()
|
|
50
|
+
*/
|
|
51
|
+
export interface NumberChainPositive {
|
|
52
|
+
(data: number, ctx: SchemaContext): () => number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Chain map for `number()` schemas.
|
|
56
|
+
*
|
|
57
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/number
|
|
58
|
+
*/
|
|
59
|
+
export interface NumberChainDefinition {
|
|
60
|
+
min: NumberChainMin;
|
|
61
|
+
max: NumberChainMax;
|
|
62
|
+
int: NumberChainInt;
|
|
63
|
+
positive: NumberChainPositive;
|
|
64
|
+
}
|
|
65
|
+
export type NumberSchema = ReturnType<typeof number>;
|
|
66
|
+
/**
|
|
67
|
+
* number is part of the public LIVON API.
|
|
68
|
+
*
|
|
69
|
+
* @remarks
|
|
70
|
+
* Parameter and return types are defined in the TypeScript signature.
|
|
71
|
+
*
|
|
72
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/number
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* // Creates a basic number schema and validates an age.
|
|
76
|
+
* const Age = number();
|
|
77
|
+
* Age.parse(21);
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* // Combines chain rules for integer, positive, and minimum age checks.
|
|
81
|
+
* const AdultAge = number().int().positive().min(18);
|
|
82
|
+
* AdultAge.parse(21);
|
|
83
|
+
*/
|
|
84
|
+
export declare const number: ({ name, doc }?: NumberFactoryInput) => import("./schemaFactory.js").SchemaWithChain<number, import("./schemaFactory.js").SchemaFactoryChainDefinition<number>>;
|
package/dist/number.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { schemaFactory } from "./schemaFactory.js";
|
|
2
|
+
import { isNumber } from "./typeGuards.js";
|
|
3
|
+
const number = ({ name = 'number', doc } = {})=>schemaFactory({
|
|
4
|
+
name,
|
|
5
|
+
type: 'number',
|
|
6
|
+
doc,
|
|
7
|
+
ast: ()=>({
|
|
8
|
+
type: 'number',
|
|
9
|
+
name
|
|
10
|
+
}),
|
|
11
|
+
validate: (input)=>{
|
|
12
|
+
if (!isNumber(input)) throw {
|
|
13
|
+
message: 'Data is not a number',
|
|
14
|
+
code: 'number.type'
|
|
15
|
+
};
|
|
16
|
+
return input;
|
|
17
|
+
},
|
|
18
|
+
chain: {
|
|
19
|
+
min: (data, _ctx)=>(min)=>{
|
|
20
|
+
if (data < min) throw {
|
|
21
|
+
message: `Expected number >= ${min}`,
|
|
22
|
+
code: 'number.min',
|
|
23
|
+
context: {
|
|
24
|
+
min
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
return data;
|
|
28
|
+
},
|
|
29
|
+
max: (data, _ctx)=>(max)=>{
|
|
30
|
+
if (data > max) throw {
|
|
31
|
+
message: `Expected number <= ${max}`,
|
|
32
|
+
code: 'number.max',
|
|
33
|
+
context: {
|
|
34
|
+
max
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
return data;
|
|
38
|
+
},
|
|
39
|
+
int: (data, _ctx)=>()=>{
|
|
40
|
+
if (!Number.isInteger(data)) throw {
|
|
41
|
+
message: 'Expected integer',
|
|
42
|
+
code: 'number.int'
|
|
43
|
+
};
|
|
44
|
+
return data;
|
|
45
|
+
},
|
|
46
|
+
positive: (data, _ctx)=>()=>{
|
|
47
|
+
if (data <= 0) throw {
|
|
48
|
+
message: 'Expected positive number',
|
|
49
|
+
code: 'number.positive'
|
|
50
|
+
};
|
|
51
|
+
return data;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
export { number };
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_exports__ = {};
|
|
3
|
+
const external_vitest_namespaceObject = require("vitest");
|
|
4
|
+
const external_number_cjs_namespaceObject = require("./number.cjs");
|
|
5
|
+
const external_schemaFactory_cjs_namespaceObject = require("./schemaFactory.cjs");
|
|
6
|
+
const external_typeGuards_cjs_namespaceObject = require("./typeGuards.cjs");
|
|
7
|
+
const index_cjs_namespaceObject = require("./testing/mocks/index.cjs");
|
|
8
|
+
external_vitest_namespaceObject.vi.mock('./schemaFactory.js', ()=>({
|
|
9
|
+
schemaFactory: external_vitest_namespaceObject.vi.fn()
|
|
10
|
+
}));
|
|
11
|
+
external_vitest_namespaceObject.vi.mock('./typeGuards.js', ()=>({
|
|
12
|
+
isNumber: external_vitest_namespaceObject.vi.fn()
|
|
13
|
+
}));
|
|
14
|
+
const schemaFactoryMock = external_vitest_namespaceObject.vi.mocked(external_schemaFactory_cjs_namespaceObject.schemaFactory);
|
|
15
|
+
const isNumberMock = external_vitest_namespaceObject.vi.mocked(external_typeGuards_cjs_namespaceObject.isNumber);
|
|
16
|
+
const schemaContextMock = (0, index_cjs_namespaceObject.createSchemaContextMock)();
|
|
17
|
+
const schemaFactoryImplementation = (0, index_cjs_namespaceObject.createSchemaFactoryMock)();
|
|
18
|
+
const getFactoryInput = ()=>{
|
|
19
|
+
const call = schemaFactoryMock.mock.calls[0];
|
|
20
|
+
if (!call) throw new Error('schemaFactory should be called once before reading input');
|
|
21
|
+
return call[0];
|
|
22
|
+
};
|
|
23
|
+
(0, external_vitest_namespaceObject.describe)('number()', ()=>{
|
|
24
|
+
(0, external_vitest_namespaceObject.beforeAll)(()=>{
|
|
25
|
+
schemaFactoryMock.mockImplementation(schemaFactoryImplementation);
|
|
26
|
+
});
|
|
27
|
+
(0, external_vitest_namespaceObject.beforeEach)(()=>{
|
|
28
|
+
schemaFactoryMock.mockClear();
|
|
29
|
+
schemaFactoryImplementation.mockClear();
|
|
30
|
+
isNumberMock.mockReset();
|
|
31
|
+
isNumberMock.mockReturnValue(true);
|
|
32
|
+
});
|
|
33
|
+
(0, external_vitest_namespaceObject.afterEach)(()=>{
|
|
34
|
+
isNumberMock.mockClear();
|
|
35
|
+
});
|
|
36
|
+
(0, external_vitest_namespaceObject.afterAll)(()=>{
|
|
37
|
+
schemaFactoryMock.mockReset();
|
|
38
|
+
schemaFactoryImplementation.mockReset();
|
|
39
|
+
isNumberMock.mockReset();
|
|
40
|
+
});
|
|
41
|
+
(0, external_vitest_namespaceObject.describe)('happy', ()=>{
|
|
42
|
+
(0, external_vitest_namespaceObject.it)('should delegate to schemaFactory when number schema is created', ()=>{
|
|
43
|
+
const result = (0, external_number_cjs_namespaceObject.number)();
|
|
44
|
+
(0, external_vitest_namespaceObject.expect)(schemaFactoryMock).toHaveBeenCalledTimes(1);
|
|
45
|
+
const factoryInput = getFactoryInput();
|
|
46
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.name).toBe('number');
|
|
47
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.type).toBe('number');
|
|
48
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.ast(schemaContextMock)).toEqual({
|
|
49
|
+
type: 'number',
|
|
50
|
+
name: 'number'
|
|
51
|
+
});
|
|
52
|
+
(0, external_vitest_namespaceObject.expect)(Object.keys(factoryInput.chain)).toEqual([
|
|
53
|
+
'min',
|
|
54
|
+
'max',
|
|
55
|
+
'int',
|
|
56
|
+
'positive'
|
|
57
|
+
]);
|
|
58
|
+
(0, external_vitest_namespaceObject.expect)(result).toBe(schemaFactoryMock.mock.results[0]?.value);
|
|
59
|
+
});
|
|
60
|
+
(0, external_vitest_namespaceObject.it)('should pass custom metadata to schemaFactory when options are provided', ()=>{
|
|
61
|
+
const doc = {
|
|
62
|
+
summary: 'number doc'
|
|
63
|
+
};
|
|
64
|
+
(0, external_number_cjs_namespaceObject.number)({
|
|
65
|
+
name: 'Count',
|
|
66
|
+
doc
|
|
67
|
+
});
|
|
68
|
+
const factoryInput = getFactoryInput();
|
|
69
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.name).toBe('Count');
|
|
70
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.doc).toEqual(doc);
|
|
71
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.ast(schemaContextMock)).toEqual({
|
|
72
|
+
type: 'number',
|
|
73
|
+
name: 'Count'
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
(0, external_vitest_namespaceObject.it)('should validate input through isNumber when input is number', ()=>{
|
|
77
|
+
(0, external_number_cjs_namespaceObject.number)();
|
|
78
|
+
const factoryInput = getFactoryInput();
|
|
79
|
+
const parsed = factoryInput.validate(42, schemaContextMock);
|
|
80
|
+
(0, external_vitest_namespaceObject.expect)(parsed).toBe(42);
|
|
81
|
+
(0, external_vitest_namespaceObject.expect)(isNumberMock).toHaveBeenCalledWith(42);
|
|
82
|
+
});
|
|
83
|
+
(0, external_vitest_namespaceObject.it)('should return input for all chain methods when constraints are valid', ()=>{
|
|
84
|
+
(0, external_number_cjs_namespaceObject.number)();
|
|
85
|
+
const factoryInput = getFactoryInput();
|
|
86
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.chain.min(5, schemaContextMock)(1)).toBe(5);
|
|
87
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.chain.max(5, schemaContextMock)(8)).toBe(5);
|
|
88
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.chain.int(5, schemaContextMock)()).toBe(5);
|
|
89
|
+
(0, external_vitest_namespaceObject.expect)(factoryInput.chain.positive(5, schemaContextMock)()).toBe(5);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
(0, external_vitest_namespaceObject.describe)('sad', ()=>{
|
|
93
|
+
(0, external_vitest_namespaceObject.it)('should throw schema error payload when input is not number', ()=>{
|
|
94
|
+
isNumberMock.mockReturnValue(false);
|
|
95
|
+
(0, external_number_cjs_namespaceObject.number)();
|
|
96
|
+
const factoryInput = getFactoryInput();
|
|
97
|
+
const thrown = (0, index_cjs_namespaceObject.captureThrow)(()=>factoryInput.validate('x', schemaContextMock));
|
|
98
|
+
(0, external_vitest_namespaceObject.expect)(thrown.threw).toBe(true);
|
|
99
|
+
(0, external_vitest_namespaceObject.expect)(thrown.value).toEqual({
|
|
100
|
+
message: 'Data is not a number',
|
|
101
|
+
code: 'number.type'
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
(0, external_vitest_namespaceObject.it)('should throw min error when value is below minimum', ()=>{
|
|
105
|
+
(0, external_number_cjs_namespaceObject.number)();
|
|
106
|
+
const factoryInput = getFactoryInput();
|
|
107
|
+
const thrown = (0, index_cjs_namespaceObject.captureThrow)(()=>factoryInput.chain.min(1, schemaContextMock)(5));
|
|
108
|
+
(0, external_vitest_namespaceObject.expect)(thrown.threw).toBe(true);
|
|
109
|
+
(0, external_vitest_namespaceObject.expect)(thrown.value).toEqual({
|
|
110
|
+
message: 'Expected number >= 5',
|
|
111
|
+
code: 'number.min',
|
|
112
|
+
context: {
|
|
113
|
+
min: 5
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
(0, external_vitest_namespaceObject.it)('should throw max error when value is above maximum', ()=>{
|
|
118
|
+
(0, external_number_cjs_namespaceObject.number)();
|
|
119
|
+
const factoryInput = getFactoryInput();
|
|
120
|
+
const thrown = (0, index_cjs_namespaceObject.captureThrow)(()=>factoryInput.chain.max(10, schemaContextMock)(8));
|
|
121
|
+
(0, external_vitest_namespaceObject.expect)(thrown.threw).toBe(true);
|
|
122
|
+
(0, external_vitest_namespaceObject.expect)(thrown.value).toEqual({
|
|
123
|
+
message: 'Expected number <= 8',
|
|
124
|
+
code: 'number.max',
|
|
125
|
+
context: {
|
|
126
|
+
max: 8
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
(0, external_vitest_namespaceObject.it)('should throw int error when value is not integer', ()=>{
|
|
131
|
+
(0, external_number_cjs_namespaceObject.number)();
|
|
132
|
+
const factoryInput = getFactoryInput();
|
|
133
|
+
const thrown = (0, index_cjs_namespaceObject.captureThrow)(()=>factoryInput.chain.int(2.5, schemaContextMock)());
|
|
134
|
+
(0, external_vitest_namespaceObject.expect)(thrown.threw).toBe(true);
|
|
135
|
+
(0, external_vitest_namespaceObject.expect)(thrown.value).toEqual({
|
|
136
|
+
message: 'Expected integer',
|
|
137
|
+
code: 'number.int'
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
(0, external_vitest_namespaceObject.it)('should throw positive error when value is not positive', ()=>{
|
|
141
|
+
(0, external_number_cjs_namespaceObject.number)();
|
|
142
|
+
const factoryInput = getFactoryInput();
|
|
143
|
+
const thrown = (0, index_cjs_namespaceObject.captureThrow)(()=>factoryInput.chain.positive(0, schemaContextMock)());
|
|
144
|
+
(0, external_vitest_namespaceObject.expect)(thrown.threw).toBe(true);
|
|
145
|
+
(0, external_vitest_namespaceObject.expect)(thrown.value).toEqual({
|
|
146
|
+
message: 'Expected positive number',
|
|
147
|
+
code: 'number.positive'
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
153
|
+
Object.defineProperty(exports, '__esModule', {
|
|
154
|
+
value: true
|
|
155
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|