@modulify/validator 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/README.md +12 -2
  3. package/dist/assert-BDOtHdLx.cjs +289 -0
  4. package/dist/assert-CzMg5aO7.mjs +206 -0
  5. package/dist/assert.cjs +7 -65
  6. package/dist/assert.d.cts +37 -0
  7. package/dist/assert.d.mts +37 -0
  8. package/dist/assert.d.ts +24 -3
  9. package/dist/assert.mjs +2 -66
  10. package/dist/assertions-DPYCHREw.mjs +297 -0
  11. package/dist/assertions-nfOKqcjs.cjs +476 -0
  12. package/dist/assertions.cjs +34 -206
  13. package/dist/assertions.d.cts +56 -0
  14. package/dist/assertions.d.mts +56 -0
  15. package/dist/assertions.d.ts +43 -45
  16. package/dist/assertions.mjs +3 -207
  17. package/dist/checkers.d.cts +8 -0
  18. package/dist/checkers.d.mts +8 -0
  19. package/dist/checkers.d.ts +1 -1
  20. package/dist/combinators.cjs +303 -304
  21. package/dist/combinators.d.cts +16 -0
  22. package/dist/combinators.d.mts +16 -0
  23. package/dist/combinators.d.ts +15 -16
  24. package/dist/combinators.mjs +304 -315
  25. package/dist/constraints.d.cts +4 -0
  26. package/dist/constraints.d.mts +4 -0
  27. package/dist/constraints.d.ts +2 -2
  28. package/dist/extractors.d.cts +2 -0
  29. package/dist/extractors.d.mts +2 -0
  30. package/dist/index.cjs +210 -213
  31. package/dist/index.d.cts +12 -0
  32. package/dist/index.d.mts +12 -0
  33. package/dist/index.d.ts +9 -9
  34. package/dist/index.mjs +165 -218
  35. package/dist/json-schema.cjs +364 -489
  36. package/dist/json-schema.d.cts +14 -0
  37. package/dist/json-schema.d.mts +14 -0
  38. package/dist/json-schema.d.ts +3 -3
  39. package/dist/json-schema.mjs +365 -492
  40. package/dist/metadata.cjs +6 -7
  41. package/dist/metadata.d.cts +8 -0
  42. package/dist/metadata.d.mts +8 -0
  43. package/dist/metadata.d.ts +2 -2
  44. package/dist/metadata.mjs +2 -8
  45. package/dist/predicates.cjs +98 -41
  46. package/dist/predicates.d.cts +77 -0
  47. package/dist/predicates.d.mts +77 -0
  48. package/dist/predicates.d.ts +25 -4
  49. package/dist/predicates.mjs +92 -66
  50. package/dist/types/index.d.cts +984 -0
  51. package/dist/types/index.d.mts +984 -0
  52. package/dist/types/index.d.ts +984 -0
  53. package/dist/types/json-schema.d.cts +75 -0
  54. package/dist/types/json-schema.d.mts +75 -0
  55. package/dist/types/json-schema.d.ts +75 -0
  56. package/dist/violations.d.cts +29 -0
  57. package/dist/violations.d.mts +29 -0
  58. package/dist/violations.d.ts +1 -1
  59. package/docs/RELEASING.md +66 -0
  60. package/docs/en/00-index.md +2 -0
  61. package/docs/en/01-shape-api.md +35 -10
  62. package/docs/en/02-metadata-and-introspection.md +2 -1
  63. package/docs/en/03-violations.md +1 -1
  64. package/docs/en/04-json-schema-export.md +5 -0
  65. package/docs/en/05-public-api.md +35 -3
  66. package/docs/en/06-common-recipes.md +2 -1
  67. package/docs/en/07-ai-reference.md +5 -2
  68. package/docs/en/08-violation-code-types.md +28 -2
  69. package/docs/en/09-migration.md +75 -0
  70. package/docs/ru/00-index.md +2 -0
  71. package/docs/ru/01-shape-api.md +35 -10
  72. package/docs/ru/02-metadata-and-introspection.md +2 -1
  73. package/docs/ru/03-violations.md +1 -1
  74. package/docs/ru/04-json-schema-export.md +5 -0
  75. package/docs/ru/05-public-api.md +35 -3
  76. package/docs/ru/06-common-recipes.md +2 -1
  77. package/docs/ru/07-ai-reference.md +5 -2
  78. package/docs/ru/08-violation-code-types.md +28 -2
  79. package/docs/ru/09-migration.md +76 -0
  80. package/docs/ru/README.md +10 -2
  81. package/package.json +63 -37
  82. package/types/index.d.ts +275 -115
  83. package/dist/metadata.cjs.js +0 -130
  84. package/dist/metadata.es.js +0 -131
