ts-fortress 4.1.1 → 4.2.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.
- package/README.md +192 -30
- package/dist/array/array-of-length.d.mts +3 -3
- package/dist/array/array-of-length.d.mts.map +1 -1
- package/dist/array/array-of-length.mjs +5 -6
- package/dist/array/array-of-length.mjs.map +1 -1
- package/dist/array/array.d.mts +2 -2
- package/dist/array/array.d.mts.map +1 -1
- package/dist/array/array.mjs +3 -4
- package/dist/array/array.mjs.map +1 -1
- package/dist/array/non-empty-array.d.mts +3 -3
- package/dist/array/non-empty-array.d.mts.map +1 -1
- package/dist/array/non-empty-array.mjs +5 -6
- package/dist/array/non-empty-array.mjs.map +1 -1
- package/dist/array/tuple.d.mts +3 -3
- package/dist/array/tuple.d.mts.map +1 -1
- package/dist/array/tuple.mjs.map +1 -1
- package/dist/compose/intersection.d.mts +2 -2
- package/dist/compose/intersection.d.mts.map +1 -1
- package/dist/compose/intersection.mjs +2 -1
- package/dist/compose/intersection.mjs.map +1 -1
- package/dist/compose/merge-records.d.mts +3 -3
- package/dist/compose/merge-records.d.mts.map +1 -1
- package/dist/compose/merge-records.mjs +2 -1
- package/dist/compose/merge-records.mjs.map +1 -1
- package/dist/compose/recursion.d.mts +2 -2
- package/dist/compose/recursion.d.mts.map +1 -1
- package/dist/compose/recursion.mjs.map +1 -1
- package/dist/compose/union.d.mts +2 -2
- package/dist/compose/union.d.mts.map +1 -1
- package/dist/compose/union.mjs +2 -1
- package/dist/compose/union.mjs.map +1 -1
- package/dist/entry-point.mjs +1 -1
- package/dist/enum/enum.d.mts +3 -3
- package/dist/enum/enum.d.mts.map +1 -1
- package/dist/enum/enum.mjs +18 -20
- package/dist/enum/enum.mjs.map +1 -1
- package/dist/enum/int-range.d.mts +1 -1
- package/dist/enum/int-range.d.mts.map +1 -1
- package/dist/enum/uint-range.d.mts +1 -1
- package/dist/enum/uint-range.d.mts.map +1 -1
- package/dist/globals.d.mts +2 -0
- package/dist/index.mjs +1 -1
- package/dist/other-types/map.d.mts +2 -2
- package/dist/other-types/map.d.mts.map +1 -1
- package/dist/other-types/map.mjs.map +1 -1
- package/dist/other-types/set.d.mts +2 -2
- package/dist/other-types/set.d.mts.map +1 -1
- package/dist/other-types/set.mjs.map +1 -1
- package/dist/record/key-value-record.d.mts +2 -2
- package/dist/record/key-value-record.d.mts.map +1 -1
- package/dist/record/key-value-record.mjs.map +1 -1
- package/dist/record/keyof.d.mts +2 -2
- package/dist/record/keyof.d.mts.map +1 -1
- package/dist/record/keyof.mjs.map +1 -1
- package/dist/record/omit.d.mts +2 -2
- package/dist/record/omit.d.mts.map +1 -1
- package/dist/record/omit.mjs.map +1 -1
- package/dist/record/partial.d.mts +2 -2
- package/dist/record/partial.d.mts.map +1 -1
- package/dist/record/partial.mjs.map +1 -1
- package/dist/record/pick.d.mts +2 -2
- package/dist/record/pick.d.mts.map +1 -1
- package/dist/record/pick.mjs.map +1 -1
- package/dist/record/record.d.mts +4 -4
- package/dist/record/record.d.mts.map +1 -1
- package/dist/record/record.mjs.map +1 -1
- package/dist/record/valueof.d.mts +2 -2
- package/dist/record/valueof.d.mts.map +1 -1
- package/dist/record/valueof.mjs.map +1 -1
- package/dist/utils/index.mjs +1 -1
- package/dist/utils/to-union-string.d.mts +1 -0
- package/dist/utils/to-union-string.d.mts.map +1 -1
- package/dist/utils/to-union-string.mjs +2 -1
- package/dist/utils/to-union-string.mjs.map +1 -1
- package/package.json +1 -1
- package/src/array/array-of-length.mts +8 -11
- package/src/array/array.mts +8 -11
- package/src/array/non-empty-array.mts +11 -12
- package/src/array/tuple.mts +3 -1
- package/src/compose/intersection.mts +5 -6
- package/src/compose/intersection.test.mts +10 -10
- package/src/compose/merge-records.mts +6 -7
- package/src/compose/merge-records.test.mts +2 -2
- package/src/compose/recursion.mts +3 -5
- package/src/compose/union.mts +6 -7
- package/src/compose/union.test.mts +3 -2
- package/src/enum/enum.mts +24 -26
- package/src/enum/int-range.mts +1 -1
- package/src/enum/uint-range.mts +1 -1
- package/src/globals.d.mts +2 -0
- package/src/other-types/map.mts +3 -1
- package/src/other-types/set.mts +3 -1
- package/src/record/key-value-record.mts +3 -1
- package/src/record/keyof.mts +3 -5
- package/src/record/omit.mts +5 -7
- package/src/record/partial.mts +6 -8
- package/src/record/pick.mts +5 -7
- package/src/record/record.mts +9 -13
- package/src/record/valueof.mts +3 -5
- package/src/utils/to-union-string.mts +3 -0
package/README.md
CHANGED
|
@@ -7,18 +7,17 @@ TypeScript-first schema validation library with static type inference.
|
|
|
7
7
|
[](./LICENSE)
|
|
8
8
|
[](https://codecov.io/gh/noshiro-pf/ts-fortress)
|
|
9
9
|
|
|
10
|
-
**ts-fortress** is a runtime validation library similar to [io-ts](https://github.com/gcanti/io-ts) and [
|
|
10
|
+
**ts-fortress** is a runtime validation library similar to [io-ts](https://github.com/gcanti/io-ts) and [Zod](https://zod.dev/), designed to provide type-safe schema validation with excellent TypeScript integration and static type inference.
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
|
+
- 🔗 **Unified type and validator definition** - Define TypeScript types and corresponding runtime validators in a single declaration, ensuring consistency between compile-time types and runtime validation logic
|
|
14
15
|
- 🔒 **Type-safe validation** - Full TypeScript support with static type inference
|
|
15
16
|
- 📖 **Readonly by default** - All constructed types are fully readonly, preventing accidental mutations and promoting immutability
|
|
16
|
-
- 🏗️ **Composable schemas** - Build complex validation schemas from simple building blocks
|
|
17
|
-
- 🔄 **Result-based error handling** - Structured error reporting with `Result<T, readonly ValidationError[]>`
|
|
18
|
-
- 🏷️ **Branded types** - Rich collection of branded number types (Int, SafeInt, PositiveInt, etc.)
|
|
19
17
|
- ⚡ **Performance focused** - Optimized validation with minimal runtime overhead (negligible impact on application performance)
|
|
20
|
-
- 🧩 **Functional composition** - Union, intersection, and merge operations for schema composition
|
|
21
18
|
- 🛠️ **Required default values** - All schemas require explicit default values, enabling automatic data filling via `fill()` function
|
|
19
|
+
- 🏷️ **Branded types** - Rich collection of branded number types (Int, SafeInt, PositiveInt, etc.)
|
|
20
|
+
- 🔄 **Result-based error handling** - Structured error reporting with `Result<T, readonly ValidationError[]>`
|
|
22
21
|
|
|
23
22
|
## Installation
|
|
24
23
|
|
|
@@ -41,11 +40,11 @@ import * as t from 'ts-fortress';
|
|
|
41
40
|
|
|
42
41
|
// Define a schema
|
|
43
42
|
const User = t.record({
|
|
44
|
-
id: t.string(
|
|
45
|
-
name: t.string(
|
|
46
|
-
age: t.number(
|
|
47
|
-
email: t.string(
|
|
48
|
-
isActive: t.boolean(
|
|
43
|
+
id: t.string(),
|
|
44
|
+
name: t.string(),
|
|
45
|
+
age: t.number(),
|
|
46
|
+
email: t.string(),
|
|
47
|
+
isActive: t.boolean(),
|
|
49
48
|
});
|
|
50
49
|
|
|
51
50
|
// Infer TypeScript type
|
|
@@ -83,7 +82,7 @@ if (t.Result.isOk(result)) {
|
|
|
83
82
|
|
|
84
83
|
## Default Values and Data Filling
|
|
85
84
|
|
|
86
|
-
One of
|
|
85
|
+
One of the key design decisions in ts-fortress is that **all schema types have explicit default values**, which allows for powerful data entry capabilities:
|
|
87
86
|
|
|
88
87
|
```typescript
|
|
89
88
|
import * as t from 'ts-fortress';
|
|
@@ -136,7 +135,7 @@ if (t.Result.isErr(result)) {
|
|
|
136
135
|
}
|
|
137
136
|
```
|
|
138
137
|
|
|
139
|
-
### Benefits of
|
|
138
|
+
### Benefits of Default Values
|
|
140
139
|
|
|
141
140
|
- **Consolidated definitions**: Type definitions and default values are defined in one place, eliminating the need to maintain separate default objects
|
|
142
141
|
- **Data integrity**: Never worry about missing required fields
|
|
@@ -145,32 +144,67 @@ if (t.Result.isErr(result)) {
|
|
|
145
144
|
- **Configuration**: Provide sensible defaults for optional configuration
|
|
146
145
|
- **Testing**: Generate complete test data from partial fixtures
|
|
147
146
|
|
|
147
|
+
### Convenient default values
|
|
148
|
+
|
|
149
|
+
Most ts-fortress types provide sensible defaults automatically, so you rarely need to specify explicit default values:
|
|
150
|
+
|
|
148
151
|
```typescript
|
|
149
|
-
//
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
timestamp: t.number(Date.now()),
|
|
159
|
-
version: t.string('1.0.0'),
|
|
160
|
-
}),
|
|
152
|
+
// Most common types have built-in defaults
|
|
153
|
+
const Schema = t.record({
|
|
154
|
+
name: t.string(), // defaults to ""
|
|
155
|
+
age: t.number(), // defaults to 0
|
|
156
|
+
active: t.boolean(), // defaults to false
|
|
157
|
+
tags: t.array(t.string()), // defaults to []
|
|
158
|
+
config: t.record({
|
|
159
|
+
debug: t.boolean(), // defaults to false
|
|
160
|
+
}), // defaults to { debug: false }
|
|
161
161
|
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
You only need to specify explicit default values in two cases: when you want custom values, or when using `intersection` types:
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// Custom default values
|
|
168
|
+
const ServerConfig = t.record({
|
|
169
|
+
port: t.number(3000), // custom default: 3000
|
|
170
|
+
host: t.string('localhost'), // custom default: 'localhost'
|
|
171
|
+
retries: t.number(5), // custom default: 5
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const JobStatus = t.enumType(['started', 'scheduled', 'succeeded', 'failed']);
|
|
162
175
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
176
|
+
const JobFulfilledStatus = t.enumType(['succeeded', 'failed', 'cancelled']);
|
|
177
|
+
|
|
178
|
+
// Intersection types require explicit defaults
|
|
179
|
+
const ReportStatus = t.intersection(
|
|
180
|
+
[JobStatus, JobFulfilledStatus],
|
|
181
|
+
t.enumType(['success', 'failed']), // must provide combined default
|
|
182
|
+
);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
This is because intersection types can be created from arbitrary types, making it impossible to automatically determine appropriate default values. However, when all constituent types are record types, you can use the `mergeRecords` function to avoid specifying defaults:
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
// Using mergeRecords for record-only intersections
|
|
189
|
+
const UserWithMetadata = t.mergeRecords(
|
|
190
|
+
t.record({
|
|
191
|
+
id: t.string(),
|
|
192
|
+
name: t.string(),
|
|
193
|
+
}),
|
|
194
|
+
t.record({
|
|
195
|
+
createdAt: t.number(),
|
|
196
|
+
updatedAt: t.number(),
|
|
197
|
+
}),
|
|
198
|
+
);
|
|
199
|
+
// No explicit default needed - automatically combines defaults from both records
|
|
200
|
+
// Default: { id: '', name: '', createdAt: 0, updatedAt: 0 }
|
|
167
201
|
```
|
|
168
202
|
|
|
169
203
|
## Why ts-fortress over Zod and io-ts?
|
|
170
204
|
|
|
171
|
-
While ts-fortress, [Zod](https://github.com/colinhacks/zod), and [io-ts](https://github.com/gcanti/io-ts) are all excellent TypeScript validation libraries, ts-fortress
|
|
205
|
+
While ts-fortress, [Zod](https://github.com/colinhacks/zod), and [io-ts](https://github.com/gcanti/io-ts) are all excellent TypeScript validation libraries, ts-fortress offers more readable and informative error messages than both, a more type-safe way of building validators than Zod, and addresses some critical runtime consistency issues found in io-ts.
|
|
172
206
|
|
|
173
|
-
### Type Safety
|
|
207
|
+
### Type Safety when Building Schemas
|
|
174
208
|
|
|
175
209
|
**Problem with Zod**: The following code compiles without errors but creates an invalid schema:
|
|
176
210
|
|
|
@@ -291,6 +325,114 @@ user.tags.push('new tag'); // No error
|
|
|
291
325
|
user.tags[0] = 'modified'; // No error
|
|
292
326
|
```
|
|
293
327
|
|
|
328
|
+
**In io-ts, Readonly types will generate verbose error messages**:
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
import * as ioTs from 'io-ts';
|
|
332
|
+
import { PathReporter } from 'io-ts/PathReporter';
|
|
333
|
+
|
|
334
|
+
// io-ts nested readonly version with multiple Readonly wrappers
|
|
335
|
+
const IoTsNestedReadonly = ioTs.readonly(
|
|
336
|
+
ioTs.type({
|
|
337
|
+
user: ioTs.readonly(
|
|
338
|
+
ioTs.type({
|
|
339
|
+
profile: ioTs.readonly(
|
|
340
|
+
ioTs.type({
|
|
341
|
+
age: ioTs.number,
|
|
342
|
+
}),
|
|
343
|
+
),
|
|
344
|
+
}),
|
|
345
|
+
),
|
|
346
|
+
}),
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
const invalidData = {
|
|
350
|
+
user: {
|
|
351
|
+
profile: {
|
|
352
|
+
age: 'not-a-number', // should be number
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
// Get io-ts error messages
|
|
358
|
+
const ioTsResult = IoTsNestedReadonly.decode(invalidData);
|
|
359
|
+
const ioTsErrorMessages = PathReporter.report(ioTsResult);
|
|
360
|
+
|
|
361
|
+
console.log(ioTsErrorMessages[0]);
|
|
362
|
+
// Output: Invalid value "not-a-number" supplied to : Readonly<{ user: Readonly<{ profile: Readonly<{ age: number }> }> }>/user: Readonly<{ profile: Readonly<{ age: number }> }>/profile: Readonly<{ age: number }>/age: number
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
**The error message contains excessive `Readonly<...>` wrapper noise:**
|
|
366
|
+
|
|
367
|
+
- Root level: `Readonly<{ user: Readonly<{ profile: Readonly<{ age: number }> }> }>`
|
|
368
|
+
- User level: `Readonly<{ profile: Readonly<{ age: number }> }>`
|
|
369
|
+
- Profile level: `Readonly<{ age: number }>`
|
|
370
|
+
- Each nested readonly creates exponentially verbose error messages with redundant type information
|
|
371
|
+
|
|
372
|
+
This verbosity makes error messages extremely difficult to read and debug in production environments.
|
|
373
|
+
|
|
374
|
+
**ts-fortress addresses this issue** by generating clean, actionable error messages without verbose type wrapper details:
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
import * as tf from 'ts-fortress';
|
|
378
|
+
|
|
379
|
+
// ts-fortress equivalent clean structure
|
|
380
|
+
const TsFortressNestedType = tf.record({
|
|
381
|
+
user: tf.record({
|
|
382
|
+
profile: tf.record({
|
|
383
|
+
age: tf.number(0),
|
|
384
|
+
}),
|
|
385
|
+
}),
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
// Get ts-fortress error messages
|
|
389
|
+
const tsFortressResult = TsFortressNestedType.validate(invalidData);
|
|
390
|
+
const tsFortressErrorMessages = tf.Result.isErr(tsFortressResult)
|
|
391
|
+
? tf.validationErrorsToMessages(tsFortressResult.value)
|
|
392
|
+
: [];
|
|
393
|
+
|
|
394
|
+
console.log(tsFortressErrorMessages[0]);
|
|
395
|
+
// Clean output: Expected <number> at user.profile.age, got <string> type value "not-a-number".
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**ts-fortress vs Zod comparison:**
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
import { z } from 'zod';
|
|
402
|
+
|
|
403
|
+
// Zod nested readonly equivalent
|
|
404
|
+
const ZodNestedType = z
|
|
405
|
+
.object({
|
|
406
|
+
user: z
|
|
407
|
+
.object({
|
|
408
|
+
profile: z
|
|
409
|
+
.object({
|
|
410
|
+
age: z.number(),
|
|
411
|
+
})
|
|
412
|
+
.readonly(),
|
|
413
|
+
})
|
|
414
|
+
.readonly(),
|
|
415
|
+
})
|
|
416
|
+
.readonly();
|
|
417
|
+
|
|
418
|
+
// Get Zod error messages using prettifyError
|
|
419
|
+
const zodResult = ZodNestedType.safeParse(invalidData);
|
|
420
|
+
const zodErrorMessages = zodResult.success
|
|
421
|
+
? ''
|
|
422
|
+
: z.prettifyError(zodResult.error);
|
|
423
|
+
|
|
424
|
+
console.log(zodErrorMessages);
|
|
425
|
+
// Clean output: "✖ Invalid input: expected number, received string\n → at user.profile.age"
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**Error message comparison:**
|
|
429
|
+
|
|
430
|
+
- **io-ts**: 148 characters of verbose type information mixed with the actual error
|
|
431
|
+
- **Zod**: 62 characters with visual formatting but missing the actual invalid value
|
|
432
|
+
- **ts-fortress**: 74 characters focused purely on what went wrong and where, including the actual invalid value
|
|
433
|
+
|
|
434
|
+
While Zod produces cleaner error messages than io-ts and includes helpful visual formatting, **ts-fortress provides superior debugging experience** by including the actual invalid value (`"not-a-number"`) in the error message, making it easier to understand what data caused the validation failure.
|
|
435
|
+
|
|
294
436
|
### Benefits of Deep Readonly
|
|
295
437
|
|
|
296
438
|
- **Immutability by default**: Prevents accidental mutations that can lead to bugs
|
|
@@ -326,6 +468,8 @@ type T = t.TypeOf<typeof T>;
|
|
|
326
468
|
// The runtime validator only accepts strings, but TypeScript thinks it accepts numbers!
|
|
327
469
|
```
|
|
328
470
|
|
|
471
|
+
For this reason, the [io-ts documentation](https://github.com/gcanti/io-ts/blob/master/index.md#implemented-types--combinators) states that `t.keyof` only supports string keys (although this is somewhat dangerous, as the TypeScript type definition does not prevent the use of keys other than string).
|
|
472
|
+
|
|
329
473
|
#### 2. Union + Undefined Decode Issues ([Issue #677](https://github.com/gcanti/io-ts/issues/677))
|
|
330
474
|
|
|
331
475
|
```typescript
|
|
@@ -371,6 +515,8 @@ const C = t.partial({
|
|
|
371
515
|
|
|
372
516
|
**ts-fortress eliminates these problems** by ensuring strict runtime-type consistency:
|
|
373
517
|
|
|
518
|
+
Keyof Type Mismatch:
|
|
519
|
+
|
|
374
520
|
```typescript
|
|
375
521
|
import * as t from 'ts-fortress';
|
|
376
522
|
|
|
@@ -392,6 +538,22 @@ type T = t.TypeOf<typeof T>;
|
|
|
392
538
|
console.log(T.validate(0)); // ❌ Fails correctly - number 0 is rejected
|
|
393
539
|
console.log(T.validate('0')); // ✅ Success - string "0" is accepted
|
|
394
540
|
|
|
541
|
+
// For this use case, if you want to define a union type of numeric literals, you can use `uintRange` from ts-fortress:
|
|
542
|
+
|
|
543
|
+
const U = t.uintRange({ start: 0, end: 5 });
|
|
544
|
+
|
|
545
|
+
type U = t.TypeOf<typeof U>;
|
|
546
|
+
// ↑ TypeScript correctly infers: 0 | 1 | 2 | 3 | 4 (number literals)
|
|
547
|
+
|
|
548
|
+
console.log(U.validate('0')); // ❌ Fails - string "0" is rejected
|
|
549
|
+
console.log(U.validate(0)); // ✅ Success - number 0 is accepted
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
Union + Undefined Decode Issues:
|
|
553
|
+
|
|
554
|
+
```ts
|
|
555
|
+
import * as t from 'ts-fortress';
|
|
556
|
+
|
|
395
557
|
// ✅ Complex union types work reliably without unexpected behavior
|
|
396
558
|
const A = t.record({
|
|
397
559
|
A: t.union([t.number(0), t.undefinedType, t.nullType]),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Type } from '../type.mjs';
|
|
2
|
-
export declare const arrayOfLength: <A, N extends SmallUint>(size: N, elementType: Type<A>, options?:
|
|
3
|
-
typeName
|
|
4
|
-
defaultValue
|
|
2
|
+
export declare const arrayOfLength: <A, N extends SmallUint>(size: N, elementType: Type<A>, options?: PartialReadonly<{
|
|
3
|
+
typeName: string;
|
|
4
|
+
defaultValue: ArrayOfLength<N, A>;
|
|
5
5
|
}>) => Type<ArrayOfLength<N, A>>;
|
|
6
6
|
//# sourceMappingURL=array-of-length.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"array-of-length.d.mts","sourceRoot":"","sources":["../../src/array/array-of-length.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAWxC,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,SAAS,SAAS,EAClD,MAAM,CAAC,EACP,aAAa,IAAI,CAAC,CAAC,CAAC,EACpB,UAAU,
|
|
1
|
+
{"version":3,"file":"array-of-length.d.mts","sourceRoot":"","sources":["../../src/array/array-of-length.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAWxC,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,SAAS,SAAS,EAClD,MAAM,CAAC,EACP,aAAa,IAAI,CAAC,CAAC,CAAC,EACpB,UAAU,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CACnC,CAAC,KACD,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAiE1B,CAAC"}
|
|
@@ -5,17 +5,16 @@ import { createIsFn } from '../utils/create-is-fn.mjs';
|
|
|
5
5
|
import { createPrimitiveValidationError, prependIndexToValidationErrors } from '../utils/validation-error.mjs';
|
|
6
6
|
|
|
7
7
|
const arrayOfLength = (size, elementType, options) => {
|
|
8
|
-
const { typeName,
|
|
8
|
+
const { typeName = `ArrayOfLength<${size}, ${elementType.typeName}>`,
|
|
9
9
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
10
10
|
defaultValue = Arr.create(size, elementType.defaultValue), } = options ?? {};
|
|
11
|
-
const typeNameFilled = typeName ?? `[${Arr.create(size, elementType.typeName).join(', ')}]`;
|
|
12
11
|
const validate = (a) => {
|
|
13
12
|
if (!Arr.isArray(a)) {
|
|
14
13
|
return Result.err([
|
|
15
14
|
createPrimitiveValidationError({
|
|
16
15
|
actualValue: a,
|
|
17
16
|
expectedType: 'array',
|
|
18
|
-
typeName
|
|
17
|
+
typeName,
|
|
19
18
|
}),
|
|
20
19
|
]);
|
|
21
20
|
}
|
|
@@ -24,9 +23,9 @@ const arrayOfLength = (size, elementType, options) => {
|
|
|
24
23
|
{
|
|
25
24
|
path: [],
|
|
26
25
|
actualValue: a,
|
|
27
|
-
expectedType:
|
|
26
|
+
expectedType: typeName,
|
|
28
27
|
message: `Expected array of length ${size}, got length ${a.length}`,
|
|
29
|
-
typeName
|
|
28
|
+
typeName,
|
|
30
29
|
},
|
|
31
30
|
]);
|
|
32
31
|
}
|
|
@@ -50,7 +49,7 @@ const arrayOfLength = (size, elementType, options) => {
|
|
|
50
49
|
Arr.map(Arr.seq(size), (i) => elementType.fill(a[i]))
|
|
51
50
|
: defaultValue;
|
|
52
51
|
return {
|
|
53
|
-
typeName
|
|
52
|
+
typeName,
|
|
54
53
|
defaultValue,
|
|
55
54
|
fill,
|
|
56
55
|
validate,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"array-of-length.mjs","sources":["../../src/array/array-of-length.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;AAYO,MAAM,aAAa,GAAG,CAC3B,IAAO,EACP,WAAoB,EACpB,OAGE,KAC2B;
|
|
1
|
+
{"version":3,"file":"array-of-length.mjs","sources":["../../src/array/array-of-length.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;AAYO,MAAM,aAAa,GAAG,CAC3B,IAAO,EACP,WAAoB,EACpB,OAGE,KAC2B;IAG7B,MAAM,EACJ,QAAQ,GAAG,CAAA,cAAA,EAAiB,IAAI,CAAA,EAAA,EAAK,WAAW,CAAC,QAAQ,CAAA,CAAA,CAAG;;AAE5D,IAAA,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,YAAY,CAAM,GAC/D,GAAG,OAAO,IAAI,EAAE;AAEjB,IAAA,MAAM,QAAQ,GAAwB,CAAC,CAAC,KAAI;QAC1C,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YACnB,OAAO,MAAM,CAAC,GAAG,CAAC;AAChB,gBAAA,8BAA8B,CAAC;AAC7B,oBAAA,WAAW,EAAE,CAAC;AACd,oBAAA,YAAY,EAAE,OAAO;oBACrB,QAAQ;iBACT,CAAC;AACH,aAAA,CAAC;QACJ;AAEA,QAAA,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,EAAE;YACrB,OAAO,MAAM,CAAC,GAAG,CAAC;AAChB,gBAAA;AACE,oBAAA,IAAI,EAAE,EAAE;AACR,oBAAA,WAAW,EAAE,CAAC;AACd,oBAAA,YAAY,EAAE,QAAQ;AACtB,oBAAA,OAAO,EAAE,CAAA,yBAAA,EAA4B,IAAI,gBAAgB,CAAC,CAAC,MAAM,CAAA,CAAE;oBACnE,QAAQ;AAC4B,iBAAA;AACvC,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,MAAM,GAA+B,GAAG,CAAC,QAAQ,CAAC,aAAS;AAC/D,YAAA,KAAK,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBACrC,MAAM,GAAG,GAAG,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;AACpC,gBAAA,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;oBACrB,OAAO,8BAA8B,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC;gBACzD;YACF;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACrB,YAAA,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;QAC3B;;AAGA,QAAA,OAAO,MAAM,CAAC,EAAE,CAAC,CAAiB,CAAC;AACrC,IAAA,CAAC;AAED,IAAA,MAAM,IAAI,GAAoB,CAAC,CAAC,KAC9B,GAAG,CAAC,OAAO,CAAC,CAAC;AACX;;YAEG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAa;UACjE,YAAY;IAElB,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,IAAI;QACJ,QAAQ;AACR,QAAA,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC;AACxB,QAAA,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;AAC5B,QAAA,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;KACnC;AACH;;;;"}
|
package/dist/array/array.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Type } from '../type.mjs';
|
|
2
|
-
export declare const array: <A>(elementType: Type<A>, options?:
|
|
2
|
+
export declare const array: <A>(elementType: Type<A>, options?: PartialReadonly<{
|
|
3
3
|
typeName: string;
|
|
4
4
|
defaultValue: readonly A[];
|
|
5
|
-
}
|
|
5
|
+
}>) => Type<readonly A[]>;
|
|
6
6
|
//# sourceMappingURL=array.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"array.d.mts","sourceRoot":"","sources":["../../src/array/array.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAUxC,eAAO,MAAM,KAAK,GAAI,CAAC,EACrB,aAAa,IAAI,CAAC,CAAC,CAAC,EACpB,UAAU,
|
|
1
|
+
{"version":3,"file":"array.d.mts","sourceRoot":"","sources":["../../src/array/array.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAUxC,eAAO,MAAM,KAAK,GAAI,CAAC,EACrB,aAAa,IAAI,CAAC,CAAC,CAAC,EACpB,UAAU,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,SAAS,CAAC,EAAE,CAAC;CAC5B,CAAC,KACD,IAAI,CAAC,SAAS,CAAC,EAAE,CA8CnB,CAAC"}
|
package/dist/array/array.mjs
CHANGED
|
@@ -5,15 +5,14 @@ import { createIsFn } from '../utils/create-is-fn.mjs';
|
|
|
5
5
|
import { createPrimitiveValidationError, prependIndexToValidationErrors } from '../utils/validation-error.mjs';
|
|
6
6
|
|
|
7
7
|
const array = (elementType, options) => {
|
|
8
|
-
const { typeName
|
|
9
|
-
const typeNameFilled = typeName ?? `(${elementType.typeName})[]`;
|
|
8
|
+
const { typeName = `${elementType.typeName}[]`, defaultValue = [] } = options ?? {};
|
|
10
9
|
const validate = (a) => {
|
|
11
10
|
if (!Arr.isArray(a)) {
|
|
12
11
|
return Result.err([
|
|
13
12
|
createPrimitiveValidationError({
|
|
14
13
|
actualValue: a,
|
|
15
14
|
expectedType: 'array',
|
|
16
|
-
typeName
|
|
15
|
+
typeName,
|
|
17
16
|
}),
|
|
18
17
|
]);
|
|
19
18
|
}
|
|
@@ -33,7 +32,7 @@ const array = (elementType, options) => {
|
|
|
33
32
|
};
|
|
34
33
|
const fill = (a) => Arr.isArray(a) ? a.map((e) => elementType.fill(e)) : defaultValue;
|
|
35
34
|
return {
|
|
36
|
-
typeName
|
|
35
|
+
typeName,
|
|
37
36
|
defaultValue,
|
|
38
37
|
fill,
|
|
39
38
|
validate,
|
package/dist/array/array.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"array.mjs","sources":["../../src/array/array.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;MAWa,KAAK,GAAG,CACnB,WAAoB,EACpB,
|
|
1
|
+
{"version":3,"file":"array.mjs","sources":["../../src/array/array.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;MAWa,KAAK,GAAG,CACnB,WAAoB,EACpB,OAGE,KACoB;AAGtB,IAAA,MAAM,EAAE,QAAQ,GAAG,CAAA,EAAG,WAAW,CAAC,QAAQ,CAAA,EAAA,CAAI,EAAE,YAAY,GAAG,EAAE,EAAE,GACjE,OAAO,IAAI,EAAE;AAEf,IAAA,MAAM,QAAQ,GAAwB,CAAC,CAAC,KAAI;QAC1C,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YACnB,OAAO,MAAM,CAAC,GAAG,CAAC;AAChB,gBAAA,8BAA8B,CAAC;AAC7B,oBAAA,WAAW,EAAE,CAAC;AACd,oBAAA,YAAY,EAAE,OAAO;oBACrB,QAAQ;iBACT,CAAC;AACH,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,MAAM,GAA+B,GAAG,CAAC,QAAQ,CAAC,aAAS;AAC/D,YAAA,KAAK,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBACrC,MAAM,GAAG,GAAG,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;AACpC,gBAAA,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;oBACrB,OAAO,8BAA8B,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC;gBACzD;YACF;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACrB,YAAA,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;QAC3B;;AAGA,QAAA,OAAO,MAAM,CAAC,EAAE,CAAC,CAAM,CAAC;AAC1B,IAAA,CAAC;AAED,IAAA,MAAM,IAAI,GAAoB,CAAC,CAAC,KAC9B,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY;IAEnE,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,IAAI;QACJ,QAAQ;AACR,QAAA,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC;AACxB,QAAA,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;AAClC,QAAA,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;KAC7B;AACH;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Type } from '../type.mjs';
|
|
2
|
-
export declare const nonEmptyArray: <A>(elementType: Type<A>, options?:
|
|
3
|
-
typeName
|
|
4
|
-
defaultValue
|
|
2
|
+
export declare const nonEmptyArray: <A>(elementType: Type<A>, options?: PartialReadonly<{
|
|
3
|
+
typeName: string;
|
|
4
|
+
defaultValue: NonEmptyArray<A>;
|
|
5
5
|
}>) => Type<NonEmptyArray<A>>;
|
|
6
6
|
//# sourceMappingURL=non-empty-array.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"non-empty-array.d.mts","sourceRoot":"","sources":["../../src/array/non-empty-array.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAWxC,eAAO,MAAM,aAAa,GAAI,CAAC,EAC7B,aAAa,IAAI,CAAC,CAAC,CAAC,EACpB,UAAU,
|
|
1
|
+
{"version":3,"file":"non-empty-array.d.mts","sourceRoot":"","sources":["../../src/array/non-empty-array.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAWxC,eAAO,MAAM,aAAa,GAAI,CAAC,EAC7B,aAAa,IAAI,CAAC,CAAC,CAAC,EACpB,UAAU,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CAChC,CAAC,KACD,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CA8DvB,CAAC"}
|
|
@@ -5,15 +5,14 @@ import { createIsFn } from '../utils/create-is-fn.mjs';
|
|
|
5
5
|
import { createPrimitiveValidationError, prependIndexToValidationErrors } from '../utils/validation-error.mjs';
|
|
6
6
|
|
|
7
7
|
const nonEmptyArray = (elementType, options) => {
|
|
8
|
-
const { typeName
|
|
9
|
-
const typeNameFilled = typeName ?? `NonEmptyArray<${elementType.typeName}>`;
|
|
8
|
+
const { typeName = `NonEmptyArray<${elementType.typeName}>`, defaultValue = Arr.newArray(1, elementType.defaultValue), } = options ?? {};
|
|
10
9
|
const validate = (a) => {
|
|
11
10
|
if (!Arr.isArray(a)) {
|
|
12
11
|
return Result.err([
|
|
13
12
|
createPrimitiveValidationError({
|
|
14
13
|
actualValue: a,
|
|
15
14
|
expectedType: 'array',
|
|
16
|
-
typeName
|
|
15
|
+
typeName,
|
|
17
16
|
}),
|
|
18
17
|
]);
|
|
19
18
|
}
|
|
@@ -22,8 +21,8 @@ const nonEmptyArray = (elementType, options) => {
|
|
|
22
21
|
{
|
|
23
22
|
path: [],
|
|
24
23
|
actualValue: a,
|
|
25
|
-
expectedType:
|
|
26
|
-
typeName
|
|
24
|
+
expectedType: typeName,
|
|
25
|
+
typeName,
|
|
27
26
|
message: 'Expected non-empty array, got empty array',
|
|
28
27
|
},
|
|
29
28
|
]);
|
|
@@ -46,7 +45,7 @@ const nonEmptyArray = (elementType, options) => {
|
|
|
46
45
|
? Arr.map(a, (e) => elementType.fill(e))
|
|
47
46
|
: defaultValue;
|
|
48
47
|
return {
|
|
49
|
-
typeName
|
|
48
|
+
typeName,
|
|
50
49
|
defaultValue,
|
|
51
50
|
fill,
|
|
52
51
|
validate,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"non-empty-array.mjs","sources":["../../src/array/non-empty-array.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;MAYa,aAAa,GAAG,CAC3B,WAAoB,EACpB,OAGE,KACwB;IAG1B,MAAM,
|
|
1
|
+
{"version":3,"file":"non-empty-array.mjs","sources":["../../src/array/non-empty-array.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;MAYa,aAAa,GAAG,CAC3B,WAAoB,EACpB,OAGE,KACwB;IAG1B,MAAM,EACJ,QAAQ,GAAG,CAAA,cAAA,EAAiB,WAAW,CAAC,QAAQ,CAAA,CAAA,CAAG,EACnD,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,GACzD,GAAG,OAAO,IAAI,EAAE;AAEjB,IAAA,MAAM,QAAQ,GAAwB,CAAC,CAAC,KAAI;QAC1C,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YACnB,OAAO,MAAM,CAAC,GAAG,CAAC;AAChB,gBAAA,8BAA8B,CAAC;AAC7B,oBAAA,WAAW,EAAE,CAAC;AACd,oBAAA,YAAY,EAAE,OAAO;oBACrB,QAAQ;iBACT,CAAC;AACH,aAAA,CAAC;QACJ;AAEA,QAAA,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YAClB,OAAO,MAAM,CAAC,GAAG,CAAC;AAChB,gBAAA;AACE,oBAAA,IAAI,EAAE,EAAE;AACR,oBAAA,WAAW,EAAE,CAAC;AACd,oBAAA,YAAY,EAAE,QAAQ;oBACtB,QAAQ;AACR,oBAAA,OAAO,EAAE,2CAA2C;AAChB,iBAAA;AACvC,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,MAAM,GAA+B,GAAG,CAAC,QAAQ,CAAC,aAAS;AAC/D,YAAA,KAAK,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBACrC,MAAM,GAAG,GAAG,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;AACpC,gBAAA,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;oBACrB,OAAO,8BAA8B,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC;gBACzD;YACF;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACrB,YAAA,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;QAC3B;;AAGA,QAAA,OAAO,MAAM,CAAC,EAAE,CAAC,CAAiB,CAAC;AACrC,IAAA,CAAC;AAED,IAAA,MAAM,IAAI,GAAoB,CAAC,CAAC,KAC9B,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;AAChC,UAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;UACrC,YAAY;IAElB,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,IAAI;QACJ,QAAQ;AACR,QAAA,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC;AACxB,QAAA,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;AAClC,QAAA,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;KAC7B;AACH;;;;"}
|
package/dist/array/tuple.d.mts
CHANGED
|
@@ -2,8 +2,8 @@ import { type Type, type TypeOf } from '../type.mjs';
|
|
|
2
2
|
type MapTuple<T extends readonly Type<unknown>[]> = {
|
|
3
3
|
readonly [K in keyof T]: TypeOf<T[K]>;
|
|
4
4
|
};
|
|
5
|
-
export declare const tuple: <const A extends readonly Type<unknown>[]>(types: A, options?:
|
|
6
|
-
typeName
|
|
7
|
-
}
|
|
5
|
+
export declare const tuple: <const A extends readonly Type<unknown>[]>(types: A, options?: PartialReadonly<{
|
|
6
|
+
typeName: string;
|
|
7
|
+
}>) => Type<MapTuple<A>>;
|
|
8
8
|
export {};
|
|
9
9
|
//# sourceMappingURL=tuple.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tuple.d.mts","sourceRoot":"","sources":["../../src/array/tuple.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAWrD,KAAK,QAAQ,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI;IAClD,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACtC,CAAC;AAEF,eAAO,MAAM,KAAK,GAAI,KAAK,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,OAAO,CAAC,EAAE,EAC5D,OAAO,CAAC,EACR,UAAU,
|
|
1
|
+
{"version":3,"file":"tuple.d.mts","sourceRoot":"","sources":["../../src/array/tuple.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAWrD,KAAK,QAAQ,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI;IAClD,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACtC,CAAC;AAEF,eAAO,MAAM,KAAK,GAAI,KAAK,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,OAAO,CAAC,EAAE,EAC5D,OAAO,CAAC,EACR,UAAU,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,KACD,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAiElB,CAAC"}
|
package/dist/array/tuple.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tuple.mjs","sources":["../../src/array/tuple.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;MAgBa,KAAK,GAAG,CACnB,KAAQ,EACR,
|
|
1
|
+
{"version":3,"file":"tuple.mjs","sources":["../../src/array/tuple.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;MAgBa,KAAK,GAAG,CACnB,KAAQ,EACR,OAEE,KACmB;IAGrB,MAAM,EAAE,QAAQ,GAAG,OAAO,EAAE,GAAG,OAAO,IAAI,EAAE;AAE5C,IAAA,MAAM,YAAY,GAAG,GAAG,CAAC,GAAG,CAC1B,KAAK,EACL,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CACA;AAEvB,IAAA,MAAM,QAAQ,GAAwB,CAAC,CAAC,KAAI;QAC1C,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YACnB,OAAO,MAAM,CAAC,GAAG,CAAC;AAChB,gBAAA,8BAA8B,CAAC;AAC7B,oBAAA,WAAW,EAAE,CAAC;AACd,oBAAA,YAAY,EAAE,OAAO;oBACrB,QAAQ;iBACT,CAAC;AACH,aAAA,CAAC;QACJ;QAEA,IAAI,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE;YAC7B,OAAO,MAAM,CAAC,GAAG,CAAC;AAChB,gBAAA;AACE,oBAAA,IAAI,EAAE,EAAE;AACR,oBAAA,WAAW,EAAE,CAAC;AACd,oBAAA,YAAY,EAAE,QAAQ;oBACtB,QAAQ;oBACR,OAAO,EAAE,yCAAyC,KAAK,CAAC,MAAM,CAAA,qBAAA,EAAwB,CAAC,CAAC,MAAM,CAAA,CAAE;AAC5D,iBAAA;AACvC,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,MAAM,GAA+B,GAAG,CAAC,QAAQ,CAAC,aAAS;YAC/D,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE;gBAChE,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;AAChC,gBAAA,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;oBACrB,OAAO,8BAA8B,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC;gBACzD;YACF;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACrB,YAAA,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;QAC3B;;AAGA,QAAA,OAAO,MAAM,CAAC,EAAE,CAAC,CAAM,CAAC;AAC1B,IAAA,CAAC;AAED,IAAA,MAAM,IAAI,GAAoB,CAAC,CAAC,KAC9B,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACZ,UAAE;AACF;YACG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAiB;IAExD,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,IAAI;QACJ,QAAQ;AACR,QAAA,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC;AACxB,QAAA,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;AAClC,QAAA,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;KAC7B;AACH;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Type, type TypeOf } from '../type.mjs';
|
|
2
|
-
export declare const intersection: <const Types extends NonEmptyArray<Type<unknown>>>(types: Types, defaultType: IntersectionType<Types>, options?:
|
|
2
|
+
export declare const intersection: <const Types extends NonEmptyArray<Type<unknown>>>(types: Types, defaultType: IntersectionType<Types>, options?: PartialReadonly<{
|
|
3
3
|
typeName: string;
|
|
4
|
-
}
|
|
4
|
+
}>) => IntersectionType<Types>;
|
|
5
5
|
type IntersectionType<Types extends NonEmptyArray<Type<unknown>>> = Type<IntersectionTypeValue<Types>>;
|
|
6
6
|
type IntersectionTypeValue<Types extends NonEmptyArray<Type<unknown>>> = TsFortressInternal.IntersectionTypeValueImpl<Types>;
|
|
7
7
|
declare namespace TsFortressInternal {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intersection.d.mts","sourceRoot":"","sources":["../../src/compose/intersection.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"intersection.d.mts","sourceRoot":"","sources":["../../src/compose/intersection.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAUrD,eAAO,MAAM,YAAY,GAAI,KAAK,CAAC,KAAK,SAAS,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAC3E,OAAO,KAAK,EACZ,aAAa,gBAAgB,CAAC,KAAK,CAAC,EACpC,UAAU,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,KACD,gBAAgB,CAAC,KAAK,CAiDxB,CAAC;AAEF,KAAK,gBAAgB,CAAC,KAAK,SAAS,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CACtE,qBAAqB,CAAC,KAAK,CAAC,CAC7B,CAAC;AAEF,KAAK,qBAAqB,CAAC,KAAK,SAAS,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IACnE,kBAAkB,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;AAEtD,kBAAU,kBAAkB,CAAC;IAC3B,MAAM,MAAM,yBAAyB,CACnC,KAAK,SAAS,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IACxC,YAAY,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAE/C,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;;CAClE;AAsBD,KAAK,cAAc,CAAC,KAAK,SAAS,SAAS,IAAI,CAAC,OAAO,CAAC,EAAE,IACxD,kBAAkB,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;AAE3C,kBAAU,kBAAkB,CAAC;IAC3B,MAAM,MAAM,cAAc,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE,IACzD,KAAK,SAAS,SAAS,EAAE,GACrB,EAAE,GACF,KAAK,SAAS,SAAS,CAAC,MAAM,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,GAChD,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,GACvD,KAAK,CAAC;IAEd,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;;CACzD"}
|
|
@@ -2,10 +2,11 @@ import { Arr, Result } from 'ts-data-forge';
|
|
|
2
2
|
import { createAssertFn } from '../utils/create-assert-fn.mjs';
|
|
3
3
|
import { createCastFn } from '../utils/create-cast-fn.mjs';
|
|
4
4
|
import { createIsFn } from '../utils/create-is-fn.mjs';
|
|
5
|
+
import { toIntersectionString } from '../utils/to-union-string.mjs';
|
|
5
6
|
|
|
6
7
|
const intersection = (types, defaultType, options) => {
|
|
7
8
|
const typeNameFilled = options?.typeName ??
|
|
8
|
-
`
|
|
9
|
+
`(${toIntersectionString(types.map((a) => a.typeName))})`;
|
|
9
10
|
const validate = (a) => {
|
|
10
11
|
const errors = Arr.generate(function* () {
|
|
11
12
|
for (const type of types) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intersection.mjs","sources":["../../src/compose/intersection.mts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"intersection.mjs","sources":["../../src/compose/intersection.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;AAWO,MAAM,YAAY,GAAG,CAC1B,KAAY,EACZ,WAAoC,EACpC,OAEE,KACyB;AAG3B,IAAA,MAAM,cAAc,GAClB,OAAO,EAAE,QAAQ;AACjB,QAAA,CAAA,CAAA,EAAI,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG;AAE3D,IAAA,MAAM,QAAQ,GAAwB,CAAC,CAAC,KAAI;AAC1C,QAAA,MAAM,MAAM,GAA+B,GAAG,CAAC,QAAQ,CAAC,aAAS;AAC/D,YAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;gBACxB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE5B,gBAAA,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;oBACrB,MAAM;AACJ,wBAAA,IAAI,EAAE,EAAE;AACR,wBAAA,WAAW,EAAE,CAAC;AACd,wBAAA,YAAY,EAAE,cAAc;wBAC5B,OAAO,EAAE,yDAAyD;6BAC/D,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ;6BACrB,IAAI,CAAC,IAAI,CAAC,CAAA,EAAA,CAAI;AACjB,wBAAA,QAAQ,EAAE,cAAc;qBACY;AAEtC,oBAAA,OAAO,GAAG,CAAC,KAAK;;;AAGtB,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACrB,YAAA,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;;;AAI3B,QAAA,OAAO,MAAM,CAAC,EAAE,CAAC,CAAM,CAAC;AAC1B,IAAA,CAAC;AAED,IAAA,MAAM,EAAE,GAAG,UAAU,CAAI,QAAQ,CAAC;IAElC,MAAM,IAAI,GAAoB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEtE,OAAO;AACL,QAAA,QAAQ,EAAE,cAAc;QACxB,YAAY,EAAE,WAAW,CAAC,YAAY;QACtC,IAAI;QACJ,QAAQ;QACR,EAAE;AACF,QAAA,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;AAClC,QAAA,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;KAC7B;AACH;;;;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type Type, type TypeOf } from '../type.mjs';
|
|
2
|
-
export declare const mergeRecords: <const Types extends NonEmptyArray<Type<UnknownRecord>>>(types: Types, options?:
|
|
3
|
-
defaultType: IntersectionType<Types>;
|
|
2
|
+
export declare const mergeRecords: <const Types extends NonEmptyArray<Type<UnknownRecord>>>(types: Types, options?: PartialReadonly<{
|
|
4
3
|
typeName: string;
|
|
5
|
-
|
|
4
|
+
defaultType: IntersectionType<Types>;
|
|
5
|
+
}>) => IntersectionType<Types>;
|
|
6
6
|
type IntersectionType<Types extends NonEmptyArray<Type<UnknownRecord>>> = Type<IntersectionTypeValue<Types>>;
|
|
7
7
|
type IntersectionTypeValue<Types extends NonEmptyArray<Type<UnknownRecord>>> = Intersection<TsFortressInternal.UnwrapTypeList<Types>>;
|
|
8
8
|
declare namespace TsFortressInternal {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-records.d.mts","sourceRoot":"","sources":["../../src/compose/merge-records.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"merge-records.d.mts","sourceRoot":"","sources":["../../src/compose/merge-records.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAUrD,eAAO,MAAM,YAAY,GACvB,KAAK,CAAC,KAAK,SAAS,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,EAEtD,OAAO,KAAK,EACZ,UAAU,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;CACtC,CAAC,KACD,gBAAgB,CAAC,KAAK,CA4DxB,CAAC;AAEF,KAAK,gBAAgB,CAAC,KAAK,SAAS,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,IAAI,CAC5E,qBAAqB,CAAC,KAAK,CAAC,CAC7B,CAAC;AAEF,KAAK,qBAAqB,CAAC,KAAK,SAAS,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IACzE,YAAY,CAAC,kBAAkB,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AAEzD,kBAAU,kBAAkB,CAAC;IAC3B,MAAM,MAAM,cAAc,CAAC,KAAK,SAAS,SAAS,IAAI,CAAC,aAAa,CAAC,EAAE,IACrE,cAAc,CAAC,KAAK,CAAC,CAAC;IAExB,KAAK,cAAc,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE,IAClD,KAAK,SAAS,SAAS,EAAE,GACrB,EAAE,GACF,KAAK,SAAS,SAAS,CAAC,MAAM,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,GAChD,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,GACvD,KAAK,CAAC;IAEd,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;;CAC/D"}
|
|
@@ -2,10 +2,11 @@ import { Arr, Result, isRecord } from 'ts-data-forge';
|
|
|
2
2
|
import { createAssertFn } from '../utils/create-assert-fn.mjs';
|
|
3
3
|
import { createCastFn } from '../utils/create-cast-fn.mjs';
|
|
4
4
|
import { createIsFn } from '../utils/create-is-fn.mjs';
|
|
5
|
+
import { toIntersectionString } from '../utils/to-union-string.mjs';
|
|
5
6
|
|
|
6
7
|
const mergeRecords = (types, options) => {
|
|
7
8
|
const typeNameFilled = options?.typeName ??
|
|
8
|
-
`
|
|
9
|
+
`(${toIntersectionString(types.map((a) => a.typeName))})`;
|
|
9
10
|
const validate = (a) => {
|
|
10
11
|
const errors = Arr.generate(function* () {
|
|
11
12
|
for (const type of types) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-records.mjs","sources":["../../src/compose/merge-records.mts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"merge-records.mjs","sources":["../../src/compose/merge-records.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;MAWa,YAAY,GAAG,CAG1B,KAAY,EACZ,OAGE,KACyB;AAG3B,IAAA,MAAM,cAAc,GAClB,OAAO,EAAE,QAAQ;AACjB,QAAA,CAAA,CAAA,EAAI,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG;AAE3D,IAAA,MAAM,QAAQ,GAAwB,CAAC,CAAC,KAAI;AAC1C,QAAA,MAAM,MAAM,GAA+B,GAAG,CAAC,QAAQ,CAAC,aAAS;AAC/D,YAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;gBACxB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5B,gBAAA,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;oBACrB,MAAM;AACJ,wBAAA,IAAI,EAAE,EAAE;AACR,wBAAA,WAAW,EAAE,CAAC;AACd,wBAAA,YAAY,EAAE,cAAc;wBAC5B,OAAO,EAAE,yDAAyD;6BAC/D,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ;6BACrB,IAAI,CAAC,IAAI,CAAC,CAAA,EAAA,CAAI;AACjB,wBAAA,QAAQ,EAAE,cAAc;qBACY;AAEtC,oBAAA,OAAO,GAAG,CAAC,KAAK;;;AAGtB,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACrB,YAAA,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;;;AAI3B,QAAA,OAAO,MAAM,CAAC,EAAE,CAAC,CAAM,CAAC;AAC1B,IAAA,CAAC;AAED,IAAA,MAAM,EAAE,GAAG,UAAU,CAAI,QAAQ,CAAC;IAElC,MAAM,IAAI,GAAoB,CAAC,CAAC,KAC9B,EAAE,CAAC,CAAC;AACF,UAAE;WACC,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;AAC9B,YAAA,iBAAiB,CACf,QAAQ,CAAC,CAAC;kBACN,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACpC,kBAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAChC,CAAC;AAER,IAAA,MAAM,YAAY,GAChB,OAAO,EAAE,WAAW,EAAE,YAAY;AAClC,QAAA,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC;IAErD,OAAO;AACL,QAAA,QAAQ,EAAE,cAAc;QACxB,YAAY;QACZ,IAAI;QACJ,QAAQ;QACR,EAAE;AACF,QAAA,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;AAClC,QAAA,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;KAC7B;AACH;AA8IA,MAAM,iBAAiB,GAAG,CACxB,IAAQ;AAER;AACA,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,MAAM,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAqB;;;;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Type } from '../type.mjs';
|
|
2
|
-
export declare const recursion: <A>(typeName: string, definition: () => Type<A>, options?:
|
|
2
|
+
export declare const recursion: <A>(typeName: string, definition: () => Type<A>, options?: PartialReadonly<{
|
|
3
3
|
defaultValue: A;
|
|
4
|
-
}
|
|
4
|
+
}>) => Type<A>;
|
|
5
5
|
//# sourceMappingURL=recursion.d.mts.map
|