justus 0.0.1 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +153 -34
- package/dist/dts-generator.js +166 -0
- package/dist/dts-generator.js.map +6 -0
- package/dist/dts-generator.mjs +158 -0
- package/dist/dts-generator.mjs.map +6 -0
- package/dist/{index.cjs → index.js} +246 -124
- package/dist/index.js.map +6 -0
- package/dist/index.mjs +218 -121
- package/dist/index.mjs.map +2 -2
- package/dts-generator.d.ts +13 -0
- package/{dist/index.d.ts → index.d.ts} +171 -40
- package/package.json +27 -16
- package/src/dts-generator.ts +276 -0
- package/src/errors.ts +3 -3
- package/src/index.ts +32 -8
- package/src/schema.ts +6 -6
- package/src/types.ts +15 -6
- package/src/validators/array.ts +14 -12
- package/src/validators/date.ts +3 -3
- package/src/validators/number.ts +54 -22
- package/src/validators/object.ts +67 -48
- package/src/validators/string.ts +25 -11
- package/src/validators/tuple.ts +17 -13
- package/src/validators/union.ts +3 -3
- package/src/validators/url.ts +140 -0
- package/dist/index.cjs.map +0 -6
package/README.md
CHANGED
|
@@ -27,6 +27,7 @@ typing can be inferred.
|
|
|
27
27
|
* [Objects](#object-validator) (yes, this is the important one!!!)
|
|
28
28
|
* [Any of, all of](#union-validators)
|
|
29
29
|
* [A (slightly more) complex example](#a-complex-example)
|
|
30
|
+
* [Generating DTS files](#generating-dts-files)
|
|
30
31
|
* [Copyright Notice](NOTICE.md)
|
|
31
32
|
* [License](LICENSE.md)
|
|
32
33
|
|
|
@@ -38,7 +39,7 @@ You can use JUSTUS in your projects quite simply: import, write a schema and
|
|
|
38
39
|
validate. For example:
|
|
39
40
|
|
|
40
41
|
```typescript
|
|
41
|
-
import {
|
|
42
|
+
import { number, object, string, validate } from 'justus'
|
|
42
43
|
|
|
43
44
|
// Create a validator, validating _objects_ with a specific schema
|
|
44
45
|
const validator = object({
|
|
@@ -68,6 +69,8 @@ The `validate` function (or anywhere a _validation_ is needed) can accept a
|
|
|
68
69
|
_shorthand_ inline syntax. From our example above:
|
|
69
70
|
|
|
70
71
|
```typescript
|
|
72
|
+
import { number, string, validate } from 'justus'
|
|
73
|
+
|
|
71
74
|
const validated = validate({
|
|
72
75
|
foo: string({ minLength: 1 }),
|
|
73
76
|
bar: number,
|
|
@@ -103,7 +106,7 @@ const s2 = string({ minLength: 1 }) // validate non empty strings
|
|
|
103
106
|
Type _branding_ can be used for string primitives. For example:
|
|
104
107
|
|
|
105
108
|
```typescript
|
|
106
|
-
import { string } from 'justus'
|
|
109
|
+
import { string, validate } from 'justus'
|
|
107
110
|
|
|
108
111
|
type UUID = string & { __brand_uuid: never }
|
|
109
112
|
|
|
@@ -118,12 +121,33 @@ const value = validate(uuidValidator, 'C274773D-1444-41E1-9D3A-9F9D584FE8B5')
|
|
|
118
121
|
value = 'foo' // <- will fail, as "foo" is a `string`, while "value" is a `UUID`
|
|
119
122
|
```
|
|
120
123
|
|
|
124
|
+
#### Implicit branding
|
|
125
|
+
|
|
126
|
+
Sometimes it might be useful to declare the _branding_ of a string without
|
|
127
|
+
recurring to an external type. We can easily do so by adding the `brand`
|
|
128
|
+
property our string constraints. Following the example above:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import { string, validate } from 'justus'
|
|
132
|
+
|
|
133
|
+
const uuidValidator = string({
|
|
134
|
+
pattern: /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/,
|
|
135
|
+
minLength: 36,
|
|
136
|
+
maxLength: 36,
|
|
137
|
+
brand: 'uuid',
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
const value = validate(uuidValidator, 'C274773D-1444-41E1-9D3A-9F9D584FE8B5')
|
|
141
|
+
|
|
142
|
+
value = 'foo' // <- fail! the type of "value" is "string & __brand_uuid: never"
|
|
143
|
+
```
|
|
144
|
+
|
|
121
145
|
#### Shorthand syntax
|
|
122
146
|
|
|
123
147
|
The shorthand syntax for string validators is simply `string`. For example:
|
|
124
148
|
|
|
125
149
|
```typescript
|
|
126
|
-
import { string } from 'justus'
|
|
150
|
+
import { object, string } from 'justus'
|
|
127
151
|
|
|
128
152
|
const validator = object({
|
|
129
153
|
foo: string // yep, no parenthesis, just "string"
|
|
@@ -157,9 +181,9 @@ const n2 = number({ minimum: 123 }) // validate numbers 123 and greater
|
|
|
157
181
|
Type _branding_ can be used for number primitives. For example:
|
|
158
182
|
|
|
159
183
|
```typescript
|
|
160
|
-
import { number } from 'justus'
|
|
184
|
+
import { number, validate } from 'justus'
|
|
161
185
|
|
|
162
|
-
type Price =
|
|
186
|
+
type Price = number & { __brand_price: never }
|
|
163
187
|
|
|
164
188
|
const priceValidator = number<Price>({
|
|
165
189
|
multipleOf: 0.01, // cents, anyone? :-)
|
|
@@ -171,12 +195,32 @@ const value = validate(priceValidator, 123.45)
|
|
|
171
195
|
value = 432 // <- will fail, as 432 is a `number`, while "value" is a `Price`
|
|
172
196
|
```
|
|
173
197
|
|
|
198
|
+
#### Implicit branding
|
|
199
|
+
|
|
200
|
+
Sometimes it might be useful to declare the _branding_ of a number without
|
|
201
|
+
recurring to an external type. We can easily do so by adding the `brand`
|
|
202
|
+
property our number constraints. Following the example above:
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
import { number, validate } from 'justus'
|
|
206
|
+
|
|
207
|
+
const priceValidator = number({
|
|
208
|
+
multipleOf: 0.01, // cents, anyone? :-)
|
|
209
|
+
minimum: 0, // no negative prices, those are _discounts_
|
|
210
|
+
brand: 'price',
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
const value = validate(priceValidator, 123.45)
|
|
214
|
+
|
|
215
|
+
value = 432 // <- fail! the type of "value" is "number & __brand_price: never"
|
|
216
|
+
```
|
|
217
|
+
|
|
174
218
|
#### Shorthand syntax
|
|
175
219
|
|
|
176
220
|
The shorthand syntax for number validators is simply `number`. For example:
|
|
177
221
|
|
|
178
222
|
```typescript
|
|
179
|
-
import { number } from 'justus'
|
|
223
|
+
import { number, object } from 'justus'
|
|
180
224
|
|
|
181
225
|
const validator = object({
|
|
182
226
|
foo: number // yep, no parenthesis, just "number"
|
|
@@ -265,7 +309,7 @@ Array validators are created using the `array` or `arrayOf` functions:
|
|
|
265
309
|
import { array, arrayOf, number, string } from 'justus'
|
|
266
310
|
|
|
267
311
|
const a1 = array() // validates any array
|
|
268
|
-
const a2 =
|
|
312
|
+
const a2 = array({ maxItems: 10, items: string }) // array of strings
|
|
269
313
|
const a3 = arrayOf(number) // array of numbers
|
|
270
314
|
```
|
|
271
315
|
|
|
@@ -281,7 +325,7 @@ const a3 = arrayOf(number) // array of numbers
|
|
|
281
325
|
The shorthand syntax for string validators is simply `array`. For example:
|
|
282
326
|
|
|
283
327
|
```typescript
|
|
284
|
-
import { array } from 'justus'
|
|
328
|
+
import { array, object } from 'justus'
|
|
285
329
|
|
|
286
330
|
const validator = object({
|
|
287
331
|
foo: array // validate any array, of any length, containing anything
|
|
@@ -293,7 +337,7 @@ The `arrayOf` function can also be considered a _shorthand_ of the full
|
|
|
293
337
|
equivalent:
|
|
294
338
|
|
|
295
339
|
```typescript
|
|
296
|
-
import { array, arrayOf } from 'justus'
|
|
340
|
+
import { array, arrayOf, string } from 'justus'
|
|
297
341
|
|
|
298
342
|
const a1 = array({ items: string })
|
|
299
343
|
const a2 = arrayOf(string) // same as above, just more readable
|
|
@@ -328,7 +372,7 @@ const d2 = date({ format: 'iso' }) // validate ISO dates
|
|
|
328
372
|
The shorthand syntax for number validators is simply `date`. For example:
|
|
329
373
|
|
|
330
374
|
```typescript
|
|
331
|
-
import { date } from 'justus'
|
|
375
|
+
import { date, object } from 'justus'
|
|
332
376
|
|
|
333
377
|
const validator = object({
|
|
334
378
|
foo: date // anything that can be converted to `Date` will be!
|
|
@@ -357,10 +401,10 @@ const t2 = tuple([ string, ...number, boolean ]) // yay! rest parameters!
|
|
|
357
401
|
As shown above, any `Validator` (or one of its shorthands) can be used as a
|
|
358
402
|
_rest parameter_ implying zero or more elements of the specified kind.
|
|
359
403
|
|
|
360
|
-
A more
|
|
404
|
+
A more complex example:
|
|
361
405
|
|
|
362
406
|
```typescript
|
|
363
|
-
import {
|
|
407
|
+
import { number, object, string, tuple, validate } from 'justus'
|
|
364
408
|
|
|
365
409
|
const myObject = object({
|
|
366
410
|
version: number,
|
|
@@ -371,7 +415,7 @@ const myObject = object({
|
|
|
371
415
|
const sillyTuple = tuple([ 'start', ...myObject, 'end' ] as const)
|
|
372
416
|
|
|
373
417
|
// Validate using our tuple:
|
|
374
|
-
validate(
|
|
418
|
+
validate(sillyTuple, [
|
|
375
419
|
'start', // yep, a constant
|
|
376
420
|
{ version: 1, title: 'Hello world' },
|
|
377
421
|
{ version: 2, title: 'Foo, bar and baz' },
|
|
@@ -414,7 +458,7 @@ Sometimes it's necessary to allow additional properties in an object.
|
|
|
414
458
|
Destructuring `...allowAdditionalProperties` in an objects does the trick!
|
|
415
459
|
|
|
416
460
|
```typescript
|
|
417
|
-
import {
|
|
461
|
+
import { allowAdditionalProperties, boolean, number, object, string, validate } from 'justus'
|
|
418
462
|
|
|
419
463
|
const o1 = object({
|
|
420
464
|
foo: string, // any string
|
|
@@ -422,7 +466,7 @@ const o1 = object({
|
|
|
422
466
|
...allowAdditionalProperties, // any other key will be "any"
|
|
423
467
|
})
|
|
424
468
|
|
|
425
|
-
const result1 = validate(o1,
|
|
469
|
+
const result1 = validate(o1, something)
|
|
426
470
|
|
|
427
471
|
result1.foo // <-- this will be a "string"
|
|
428
472
|
result1.bar // <-- this will be a "number"
|
|
@@ -436,12 +480,11 @@ const o2 = object({
|
|
|
436
480
|
...allowAdditionalProperties(boolean), // any other key will be "boolean"
|
|
437
481
|
})
|
|
438
482
|
|
|
439
|
-
const result2 = validate(o2,
|
|
483
|
+
const result2 = validate(o2, something)
|
|
440
484
|
|
|
441
485
|
result2.foo // <-- this will be a "string"
|
|
442
486
|
result2.bar // <-- this will be a "number"
|
|
443
487
|
result2.baz // <-- additional property, this will be "boolean"
|
|
444
|
-
|
|
445
488
|
```
|
|
446
489
|
|
|
447
490
|
Here `allowAdditionalProperties` is also a function, which can take some
|
|
@@ -485,7 +528,7 @@ To do so, simply override in the extended object as follows:
|
|
|
485
528
|
Simply destructure one into another. For example:
|
|
486
529
|
|
|
487
530
|
```typescript
|
|
488
|
-
import {
|
|
531
|
+
import { allowAdditionalProperties, boolean, number, object, string } from 'justus'
|
|
489
532
|
|
|
490
533
|
const o1 = object({
|
|
491
534
|
foo: string, // any string
|
|
@@ -496,7 +539,33 @@ const o1 = object({
|
|
|
496
539
|
const o2 = object({
|
|
497
540
|
...o1, // anything part of "o1" will be here as well!
|
|
498
541
|
baz: boolean, // add "baz" to "o1", forcing it to be a "boolean"
|
|
499
|
-
...
|
|
542
|
+
...allowAdditionalProperties(false), // no more additional properties here!
|
|
543
|
+
} as const)
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
#### Ensure properties never exist
|
|
547
|
+
|
|
548
|
+
When allowing extra properties, or extending objects, we might want to validate
|
|
549
|
+
the _non-existance_ of a specific property. We can do this setting a property
|
|
550
|
+
to `never`:
|
|
551
|
+
|
|
552
|
+
```typescript
|
|
553
|
+
import { allowAdditionalProperties, never, number, object, string } from 'justus'
|
|
554
|
+
|
|
555
|
+
const o1 = object({
|
|
556
|
+
foo: string, // any string
|
|
557
|
+
bar: number, // any number
|
|
558
|
+
})
|
|
559
|
+
|
|
560
|
+
const o2 = object({
|
|
561
|
+
...o1, // anything part of "o1" will be here as well!
|
|
562
|
+
bar: never, // remove "bar" from the properties inherited by "o1"
|
|
563
|
+
} as const)
|
|
564
|
+
|
|
565
|
+
const o3 = object({
|
|
566
|
+
...o1, // anything part of "o1" will be here as well!
|
|
567
|
+
...allowAdditionalProperties, // allow additional properties as "any"
|
|
568
|
+
baz: never, // even with additional properties, "baz" must not exist
|
|
500
569
|
} as const)
|
|
501
570
|
```
|
|
502
571
|
|
|
@@ -525,28 +594,28 @@ functions.
|
|
|
525
594
|
To make sure all validations pass use `allOf`:
|
|
526
595
|
|
|
527
596
|
```typescript
|
|
528
|
-
import { allOf, object, string,
|
|
597
|
+
import { allOf, number, object, string, validate } from 'justus'
|
|
529
598
|
|
|
530
599
|
const o1 = object({ foo: string })
|
|
531
600
|
const o2 = object({ bar: number })
|
|
532
601
|
|
|
533
|
-
const result = validate(allOf(o1, o2),
|
|
602
|
+
const result = validate(allOf(o1, o2), something)
|
|
534
603
|
// result here will have the type of what's inferred by o1 _and_ o2
|
|
535
604
|
|
|
536
605
|
result.foo // <-- this is a "string"
|
|
537
606
|
result.bar // <-- this is a "number"
|
|
538
607
|
|
|
539
608
|
// be careful about never!
|
|
540
|
-
const result2 = validate(allOf(number, string),
|
|
609
|
+
const result2 = validate(allOf(number, string), something)
|
|
541
610
|
// obviously "result2" will be of type "never" as "number" and "string" do not match!
|
|
542
611
|
```
|
|
543
612
|
|
|
544
613
|
More useful, to make sure all validations pass use `oneOf`:
|
|
545
614
|
|
|
546
615
|
```typescript
|
|
547
|
-
import { oneOf, string,
|
|
616
|
+
import { number, oneOf, string, validate } from 'justus'
|
|
548
617
|
|
|
549
|
-
const result = validate(oneOf(number, string),
|
|
618
|
+
const result = validate(oneOf(number, string), something)
|
|
550
619
|
|
|
551
620
|
result // <-- its type will be "number | string"
|
|
552
621
|
```
|
|
@@ -562,16 +631,7 @@ Let's assume we have some _time series_ data, but we can expect this in a
|
|
|
562
631
|
couple of different flavors, either V1 or V2 with some subtle differences:
|
|
563
632
|
|
|
564
633
|
```typescript
|
|
565
|
-
import {
|
|
566
|
-
arrayOf,
|
|
567
|
-
date,
|
|
568
|
-
number,
|
|
569
|
-
object,
|
|
570
|
-
oneOf,
|
|
571
|
-
string,
|
|
572
|
-
tuple,
|
|
573
|
-
validate,
|
|
574
|
-
} from '../src'
|
|
634
|
+
import { arrayOf, date, number, object, oneOf, string, tuple, validate } from 'justus'
|
|
575
635
|
|
|
576
636
|
// Our V1 time-series tuple is simply a timestamp followed by a numeric value
|
|
577
637
|
const entryv1 = tuple([ date, number ] as const)
|
|
@@ -618,3 +678,62 @@ if (result.version === 1) {
|
|
|
618
678
|
result.average // this will be a "number""
|
|
619
679
|
}
|
|
620
680
|
```
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
Generating DTS files
|
|
684
|
+
--------------------
|
|
685
|
+
|
|
686
|
+
Sometimes it might be necessary to generate `.d.ts` files for your schemas,
|
|
687
|
+
rather than relying on the type inference provided by JUSTUS.
|
|
688
|
+
|
|
689
|
+
For example, if you were to use JUSTUS on a server application to validate
|
|
690
|
+
HTTP requests and responses, and wanted to have strong typing when interacting
|
|
691
|
+
with it from a client, you might not necessarily want to have JUSTUS (and your
|
|
692
|
+
schemas) as a client dependency.
|
|
693
|
+
|
|
694
|
+
So, assuming your schemas might look something like this:
|
|
695
|
+
|
|
696
|
+
```typescript
|
|
697
|
+
import { number, object, string } from 'justus'
|
|
698
|
+
|
|
699
|
+
// this will be exported as a type
|
|
700
|
+
const uuid = string({ brand: 'uuid ' })
|
|
701
|
+
|
|
702
|
+
// this will be embedded in product below
|
|
703
|
+
const price = number({ brand: 'price' })
|
|
704
|
+
|
|
705
|
+
// object mapping two validators above
|
|
706
|
+
const product = object({
|
|
707
|
+
uuid,
|
|
708
|
+
price,
|
|
709
|
+
name: string({ minLength: 1 }),
|
|
710
|
+
})
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
We can generate the DTS for `UUID` and `Product` (we specifically not export
|
|
714
|
+
`Product` in this example) using our `dts-generator` as follows:
|
|
715
|
+
|
|
716
|
+
```typescript
|
|
717
|
+
import { generateTypes } from 'justus/dts-generator'
|
|
718
|
+
|
|
719
|
+
// Note how we rename the exports to "UUID" and "Product" (casing, ...)
|
|
720
|
+
const dts = generateTypes({
|
|
721
|
+
UUID: uuid,
|
|
722
|
+
Product: product,
|
|
723
|
+
})
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
The resulting `dts` will be a `string` containing the DTS as follows:
|
|
727
|
+
|
|
728
|
+
```typescript
|
|
729
|
+
export type UUID = string & {
|
|
730
|
+
__brand_uuid : never;
|
|
731
|
+
};
|
|
732
|
+
export type Product = {
|
|
733
|
+
uuid: UUID;
|
|
734
|
+
price: number & {
|
|
735
|
+
__brand_price: never;
|
|
736
|
+
};
|
|
737
|
+
name: string;
|
|
738
|
+
};
|
|
739
|
+
```
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
|
|
20
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
|
|
22
|
+
// src/dts-generator.ts
|
|
23
|
+
var dts_generator_exports = {};
|
|
24
|
+
__export(dts_generator_exports, {
|
|
25
|
+
generateTypes: () => generateTypes,
|
|
26
|
+
registerTypeGenerator: () => registerTypeGenerator
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(dts_generator_exports);
|
|
29
|
+
var import_typescript = __toESM(require("typescript"));
|
|
30
|
+
var import_index = require("./index.js");
|
|
31
|
+
var generators = /* @__PURE__ */ new Map();
|
|
32
|
+
function registerTypeGenerator(validator, generator) {
|
|
33
|
+
(0, import_index.assertSchema)(validator.prototype instanceof import_index.Validator, "Not a `Validator` class");
|
|
34
|
+
generators.set(validator, generator);
|
|
35
|
+
}
|
|
36
|
+
function generateTypes(validations) {
|
|
37
|
+
const validators = /* @__PURE__ */ new Map();
|
|
38
|
+
const references = /* @__PURE__ */ new Map();
|
|
39
|
+
Object.entries(validations).forEach(([name, validation]) => {
|
|
40
|
+
const validator = (0, import_index.getValidator)(validation);
|
|
41
|
+
if (!references.has(validator))
|
|
42
|
+
references.set(validator, name);
|
|
43
|
+
validators.set(name, validator);
|
|
44
|
+
});
|
|
45
|
+
const types = [];
|
|
46
|
+
for (const [name, validator] of validators.entries()) {
|
|
47
|
+
const referenceable = new Map(references);
|
|
48
|
+
if (referenceable.get(validator) === name) {
|
|
49
|
+
referenceable.delete(validator);
|
|
50
|
+
}
|
|
51
|
+
const type = generateTypeNode(validator, referenceable);
|
|
52
|
+
const modifiers = [import_typescript.default.factory.createModifier(import_typescript.default.SyntaxKind.ExportKeyword)];
|
|
53
|
+
const decl = import_typescript.default.factory.createTypeAliasDeclaration(void 0, modifiers, name, [], type);
|
|
54
|
+
types.push(decl);
|
|
55
|
+
}
|
|
56
|
+
return import_typescript.default.createPrinter().printList(import_typescript.default.ListFormat.SourceFileStatements, import_typescript.default.factory.createNodeArray(types), import_typescript.default.createSourceFile("types.d.ts", "", import_typescript.default.ScriptTarget.Latest));
|
|
57
|
+
}
|
|
58
|
+
function generateTypeNode(validator, references) {
|
|
59
|
+
const reference = references.get(validator);
|
|
60
|
+
if (reference)
|
|
61
|
+
return import_typescript.default.factory.createTypeReferenceNode(reference);
|
|
62
|
+
const generator = generators.get(validator.constructor);
|
|
63
|
+
(0, import_index.assertSchema)(!!generator, `Type generator for "${validator.constructor.name}" not found`);
|
|
64
|
+
return generator(validator, references);
|
|
65
|
+
}
|
|
66
|
+
var anyType = import_typescript.default.factory.createKeywordTypeNode(import_typescript.default.SyntaxKind.AnyKeyword);
|
|
67
|
+
var anyArrayType = import_typescript.default.factory.createArrayTypeNode(anyType);
|
|
68
|
+
var booleanType = import_typescript.default.factory.createKeywordTypeNode(import_typescript.default.SyntaxKind.BooleanKeyword);
|
|
69
|
+
var numberType = import_typescript.default.factory.createKeywordTypeNode(import_typescript.default.SyntaxKind.NumberKeyword);
|
|
70
|
+
var neverType = import_typescript.default.factory.createKeywordTypeNode(import_typescript.default.SyntaxKind.NeverKeyword);
|
|
71
|
+
var stringType = import_typescript.default.factory.createKeywordTypeNode(import_typescript.default.SyntaxKind.StringKeyword);
|
|
72
|
+
var recordType = import_typescript.default.factory.createMappedTypeNode(void 0, import_typescript.default.factory.createTypeParameterDeclaration("key", stringType), void 0, void 0, anyType, void 0);
|
|
73
|
+
var readonlyKeyword = [import_typescript.default.factory.createModifier(import_typescript.default.SyntaxKind.ReadonlyKeyword)];
|
|
74
|
+
var optionalKeyword = import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.QuestionToken);
|
|
75
|
+
registerTypeGenerator(import_index.AnyValidator, () => anyType);
|
|
76
|
+
registerTypeGenerator(import_index.AnyArrayValidator, () => anyArrayType);
|
|
77
|
+
registerTypeGenerator(import_index.AnyNumberValidator, () => numberType);
|
|
78
|
+
registerTypeGenerator(import_index.AnyObjectValidator, () => recordType);
|
|
79
|
+
registerTypeGenerator(import_index.AnyStringValidator, () => stringType);
|
|
80
|
+
registerTypeGenerator(import_index.BooleanValidator, () => booleanType);
|
|
81
|
+
registerTypeGenerator(import_index.DateValidator, () => import_typescript.default.factory.createTypeReferenceNode("Date"));
|
|
82
|
+
registerTypeGenerator(import_index.URLValidator, () => import_typescript.default.factory.createTypeReferenceNode("URL"));
|
|
83
|
+
registerTypeGenerator(import_index.ArrayValidator, (validator, references) => {
|
|
84
|
+
const itemType = generateTypeNode(validator.items, references);
|
|
85
|
+
return import_typescript.default.factory.createArrayTypeNode(itemType);
|
|
86
|
+
});
|
|
87
|
+
registerTypeGenerator(import_index.ConstantValidator, (validator) => {
|
|
88
|
+
const literal = typeof validator.constant === "number" ? import_typescript.default.factory.createNumericLiteral(validator.constant) : typeof validator.constant === "string" ? import_typescript.default.factory.createStringLiteral(validator.constant) : validator.constant === false ? import_typescript.default.factory.createFalse() : validator.constant === true ? import_typescript.default.factory.createTrue() : validator.constant === null ? import_typescript.default.factory.createNull() : void 0;
|
|
89
|
+
(0, import_index.assertSchema)(!!literal, `Invalid constant "${validator.constant}"`);
|
|
90
|
+
return import_typescript.default.factory.createLiteralTypeNode(literal);
|
|
91
|
+
});
|
|
92
|
+
registerTypeGenerator(import_index.NumberValidator, (validator) => {
|
|
93
|
+
if (!validator.brand)
|
|
94
|
+
return numberType;
|
|
95
|
+
const signature = import_typescript.default.factory.createPropertySignature(void 0, `__brand_${validator.brand}`, void 0, neverType);
|
|
96
|
+
const literal = import_typescript.default.factory.createTypeLiteralNode([signature]);
|
|
97
|
+
return import_typescript.default.factory.createIntersectionTypeNode([numberType, literal]);
|
|
98
|
+
});
|
|
99
|
+
registerTypeGenerator(import_index.StringValidator, (validator) => {
|
|
100
|
+
if (!validator.brand)
|
|
101
|
+
return stringType;
|
|
102
|
+
const signature = import_typescript.default.factory.createPropertySignature(void 0, `__brand_${validator.brand}`, void 0, neverType);
|
|
103
|
+
const literal = import_typescript.default.factory.createTypeLiteralNode([signature]);
|
|
104
|
+
return import_typescript.default.factory.createIntersectionTypeNode([stringType, literal]);
|
|
105
|
+
});
|
|
106
|
+
registerTypeGenerator(import_index.TupleValidator, (validator, references) => {
|
|
107
|
+
const members = validator.members;
|
|
108
|
+
const { count, first, next } = members.reduce(({ count: count2, first: first2, next: next2 }, { single }, i) => {
|
|
109
|
+
if (!single) {
|
|
110
|
+
if (i < first2)
|
|
111
|
+
first2 = i;
|
|
112
|
+
next2 = i + 1;
|
|
113
|
+
count2 += 1;
|
|
114
|
+
}
|
|
115
|
+
return { count: count2, first: first2, next: next2 };
|
|
116
|
+
}, { count: 0, first: members.length, next: -1 });
|
|
117
|
+
if (count < 2) {
|
|
118
|
+
const types2 = members.map(({ single, validator: validator2 }) => {
|
|
119
|
+
const memberType = generateTypeNode(validator2, references);
|
|
120
|
+
if (single)
|
|
121
|
+
return generateTypeNode(validator2, references);
|
|
122
|
+
const arrayType = import_typescript.default.factory.createArrayTypeNode(memberType);
|
|
123
|
+
return import_typescript.default.factory.createRestTypeNode(arrayType);
|
|
124
|
+
});
|
|
125
|
+
return import_typescript.default.factory.createTupleTypeNode(types2);
|
|
126
|
+
}
|
|
127
|
+
const before = members.slice(0, first).map(({ validator: validator2 }) => generateTypeNode(validator2, references));
|
|
128
|
+
const types = members.slice(first, next).map(({ validator: validator2 }) => generateTypeNode(validator2, references));
|
|
129
|
+
const after = members.slice(next).map(({ validator: validator2 }) => generateTypeNode(validator2, references));
|
|
130
|
+
const union = import_typescript.default.factory.createUnionTypeNode(types);
|
|
131
|
+
const array = import_typescript.default.factory.createArrayTypeNode(union);
|
|
132
|
+
const rest = import_typescript.default.factory.createRestTypeNode(array);
|
|
133
|
+
return import_typescript.default.factory.createTupleTypeNode([...before, rest, ...after]);
|
|
134
|
+
});
|
|
135
|
+
registerTypeGenerator(import_index.AllOfValidator, (validator, references) => {
|
|
136
|
+
const members = validator.validators.map((validator2) => generateTypeNode(validator2, references));
|
|
137
|
+
return import_typescript.default.factory.createIntersectionTypeNode(members);
|
|
138
|
+
});
|
|
139
|
+
registerTypeGenerator(import_index.OneOfValidator, (validator, references) => {
|
|
140
|
+
const members = validator.validators.map((validator2) => generateTypeNode(validator2, references));
|
|
141
|
+
return import_typescript.default.factory.createUnionTypeNode(members);
|
|
142
|
+
});
|
|
143
|
+
registerTypeGenerator(import_index.ObjectValidator, (validator, references) => {
|
|
144
|
+
const properties = [];
|
|
145
|
+
for (const [key, property] of validator.properties.entries()) {
|
|
146
|
+
const { validator: validator2, readonly, optional } = property || { optional: true };
|
|
147
|
+
const type = validator2 ? generateTypeNode(validator2, references) : neverType;
|
|
148
|
+
const signature = import_typescript.default.factory.createPropertySignature(readonly ? readonlyKeyword : void 0, key, optional ? optionalKeyword : void 0, type);
|
|
149
|
+
properties.push(signature);
|
|
150
|
+
}
|
|
151
|
+
if (validator.additionalProperties) {
|
|
152
|
+
const extra = import_typescript.default.factory.createMappedTypeNode(void 0, import_typescript.default.factory.createTypeParameterDeclaration("key", stringType), void 0, void 0, generateTypeNode(validator.additionalProperties, references), void 0);
|
|
153
|
+
if (properties.length == 0)
|
|
154
|
+
return extra;
|
|
155
|
+
const type = import_typescript.default.factory.createTypeLiteralNode(properties);
|
|
156
|
+
return import_typescript.default.factory.createIntersectionTypeNode([type, extra]);
|
|
157
|
+
} else {
|
|
158
|
+
return import_typescript.default.factory.createTypeLiteralNode(properties);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
162
|
+
0 && (module.exports = {
|
|
163
|
+
generateTypes,
|
|
164
|
+
registerTypeGenerator
|
|
165
|
+
});
|
|
166
|
+
//# sourceMappingURL=dts-generator.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/dts-generator.ts"],
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|