package/CHANGELOG.md CHANGED
@@ -1,6 +1,31 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
3
+ ## 0.3.0
4
+
5
+ ### ⚠ BREAKING CHANGE* **types:** Public type names were simplified
6
+ * **types:** Exported public type names were renamed without compatibility aliases.
7
+ * Object shape refinements were made async-first
8
+ * shape.refine(...) was changed to the async-first object-level API. Use shape.refine.sync(...) for explicitly sync-safe object rules.
9
+ * ObjectShapeRefinement now describes the async-first refinement contract. Use ObjectShapeRefinementSync for the explicit sync-only type name.
10
+ * validate.sync(...), matches.sync(...), and shape.check(...) now throw when they encounter async object-level shape refinements.
11
+
12
+
13
+ ### Features
14
+
15
+ * Object shape refinements were made async-first ([8877b93](https://github.com/modulify/validator/commit/8877b93fa4a8b7c29c918d5d9df08e90ae816379))
16
+ * Built-in value guards were expanded ([1846c17](https://github.com/modulify/validator/commit/1846c176188182b76074b46a60c12d3a2af790a0))
17
+
18
+ ### Bug Fixes
19
+
20
+ * **predicates:** Shape field validation and inference were corrected ([b2c0e44](https://github.com/modulify/validator/commit/b2c0e441ecf923c0ed3e3a8cbe432a052fed42ce))
21
+ * **types:** Strict assertion contracts were aligned ([2bdd390](https://github.com/modulify/validator/commit/2bdd39019caff5522821ab3b07d832efdd4ca1ab))
22
+ * **build:** Packed ESM and CommonJS consumers were supported ([6fd0c3b](https://github.com/modulify/validator/commit/6fd0c3b2ad7adca314b321283245f831deb2e160))
23
+
24
+ ### Performance Improvements
25
+
26
+ * **build:** Tree-shaking hints were added ([29bbc70](https://github.com/modulify/validator/commit/29bbc7017b58ef50927ccda745a7be76a8b73ba4))
27
+
28
+ All notable changes to this project will be documented in this file. Release notes are generated by [@modulify/conventional-release](https://github.com/modulify/conventional/tree/main/packages/conventional-release) from Conventional Commits.
4
29
 
5
30
  ### [0.2.1](https://github.com/modulify/validator/compare/v0.2.0...v0.2.1) (2026-03-09)
6
31
 
@@ -73,3 +98,4 @@ All notable changes to this project will be documented in this file. See [standa
73
98
  * Added meta to OneOf violation ([8dd59fc](https://github.com/modulify/validator/commit/8dd59fc2663df1e791ad95449ba774374b6e0bf8))
74
99
  * Added possibility to override initial valitators set ([0192f44](https://github.com/modulify/validator/commit/0192f44e4e9e487cbc1230cd588ea62d926e7143))
75
100
  * Asynchronous validation ([1505f41](https://github.com/modulify/validator/commit/1505f417bd869ba762f6a91d1d30a360d2505ad4))
101
+
package/README.md CHANGED
@@ -204,7 +204,7 @@ if (ok) {
204
204
 
205
205
  ## Shape API
206
206
 
207
- `shape(...)` is the reusable object-shape API. It validates nested record-like objects and exposes small immutable helpers such as `strict()`, `pick()`, `omit()`, `partial()`, `extend()`, `merge()`, `refine()`, and `fieldsMatch(...)`.
207
+ `shape(...)` is the reusable object-shape API. It validates nested record-like objects and exposes small immutable helpers such as `strict()`, `pick()`, `omit()`, `partial()`, `extend()`, `merge()`, async-first `refine()`, explicit `refine.sync()`, and `fieldsMatch(...)`.
208
208
 
209
209
  ```typescript
210
210
  import {
@@ -270,11 +270,17 @@ A practical way to think about the library is:
270
270
 
271
271
  In the current API this usually looks like:
272
272
 
273
- - leaf checks with assertions such as `isString`, `isDefined`, `hasLength`, `oneOf`;
273
+ - guard assertions such as `isString`, `isNumber`, `isDefined`, `oneOf(...)` establish the base domain for a value;
274
+ - refinement assertions such as `hasLength(...)`, `hasPattern(...)`, `startsWith(...)`, `hasValue(...)`, `multipleOf(...)` validate properties inside that domain;
274
275
  - schema composition with combinators such as `exact`, `optional`, `nullable`, `nullish`, `shape(...)`, `each(...)`;
275
276
  - typed validation through `validate(...)` or `validate.sync(...)`;
276
277
  - narrowing of the original sync variable through `matches.sync(...)`.
277
278
 
279
+ Sequential assertion arrays are stage-aware. A tuple like `[isString, hasLength({ min: 3 })]` is valid, while incompatible combinations like `[isNumber, hasLength({ min: 3 })]` are rejected by TypeScript.
280
+ Refinement assertions are not meant to be passed to `validate(...)` or `matches.sync(...)` on their own.
281
+
282
+ `validate(...)` is the default async-first validation entrypoint. `validate.sync(...)` and `matches.sync(...)` are specialized sync APIs and will throw if they encounter async validators or async object-level `shape(...).refine(...)` rules.
283
+
278
284
  ## Violations
279
285
 
280
286
  `validate(...)` returns machine-readable `Violation[]`, and `collection(...)` can wrap that list into a small helper API for exact path lookups and tree traversal.
@@ -354,6 +360,8 @@ Two additional guides are useful when you want faster practical navigation inste
354
360
  - [Common Recipes](./docs/en/06-common-recipes.md) - task-oriented examples for payload validation, wrapper choice, reusable shapes, form error mapping, and JSON Schema export.
355
361
  - [AI Reference](./docs/en/07-ai-reference.md) - compact contract summary for agents, tooling, and quick semantic lookup.
356
362
 
363
+ - [Migration From 0.2.1](./docs/en/09-migration.md)
364
+
357
365
  ## Notes
358
366
 
359
367
  - Assertions return structured metadata instead of messages.
@@ -366,3 +374,5 @@ Two additional guides are useful when you want faster practical navigation inste
366
374
  ## Translations
367
375
 
368
376
  - [Russian](./docs/ru/README.md)
377
+
378
+ Release workflow and npm OIDC setup: [Releasing](docs/RELEASING.md).
@@ -0,0 +1,289 @@
1
+ //#region src/constraints.ts
2
+ var isValidator = (constraint) => "run" in constraint;
3
+ function arrayify(value) {
4
+ return Array.isArray(value) ? [...value] : [value];
5
+ }
6
+ function matchesConstraints(value, constraints) {
7
+ let establishedDomain = false;
8
+ return arrayify(constraints).every((constraint) => {
9
+ if (isValidator(constraint)) {
10
+ establishedDomain = false;
11
+ return constraint.check(value);
12
+ }
13
+ if (!establishedDomain && isRefinementAssertion(constraint)) return false;
14
+ const matched = establishedDomain && isRefinementAssertion(constraint) ? checkRefinementAssertion(constraint, value) : constraint.check(value);
15
+ if (matched) establishedDomain = true;
16
+ return matched;
17
+ });
18
+ }
19
+ //#endregion
20
+ //#region src/metadata.ts
21
+ var constraintDescriptorSymbol = Symbol("modulify.validator.descriptor");
22
+ var constraintMetadataSymbol = Symbol("modulify.validator.metadata");
23
+ var cloneCallableConstraint = (constraint) => {
24
+ const source = constraint;
25
+ const cloned = ((value) => source(value));
26
+ const { length: _length, name: _name, prototype: _prototype, ...descriptors } = Object.getOwnPropertyDescriptors(source);
27
+ Object.defineProperties(cloned, descriptors);
28
+ try {
29
+ Object.defineProperty(cloned, "name", {
30
+ configurable: true,
31
+ value: source.name
32
+ });
33
+ } catch {}
34
+ Object.setPrototypeOf(cloned, Object.getPrototypeOf(source));
35
+ return cloned;
36
+ };
37
+ var cloneConstraint = (constraint) => {
38
+ if (typeof constraint === "function") return cloneCallableConstraint(constraint);
39
+ return Object.create(Object.getPrototypeOf(constraint), Object.getOwnPropertyDescriptors(constraint));
40
+ };
41
+ var freezeMetadata = (metadata) => Object.freeze({ ...metadata });
42
+ var getConstraintMetadata = (constraint) => {
43
+ return constraint[constraintMetadataSymbol];
44
+ };
45
+ var getDescriptorFactory = (constraint) => {
46
+ return constraint[constraintDescriptorSymbol];
47
+ };
48
+ var getPublicDescriptor = (constraint) => {
49
+ if (!isValidator(constraint)) return;
50
+ const { describe } = constraint;
51
+ return typeof describe === "function" ? describe.call(constraint) : void 0;
52
+ };
53
+ var inferAssertionDescriptor = (assertion) => ({
54
+ kind: "assertion",
55
+ name: assertion.name,
56
+ bail: assertion.bail,
57
+ code: assertion.name,
58
+ args: [],
59
+ constraints: assertion.constraints.map(([, , code, ...args]) => ({
60
+ code,
61
+ args
62
+ }))
63
+ });
64
+ var withMetadata = (descriptor, metadata) => {
65
+ if (!metadata) return descriptor;
66
+ return {
67
+ ...descriptor,
68
+ metadata
69
+ };
70
+ };
71
+ var attachConstraintDescriptor = (constraint, describe) => {
72
+ Object.defineProperty(constraint, constraintDescriptorSymbol, {
73
+ configurable: false,
74
+ enumerable: false,
75
+ value: describe,
76
+ writable: false
77
+ });
78
+ return constraint;
79
+ };
80
+ var meta = (constraint, metadata) => {
81
+ const cloned = cloneConstraint(constraint);
82
+ const nextMetadata = freezeMetadata({
83
+ ...getConstraintMetadata(constraint) ?? {},
84
+ ...metadata
85
+ });
86
+ Object.defineProperty(cloned, constraintMetadataSymbol, {
87
+ configurable: true,
88
+ enumerable: false,
89
+ value: nextMetadata,
90
+ writable: false
91
+ });
92
+ return cloned;
93
+ };
94
+ var custom = (validator) => validator;
95
+ var describeConstraints = (constraints) => {
96
+ const values = arrayify(constraints);
97
+ return values.length === 1 ? describe(values[0]) : {
98
+ kind: "allOf",
99
+ constraints: values.map((value) => describe(value))
100
+ };
101
+ };
102
+ var describe = (constraint) => {
103
+ const factory = getDescriptorFactory(constraint);
104
+ const metadata = getConstraintMetadata(constraint);
105
+ if (factory) return withMetadata(factory(), metadata);
106
+ const publicDescriptor = getPublicDescriptor(constraint);
107
+ if (publicDescriptor) return withMetadata(publicDescriptor, metadata);
108
+ if (isValidator(constraint)) return withMetadata({ kind: "validator" }, metadata);
109
+ return withMetadata(inferAssertionDescriptor(constraint), metadata);
110
+ };
111
+ //#endregion
112
+ //#region src/assert.ts
113
+ var assertionStageSymbol = Symbol("modulify.validator.assertion.stage");
114
+ var runRefinementSymbol = Symbol("modulify.validator.assertion.runRefinement");
115
+ var checkRefinementSymbol = Symbol("modulify.validator.assertion.checkRefinement");
116
+ var createAssertion = (stage, predicate, meta, constraints = []) => {
117
+ const assertionCode = meta.code ?? meta.name;
118
+ const assertionArgs = meta.args ?? [];
119
+ const violationSubject = {
120
+ kind: "assertion",
121
+ name: meta.name,
122
+ code: assertionCode,
123
+ args: assertionArgs
124
+ };
125
+ const runConstraints = (value) => {
126
+ for (const [extract, check, code, ...args] of constraints) if (!check(extract(value), ...args)) return {
127
+ value,
128
+ violates: {
129
+ kind: "assertion",
130
+ name: meta.name,
131
+ code,
132
+ args
133
+ }
134
+ };
135
+ return null;
136
+ };
137
+ const checkConstraints = (value) => !constraints.length || constraints.every(([extract, check, , ...args]) => check(extract(value), ...args));
138
+ const assertion = ((value) => {
139
+ if (!predicate(value)) return {
140
+ value,
141
+ violates: violationSubject
142
+ };
143
+ return runConstraints(value);
144
+ });
145
+ Object.defineProperties(assertion, {
146
+ name: {
147
+ configurable: true,
148
+ value: meta.name
149
+ },
150
+ bail: {
151
+ enumerable: true,
152
+ value: meta.bail
153
+ },
154
+ constraints: {
155
+ enumerable: true,
156
+ value: constraints
157
+ },
158
+ check: {
159
+ enumerable: true,
160
+ value: (value) => predicate(value) && checkConstraints(value)
161
+ },
162
+ [assertionStageSymbol]: {
163
+ enumerable: false,
164
+ value: stage
165
+ },
166
+ [runRefinementSymbol]: {
167
+ enumerable: false,
168
+ value: (value) => runConstraints(value)
169
+ },
170
+ [checkRefinementSymbol]: {
171
+ enumerable: false,
172
+ value: (value) => checkConstraints(value)
173
+ }
174
+ });
175
+ return /* @__PURE__ */ attachConstraintDescriptor(assertion, () => ({
176
+ kind: "assertion",
177
+ name: meta.name,
178
+ bail: meta.bail,
179
+ code: assertionCode,
180
+ args: assertionArgs,
181
+ constraints: constraints.map(([, , code, ...args]) => ({
182
+ code,
183
+ args
184
+ }))
185
+ }));
186
+ };
187
+ var assert = (predicate, meta, constraints = []) => {
188
+ return createAssertion("guard", predicate, meta, constraints);
189
+ };
190
+ var isRefinementAssertion = (constraint) => {
191
+ return typeof constraint === "function" && constraint[assertionStageSymbol] === "refinement";
192
+ };
193
+ var runRefinementAssertion = (constraint, value) => {
194
+ const runRefinement = constraint[runRefinementSymbol];
195
+ return runRefinement ? runRefinement(value) : constraint(value);
196
+ };
197
+ var checkRefinementAssertion = (constraint, value) => {
198
+ const checkRefinement = constraint[checkRefinementSymbol];
199
+ return checkRefinement ? checkRefinement(value) : constraint.check(value);
200
+ };
201
+ var createRefinement = (meta, constraints = []) => {
202
+ return createAssertion("refinement", ((value) => true), meta, constraints);
203
+ };
204
+ var refine = createRefinement;
205
+ //#endregion
206
+ Object.defineProperty(exports, "arrayify", {
207
+ enumerable: true,
208
+ get: function() {
209
+ return arrayify;
210
+ }
211
+ });
212
+ Object.defineProperty(exports, "assert", {
213
+ enumerable: true,
214
+ get: function() {
215
+ return assert;
216
+ }
217
+ });
218
+ Object.defineProperty(exports, "attachConstraintDescriptor", {
219
+ enumerable: true,
220
+ get: function() {
221
+ return attachConstraintDescriptor;
222
+ }
223
+ });
224
+ Object.defineProperty(exports, "checkRefinementAssertion", {
225
+ enumerable: true,
226
+ get: function() {
227
+ return checkRefinementAssertion;
228
+ }
229
+ });
230
+ Object.defineProperty(exports, "createRefinement", {
231
+ enumerable: true,
232
+ get: function() {
233
+ return createRefinement;
234
+ }
235
+ });
236
+ Object.defineProperty(exports, "custom", {
237
+ enumerable: true,
238
+ get: function() {
239
+ return custom;
240
+ }
241
+ });
242
+ Object.defineProperty(exports, "describe", {
243
+ enumerable: true,
244
+ get: function() {
245
+ return describe;
246
+ }
247
+ });
248
+ Object.defineProperty(exports, "describeConstraints", {
249
+ enumerable: true,
250
+ get: function() {
251
+ return describeConstraints;
252
+ }
253
+ });
254
+ Object.defineProperty(exports, "isRefinementAssertion", {
255
+ enumerable: true,
256
+ get: function() {
257
+ return isRefinementAssertion;
258
+ }
259
+ });
260
+ Object.defineProperty(exports, "isValidator", {
261
+ enumerable: true,
262
+ get: function() {
263
+ return isValidator;
264
+ }
265
+ });
266
+ Object.defineProperty(exports, "matchesConstraints", {
267
+ enumerable: true,
268
+ get: function() {
269
+ return matchesConstraints;
270
+ }
271
+ });
272
+ Object.defineProperty(exports, "meta", {
273
+ enumerable: true,
274
+ get: function() {
275
+ return meta;
276
+ }
277
+ });
278
+ Object.defineProperty(exports, "refine", {
279
+ enumerable: true,
280
+ get: function() {
281
+ return refine;
282
+ }
283
+ });
284
+ Object.defineProperty(exports, "runRefinementAssertion", {
285
+ enumerable: true,
286
+ get: function() {
287
+ return runRefinementAssertion;
288
+ }
289
+ });
@@ -0,0 +1,206 @@
1
+ //#region src/constraints.ts
2
+ var isValidator = (constraint) => "run" in constraint;
3
+ function arrayify(value) {
4
+ return Array.isArray(value) ? [...value] : [value];
5
+ }
6
+ function matchesConstraints(value, constraints) {
7
+ let establishedDomain = false;
8
+ return arrayify(constraints).every((constraint) => {
9
+ if (isValidator(constraint)) {
10
+ establishedDomain = false;
11
+ return constraint.check(value);
12
+ }
13
+ if (!establishedDomain && isRefinementAssertion(constraint)) return false;
14
+ const matched = establishedDomain && isRefinementAssertion(constraint) ? checkRefinementAssertion(constraint, value) : constraint.check(value);
15
+ if (matched) establishedDomain = true;
16
+ return matched;
17
+ });
18
+ }
19
+ //#endregion
20
+ //#region src/metadata.ts
21
+ var constraintDescriptorSymbol = Symbol("modulify.validator.descriptor");
22
+ var constraintMetadataSymbol = Symbol("modulify.validator.metadata");
23
+ var cloneCallableConstraint = (constraint) => {
24
+ const source = constraint;
25
+ const cloned = ((value) => source(value));
26
+ const { length: _length, name: _name, prototype: _prototype, ...descriptors } = Object.getOwnPropertyDescriptors(source);
27
+ Object.defineProperties(cloned, descriptors);
28
+ try {
29
+ Object.defineProperty(cloned, "name", {
30
+ configurable: true,
31
+ value: source.name
32
+ });
33
+ } catch {}
34
+ Object.setPrototypeOf(cloned, Object.getPrototypeOf(source));
35
+ return cloned;
36
+ };
37
+ var cloneConstraint = (constraint) => {
38
+ if (typeof constraint === "function") return cloneCallableConstraint(constraint);
39
+ return Object.create(Object.getPrototypeOf(constraint), Object.getOwnPropertyDescriptors(constraint));
40
+ };
41
+ var freezeMetadata = (metadata) => Object.freeze({ ...metadata });
42
+ var getConstraintMetadata = (constraint) => {
43
+ return constraint[constraintMetadataSymbol];
44
+ };
45
+ var getDescriptorFactory = (constraint) => {
46
+ return constraint[constraintDescriptorSymbol];
47
+ };
48
+ var getPublicDescriptor = (constraint) => {
49
+ if (!isValidator(constraint)) return;
50
+ const { describe } = constraint;
51
+ return typeof describe === "function" ? describe.call(constraint) : void 0;
52
+ };
53
+ var inferAssertionDescriptor = (assertion) => ({
54
+ kind: "assertion",
55
+ name: assertion.name,
56
+ bail: assertion.bail,
57
+ code: assertion.name,
58
+ args: [],
59
+ constraints: assertion.constraints.map(([, , code, ...args]) => ({
60
+ code,
61
+ args
62
+ }))
63
+ });
64
+ var withMetadata = (descriptor, metadata) => {
65
+ if (!metadata) return descriptor;
66
+ return {
67
+ ...descriptor,
68
+ metadata
69
+ };
70
+ };
71
+ var attachConstraintDescriptor = (constraint, describe) => {
72
+ Object.defineProperty(constraint, constraintDescriptorSymbol, {
73
+ configurable: false,
74
+ enumerable: false,
75
+ value: describe,
76
+ writable: false
77
+ });
78
+ return constraint;
79
+ };
80
+ var meta = (constraint, metadata) => {
81
+ const cloned = cloneConstraint(constraint);
82
+ const nextMetadata = freezeMetadata({
83
+ ...getConstraintMetadata(constraint) ?? {},
84
+ ...metadata
85
+ });
86
+ Object.defineProperty(cloned, constraintMetadataSymbol, {
87
+ configurable: true,
88
+ enumerable: false,
89
+ value: nextMetadata,
90
+ writable: false
91
+ });
92
+ return cloned;
93
+ };
94
+ var custom = (validator) => validator;
95
+ var describeConstraints = (constraints) => {
96
+ const values = arrayify(constraints);
97
+ return values.length === 1 ? describe(values[0]) : {
98
+ kind: "allOf",
99
+ constraints: values.map((value) => describe(value))
100
+ };
101
+ };
102
+ var describe = (constraint) => {
103
+ const factory = getDescriptorFactory(constraint);
104
+ const metadata = getConstraintMetadata(constraint);
105
+ if (factory) return withMetadata(factory(), metadata);
106
+ const publicDescriptor = getPublicDescriptor(constraint);
107
+ if (publicDescriptor) return withMetadata(publicDescriptor, metadata);
108
+ if (isValidator(constraint)) return withMetadata({ kind: "validator" }, metadata);
109
+ return withMetadata(inferAssertionDescriptor(constraint), metadata);
110
+ };
111
+ //#endregion
112
+ //#region src/assert.ts
113
+ var assertionStageSymbol = Symbol("modulify.validator.assertion.stage");
114
+ var runRefinementSymbol = Symbol("modulify.validator.assertion.runRefinement");
115
+ var checkRefinementSymbol = Symbol("modulify.validator.assertion.checkRefinement");
116
+ var createAssertion = (stage, predicate, meta, constraints = []) => {
117
+ const assertionCode = meta.code ?? meta.name;
118
+ const assertionArgs = meta.args ?? [];
119
+ const violationSubject = {
120
+ kind: "assertion",
121
+ name: meta.name,
122
+ code: assertionCode,
123
+ args: assertionArgs
124
+ };
125
+ const runConstraints = (value) => {
126
+ for (const [extract, check, code, ...args] of constraints) if (!check(extract(value), ...args)) return {
127
+ value,
128
+ violates: {
129
+ kind: "assertion",
130
+ name: meta.name,
131
+ code,
132
+ args
133
+ }
134
+ };
135
+ return null;
136
+ };
137
+ const checkConstraints = (value) => !constraints.length || constraints.every(([extract, check, , ...args]) => check(extract(value), ...args));
138
+ const assertion = ((value) => {
139
+ if (!predicate(value)) return {
140
+ value,
141
+ violates: violationSubject
142
+ };
143
+ return runConstraints(value);
144
+ });
145
+ Object.defineProperties(assertion, {
146
+ name: {
147
+ configurable: true,
148
+ value: meta.name
149
+ },
150
+ bail: {
151
+ enumerable: true,
152
+ value: meta.bail
153
+ },
154
+ constraints: {
155
+ enumerable: true,
156
+ value: constraints
157
+ },
158
+ check: {
159
+ enumerable: true,
160
+ value: (value) => predicate(value) && checkConstraints(value)
161
+ },
162
+ [assertionStageSymbol]: {
163
+ enumerable: false,
164
+ value: stage
165
+ },
166
+ [runRefinementSymbol]: {
167
+ enumerable: false,
168
+ value: (value) => runConstraints(value)
169
+ },
170
+ [checkRefinementSymbol]: {
171
+ enumerable: false,
172
+ value: (value) => checkConstraints(value)
173
+ }
174
+ });
175
+ return /* @__PURE__ */ attachConstraintDescriptor(assertion, () => ({
176
+ kind: "assertion",
177
+ name: meta.name,
178
+ bail: meta.bail,
179
+ code: assertionCode,
180
+ args: assertionArgs,
181
+ constraints: constraints.map(([, , code, ...args]) => ({
182
+ code,
183
+ args
184
+ }))
185
+ }));
186
+ };
187
+ var assert = (predicate, meta, constraints = []) => {
188
+ return createAssertion("guard", predicate, meta, constraints);
189
+ };
190
+ var isRefinementAssertion = (constraint) => {
191
+ return typeof constraint === "function" && constraint[assertionStageSymbol] === "refinement";
192
+ };
193
+ var runRefinementAssertion = (constraint, value) => {
194
+ const runRefinement = constraint[runRefinementSymbol];
195
+ return runRefinement ? runRefinement(value) : constraint(value);
196
+ };
197
+ var checkRefinementAssertion = (constraint, value) => {
198
+ const checkRefinement = constraint[checkRefinementSymbol];
199
+ return checkRefinement ? checkRefinement(value) : constraint.check(value);
200
+ };
201
+ var createRefinement = (meta, constraints = []) => {
202
+ return createAssertion("refinement", ((value) => true), meta, constraints);
203
+ };
204
+ var refine = createRefinement;
205
+ //#endregion
206
+ export { refine as a, custom as c, meta as d, arrayify as f, isRefinementAssertion as i, describe as l, matchesConstraints as m, checkRefinementAssertion as n, runRefinementAssertion as o, isValidator as p, createRefinement as r, attachConstraintDescriptor as s, assert as t, describeConstraints as u };
package/dist/assert.cjs CHANGED
@@ -1,66 +1,8 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const metadata = require("./metadata.cjs.js");
4
- const assert = (predicate, meta, constraints = []) => {
5
- const assertionCode = meta.code ?? meta.name;
6
- const assertionArgs = meta.args ?? [];
7
- const violationSubject = {
8
- kind: "assertion",
9
- name: meta.name,
10
- code: assertionCode,
11
- args: assertionArgs
12
- };
13
- const assertion = ((value) => {
14
- if (!predicate(value)) {
15
- return {
16
- value,
17
- violates: violationSubject
18
- };
19
- }
20
- for (const [extract, check, code, ...args] of constraints) {
21
- if (!check(extract(value), ...args)) {
22
- const constraintSubject = {
23
- kind: "assertion",
24
- name: meta.name,
25
- code,
26
- args
27
- };
28
- return {
29
- value,
30
- violates: constraintSubject
31
- };
32
- }
33
- }
34
- return null;
35
- });
36
- Object.defineProperties(assertion, {
37
- name: {
38
- configurable: true,
39
- value: meta.name
40
- },
41
- bail: {
42
- enumerable: true,
43
- value: meta.bail
44
- },
45
- constraints: {
46
- enumerable: true,
47
- value: constraints
48
- },
49
- check: {
50
- enumerable: true,
51
- value: (value) => predicate(value) && (!constraints.length || constraints.every(([extract, check, , ...args]) => check(extract(value), ...args)))
52
- }
53
- });
54
- return metadata.attachConstraintDescriptor(assertion, () => ({
55
- kind: "assertion",
56
- name: meta.name,
57
- bail: meta.bail,
58
- code: assertionCode,
59
- args: assertionArgs,
60
- constraints: constraints.map(([, , code, ...args]) => ({
61
- code,
62
- args
63
- }))
64
- }));
65
- };
66
- exports.assert = assert;
2
+ const require_assert = require("./assert-BDOtHdLx.cjs");
3
+ exports.assert = require_assert.assert;
4
+ exports.checkRefinementAssertion = require_assert.checkRefinementAssertion;
5
+ exports.createRefinement = require_assert.createRefinement;
6
+ exports.isRefinementAssertion = require_assert.isRefinementAssertion;
7
+ exports.refine = require_assert.refine;
8
+ exports.runRefinementAssertion = require_assert.runRefinementAssertion;
@@ -0,0 +1,37 @@
1
+ import { Assertion, Constraint, AssertionConstraint, Guard, Predicate, Refinement } from './types/index.cjs';
2
+ type AssertMeta = {
3
+ name: string;
4
+ bail: boolean;
5
+ code?: string;
6
+ args?: readonly unknown[];
7
+ };
8
+ type ResolveAssertionCode<Name extends string, Code extends string | undefined> = Code extends string ? Code : Name;
9
+ type ResolveAssertionArgs<Args extends readonly unknown[] | undefined> = Args extends readonly unknown[] ? Args : [];
10
+ type ConstraintInputFunction<C extends AssertionConstraint> = C extends unknown ? (value: Parameters<C[0]>[0]) => void : never;
11
+ type ConstraintInput<C extends readonly AssertionConstraint[]> = C extends readonly [] ? unknown : ConstraintInputFunction<C[number]> extends (value: infer Input) => void ? Input : never;
12
+ type ConstraintArgs<C extends AssertionConstraint> = C extends readonly [unknown, unknown, string, ...infer Args] ? Args : never;
13
+ type CompatibleAssertionConstraints<Input, C extends readonly AssertionConstraint[]> = {
14
+ [K in keyof C]: AssertionConstraint<Input, ReturnType<C[K][0]>, ConstraintArgs<C[K]>, C[K][2]>;
15
+ };
16
+ export declare const assert: <T, const Name extends string, const Bail extends boolean, const Code extends string | undefined = undefined, const Args extends readonly unknown[] | undefined = undefined, const C extends readonly AssertionConstraint<T, any, any[], string>[] = []>(predicate: Predicate<T>, meta: AssertMeta & {
17
+ name: Name;
18
+ bail: Bail;
19
+ code?: Code;
20
+ args?: Args;
21
+ }, constraints?: C & CompatibleAssertionConstraints<T, C>) => Guard<T, C, ResolveAssertionCode<Name, Code>, ResolveAssertionArgs<Args>, Name>;
22
+ export declare const isRefinementAssertion: (constraint: Constraint) => constraint is Assertion;
23
+ export declare const runRefinementAssertion: (constraint: Assertion, value: unknown) => ReturnType<Assertion>;
24
+ export declare const checkRefinementAssertion: (constraint: Assertion, value: unknown) => boolean;
25
+ export declare const createRefinement: <const Name extends string, const Bail extends boolean, const Code extends string | undefined = undefined, const Args extends readonly unknown[] | undefined = undefined, const C extends readonly AssertionConstraint[] = []>(meta: AssertMeta & {
26
+ name: Name;
27
+ bail: Bail;
28
+ code?: Code;
29
+ args?: Args;
30
+ }, constraints?: C) => Refinement<ConstraintInput<C>, C, ResolveAssertionCode<Name, Code>, ResolveAssertionArgs<Args>, Name>;
31
+ export declare const refine: <const Name extends string, const Bail extends boolean, const Code extends string | undefined = undefined, const Args extends readonly unknown[] | undefined = undefined, const C extends readonly AssertionConstraint[] = []>(meta: AssertMeta & {
32
+ name: Name;
33
+ bail: Bail;
34
+ code?: Code;
35
+ args?: Args;
36
+ }, constraints?: C & CompatibleAssertionConstraints<ConstraintInput<C>, C>) => Refinement<ConstraintInput<C>, C, ResolveAssertionCode<Name, Code>, ResolveAssertionArgs<Args>, Name>;
37
+ export {};