is-kit 1.8.2 → 1.10.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 +61 -4
- package/dist/index.d.mts +20 -1
- package/dist/index.d.ts +20 -1
- package/dist/index.js +22 -0
- package/dist/index.mjs +20 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -116,6 +116,7 @@ This is the core idea of `is-kit`:
|
|
|
116
116
|
If you are new to the library, these are the pieces to remember:
|
|
117
117
|
|
|
118
118
|
- `define<T>(fn)` turns a boolean check into a typed guard.
|
|
119
|
+
- `lazy(factory)` defers a guard definition so recursive structures can refer to themselves.
|
|
119
120
|
- `predicateToRefine(fn)` upgrades an existing predicate so it can participate in narrowing chains.
|
|
120
121
|
- `struct({...})` builds an object-shape guard.
|
|
121
122
|
- `safeParse(guard, value)` gives you a small tagged result object.
|
|
@@ -224,7 +225,31 @@ import { oneOfValues } from 'is-kit';
|
|
|
224
225
|
const isStatus = oneOfValues('draft', 'published', 'archived');
|
|
225
226
|
```
|
|
226
227
|
|
|
227
|
-
### 6.
|
|
228
|
+
### 6. Validate recursive structures
|
|
229
|
+
|
|
230
|
+
Use `lazy` when a guard needs to refer to itself. The factory runs on first use,
|
|
231
|
+
and the resulting guard is cached.
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
import { arrayOf, isString, lazy, typedStruct } from 'is-kit';
|
|
235
|
+
import type { Predicate } from 'is-kit';
|
|
236
|
+
|
|
237
|
+
type Tree = {
|
|
238
|
+
readonly value: string;
|
|
239
|
+
readonly children: readonly Tree[];
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const isTree: Predicate<Tree> = lazy(() =>
|
|
243
|
+
typedStruct<Tree>()({
|
|
244
|
+
value: isString,
|
|
245
|
+
children: arrayOf(isTree)
|
|
246
|
+
})
|
|
247
|
+
);
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
`lazy` does not detect circular references in the input value.
|
|
251
|
+
|
|
252
|
+
### 7. Handle null and undefined explicitly
|
|
228
253
|
|
|
229
254
|
Use the nullish helpers to say exactly what is allowed.
|
|
230
255
|
|
|
@@ -245,7 +270,7 @@ const isDefinedString = required(optional(isString));
|
|
|
245
270
|
const isNonNullString = nonNull(nullable(isString));
|
|
246
271
|
```
|
|
247
272
|
|
|
248
|
-
###
|
|
273
|
+
### 8. Parse or assert unknown input
|
|
249
274
|
|
|
250
275
|
Use `safeParse` when you want a result object, and `assert` when invalid data should stop execution.
|
|
251
276
|
|
|
@@ -264,7 +289,39 @@ assert(isString, input, 'Expected a string');
|
|
|
264
289
|
input.toUpperCase();
|
|
265
290
|
```
|
|
266
291
|
|
|
267
|
-
###
|
|
292
|
+
### 9. Decode and validate JSON input
|
|
293
|
+
|
|
294
|
+
Use `safeJsonParse` at a JSON text boundary. It decodes the text, treats the
|
|
295
|
+
result as `unknown`, and only returns the value after the guard accepts it.
|
|
296
|
+
Invalid JSON and guard mismatches both return `{ valid: false }`; values are not
|
|
297
|
+
coerced to satisfy the guard.
|
|
298
|
+
|
|
299
|
+
```ts
|
|
300
|
+
import { isString, safeJsonParse, typedStruct } from 'is-kit';
|
|
301
|
+
|
|
302
|
+
type User = {
|
|
303
|
+
id: string;
|
|
304
|
+
name: string;
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const isUser = typedStruct<User>()({
|
|
308
|
+
id: isString,
|
|
309
|
+
name: isString
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
declare const input: string;
|
|
313
|
+
const result = safeJsonParse(input, isUser);
|
|
314
|
+
|
|
315
|
+
if (result.valid) {
|
|
316
|
+
result.value.name.toUpperCase();
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
`safeJsonParse` is a decode-then-guard helper. It does not perform schema
|
|
321
|
+
coercion and does not depend on a transport or schema format such as HTTP or
|
|
322
|
+
OpenAPI.
|
|
323
|
+
|
|
324
|
+
### 10. Narrow object keys
|
|
268
325
|
|
|
269
326
|
Use key helpers when the important part of a value is one property.
|
|
270
327
|
|
|
@@ -378,7 +435,7 @@ The library is organized around a few small building blocks:
|
|
|
378
435
|
- **Collections**: `arrayOf`, `nonEmptyArrayOf`, `tupleOf`, `setOf`, `mapOf`, `recordOf`
|
|
379
436
|
- **Literals**: `oneOfValues`, `equals`, `equalsBy`, `equalsKey`
|
|
380
437
|
- **Nullish handling**: `nullable`, `nonNull`, `nullish`, `optional`, `required`
|
|
381
|
-
- **Result helpers**: `safeParse`, `safeParseWith`, `assert`
|
|
438
|
+
- **Result helpers**: `safeParse`, `safeParseWith`, `safeJsonParse`, `assert`
|
|
382
439
|
|
|
383
440
|
For the full API list and dedicated pages, use the docs site below.
|
|
384
441
|
|
package/dist/index.d.mts
CHANGED
|
@@ -133,6 +133,17 @@ declare const hasKeys: <const KS extends readonly [PropertyKey, ...PropertyKey[]
|
|
|
133
133
|
*/
|
|
134
134
|
declare function narrowKeyTo<A, K extends keyof A>(guard: Guard<A>, key: K): <const T extends A[K]>(target: T) => Predicate<A & Record<K, T>>;
|
|
135
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Creates a predicate whose implementation is initialized on first use.
|
|
138
|
+
*
|
|
139
|
+
* The initialized predicate is cached after the factory returns successfully.
|
|
140
|
+
* Circular references in the input value are not detected.
|
|
141
|
+
*
|
|
142
|
+
* @param factory Function that creates the predicate when it is first evaluated.
|
|
143
|
+
* @returns Predicate that delegates to the lazily initialized implementation.
|
|
144
|
+
*/
|
|
145
|
+
declare function lazy<T>(factory: () => Predicate<T>): Predicate<T>;
|
|
146
|
+
|
|
136
147
|
/**
|
|
137
148
|
* Combines a precondition guard with an additional refinement to narrow the type.
|
|
138
149
|
*
|
|
@@ -232,6 +243,14 @@ declare function safeParse(fn: (value: unknown) => boolean, value: unknown): Par
|
|
|
232
243
|
*/
|
|
233
244
|
declare function safeParseWith<T>(guard: Guard<T>): (value: unknown) => ParseResult<T>;
|
|
234
245
|
declare function safeParseWith<A, B extends A>(refine: Refine<A, B>): (value: A) => ParseResult<B>;
|
|
246
|
+
/**
|
|
247
|
+
* Decodes JSON text and validates the decoded value without coercion.
|
|
248
|
+
*
|
|
249
|
+
* @param input JSON text to decode.
|
|
250
|
+
* @param guard Guard used to validate the decoded `unknown` value.
|
|
251
|
+
* @returns The decoded value when valid; `{ valid: false }` for invalid JSON or a guard mismatch.
|
|
252
|
+
*/
|
|
253
|
+
declare function safeJsonParse<T>(input: string, guard: Predicate<T>): ParseResult<T>;
|
|
235
254
|
|
|
236
255
|
/**
|
|
237
256
|
* Converts a boolean predicate into a refinement preserving the input type.
|
|
@@ -645,4 +664,4 @@ declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPred
|
|
|
645
664
|
*/
|
|
646
665
|
declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
|
|
647
666
|
|
|
648
|
-
export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OptionalSchemaField, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, type SchemaField, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, everyArrayValue, everyMapEntry, everyOwnEnumerableEntry, everySetValue, everyTupleValue, guardIn, hasKey, hasKeys, isArray, isArrayBuffer, isAsyncIterable, isBigInt, isBlob, isBoolean, isDataView, isDate, isError, isFiniteNumber, isFunction, isInfiniteNumber, isInstanceOf, isInteger, isIterable, isMap, isNaN, isNegative, isNull, isNumber, isNumberPrimitive, isObject, isPlainObject, isPositive, isPrimitive, isPromiseLike, isRegExp, isSafeInteger, isSet, isString, isSymbol, isTypedArray, isURL, isUndefined, isWeakMap, isWeakSet, isZero, mapOf, narrowKeyTo, nonEmptyArrayOf, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, optionalKey, or, predicateToRefine, recordOf, required, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf, typedStruct };
|
|
667
|
+
export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OptionalSchemaField, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, type SchemaField, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, everyArrayValue, everyMapEntry, everyOwnEnumerableEntry, everySetValue, everyTupleValue, guardIn, hasKey, hasKeys, isArray, isArrayBuffer, isAsyncIterable, isBigInt, isBlob, isBoolean, isDataView, isDate, isError, isFiniteNumber, isFunction, isInfiniteNumber, isInstanceOf, isInteger, isIterable, isMap, isNaN, isNegative, isNull, isNumber, isNumberPrimitive, isObject, isPlainObject, isPositive, isPrimitive, isPromiseLike, isRegExp, isSafeInteger, isSet, isString, isSymbol, isTypedArray, isURL, isUndefined, isWeakMap, isWeakSet, isZero, lazy, mapOf, narrowKeyTo, nonEmptyArrayOf, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, optionalKey, or, predicateToRefine, recordOf, required, safeJsonParse, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf, typedStruct };
|
package/dist/index.d.ts
CHANGED
|
@@ -133,6 +133,17 @@ declare const hasKeys: <const KS extends readonly [PropertyKey, ...PropertyKey[]
|
|
|
133
133
|
*/
|
|
134
134
|
declare function narrowKeyTo<A, K extends keyof A>(guard: Guard<A>, key: K): <const T extends A[K]>(target: T) => Predicate<A & Record<K, T>>;
|
|
135
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Creates a predicate whose implementation is initialized on first use.
|
|
138
|
+
*
|
|
139
|
+
* The initialized predicate is cached after the factory returns successfully.
|
|
140
|
+
* Circular references in the input value are not detected.
|
|
141
|
+
*
|
|
142
|
+
* @param factory Function that creates the predicate when it is first evaluated.
|
|
143
|
+
* @returns Predicate that delegates to the lazily initialized implementation.
|
|
144
|
+
*/
|
|
145
|
+
declare function lazy<T>(factory: () => Predicate<T>): Predicate<T>;
|
|
146
|
+
|
|
136
147
|
/**
|
|
137
148
|
* Combines a precondition guard with an additional refinement to narrow the type.
|
|
138
149
|
*
|
|
@@ -232,6 +243,14 @@ declare function safeParse(fn: (value: unknown) => boolean, value: unknown): Par
|
|
|
232
243
|
*/
|
|
233
244
|
declare function safeParseWith<T>(guard: Guard<T>): (value: unknown) => ParseResult<T>;
|
|
234
245
|
declare function safeParseWith<A, B extends A>(refine: Refine<A, B>): (value: A) => ParseResult<B>;
|
|
246
|
+
/**
|
|
247
|
+
* Decodes JSON text and validates the decoded value without coercion.
|
|
248
|
+
*
|
|
249
|
+
* @param input JSON text to decode.
|
|
250
|
+
* @param guard Guard used to validate the decoded `unknown` value.
|
|
251
|
+
* @returns The decoded value when valid; `{ valid: false }` for invalid JSON or a guard mismatch.
|
|
252
|
+
*/
|
|
253
|
+
declare function safeJsonParse<T>(input: string, guard: Predicate<T>): ParseResult<T>;
|
|
235
254
|
|
|
236
255
|
/**
|
|
237
256
|
* Converts a boolean predicate into a refinement preserving the input type.
|
|
@@ -645,4 +664,4 @@ declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPred
|
|
|
645
664
|
*/
|
|
646
665
|
declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
|
|
647
666
|
|
|
648
|
-
export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OptionalSchemaField, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, type SchemaField, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, everyArrayValue, everyMapEntry, everyOwnEnumerableEntry, everySetValue, everyTupleValue, guardIn, hasKey, hasKeys, isArray, isArrayBuffer, isAsyncIterable, isBigInt, isBlob, isBoolean, isDataView, isDate, isError, isFiniteNumber, isFunction, isInfiniteNumber, isInstanceOf, isInteger, isIterable, isMap, isNaN, isNegative, isNull, isNumber, isNumberPrimitive, isObject, isPlainObject, isPositive, isPrimitive, isPromiseLike, isRegExp, isSafeInteger, isSet, isString, isSymbol, isTypedArray, isURL, isUndefined, isWeakMap, isWeakSet, isZero, mapOf, narrowKeyTo, nonEmptyArrayOf, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, optionalKey, or, predicateToRefine, recordOf, required, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf, typedStruct };
|
|
667
|
+
export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OptionalSchemaField, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, type SchemaField, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, everyArrayValue, everyMapEntry, everyOwnEnumerableEntry, everySetValue, everyTupleValue, guardIn, hasKey, hasKeys, isArray, isArrayBuffer, isAsyncIterable, isBigInt, isBlob, isBoolean, isDataView, isDate, isError, isFiniteNumber, isFunction, isInfiniteNumber, isInstanceOf, isInteger, isIterable, isMap, isNaN, isNegative, isNull, isNumber, isNumberPrimitive, isObject, isPlainObject, isPositive, isPrimitive, isPromiseLike, isRegExp, isSafeInteger, isSet, isString, isSymbol, isTypedArray, isURL, isUndefined, isWeakMap, isWeakSet, isZero, lazy, mapOf, narrowKeyTo, nonEmptyArrayOf, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, optionalKey, or, predicateToRefine, recordOf, required, safeJsonParse, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf, typedStruct };
|
package/dist/index.js
CHANGED
|
@@ -73,6 +73,7 @@ __export(index_exports, {
|
|
|
73
73
|
isWeakMap: () => isWeakMap,
|
|
74
74
|
isWeakSet: () => isWeakSet,
|
|
75
75
|
isZero: () => isZero,
|
|
76
|
+
lazy: () => lazy,
|
|
76
77
|
mapOf: () => mapOf,
|
|
77
78
|
narrowKeyTo: () => narrowKeyTo,
|
|
78
79
|
nonEmptyArrayOf: () => nonEmptyArrayOf,
|
|
@@ -88,6 +89,7 @@ __export(index_exports, {
|
|
|
88
89
|
predicateToRefine: () => predicateToRefine,
|
|
89
90
|
recordOf: () => recordOf,
|
|
90
91
|
required: () => required,
|
|
92
|
+
safeJsonParse: () => safeJsonParse,
|
|
91
93
|
safeParse: () => safeParse,
|
|
92
94
|
safeParseWith: () => safeParseWith,
|
|
93
95
|
setOf: () => setOf,
|
|
@@ -219,6 +221,15 @@ function narrowKeyTo(guard, key) {
|
|
|
219
221
|
};
|
|
220
222
|
}
|
|
221
223
|
|
|
224
|
+
// src/core/lazy.ts
|
|
225
|
+
function lazy(factory) {
|
|
226
|
+
let predicate;
|
|
227
|
+
return (value) => {
|
|
228
|
+
predicate ??= factory();
|
|
229
|
+
return predicate(value);
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
222
233
|
// src/utils/guard-collections.ts
|
|
223
234
|
var everyArrayValue = (values, predicate) => {
|
|
224
235
|
for (const value of values) {
|
|
@@ -317,6 +328,15 @@ function safeParse(fn, value) {
|
|
|
317
328
|
function safeParseWith(fn) {
|
|
318
329
|
return (value) => safeParse(fn, value);
|
|
319
330
|
}
|
|
331
|
+
function safeJsonParse(input, guard) {
|
|
332
|
+
let value;
|
|
333
|
+
try {
|
|
334
|
+
value = JSON.parse(input);
|
|
335
|
+
} catch {
|
|
336
|
+
return { valid: false };
|
|
337
|
+
}
|
|
338
|
+
return safeParse(guard, value);
|
|
339
|
+
}
|
|
320
340
|
|
|
321
341
|
// src/core/predicate.ts
|
|
322
342
|
var predicateToRefine = (fn) => (value) => fn(value);
|
|
@@ -550,6 +570,7 @@ function tupleOf(...guards) {
|
|
|
550
570
|
isWeakMap,
|
|
551
571
|
isWeakSet,
|
|
552
572
|
isZero,
|
|
573
|
+
lazy,
|
|
553
574
|
mapOf,
|
|
554
575
|
narrowKeyTo,
|
|
555
576
|
nonEmptyArrayOf,
|
|
@@ -565,6 +586,7 @@ function tupleOf(...guards) {
|
|
|
565
586
|
predicateToRefine,
|
|
566
587
|
recordOf,
|
|
567
588
|
required,
|
|
589
|
+
safeJsonParse,
|
|
568
590
|
safeParse,
|
|
569
591
|
safeParseWith,
|
|
570
592
|
setOf,
|
package/dist/index.mjs
CHANGED
|
@@ -119,6 +119,15 @@ function narrowKeyTo(guard, key) {
|
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
// src/core/lazy.ts
|
|
123
|
+
function lazy(factory) {
|
|
124
|
+
let predicate;
|
|
125
|
+
return (value) => {
|
|
126
|
+
predicate ??= factory();
|
|
127
|
+
return predicate(value);
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
122
131
|
// src/utils/guard-collections.ts
|
|
123
132
|
var everyArrayValue = (values, predicate) => {
|
|
124
133
|
for (const value of values) {
|
|
@@ -217,6 +226,15 @@ function safeParse(fn, value) {
|
|
|
217
226
|
function safeParseWith(fn) {
|
|
218
227
|
return (value) => safeParse(fn, value);
|
|
219
228
|
}
|
|
229
|
+
function safeJsonParse(input, guard) {
|
|
230
|
+
let value;
|
|
231
|
+
try {
|
|
232
|
+
value = JSON.parse(input);
|
|
233
|
+
} catch {
|
|
234
|
+
return { valid: false };
|
|
235
|
+
}
|
|
236
|
+
return safeParse(guard, value);
|
|
237
|
+
}
|
|
220
238
|
|
|
221
239
|
// src/core/predicate.ts
|
|
222
240
|
var predicateToRefine = (fn) => (value) => fn(value);
|
|
@@ -449,6 +467,7 @@ export {
|
|
|
449
467
|
isWeakMap,
|
|
450
468
|
isWeakSet,
|
|
451
469
|
isZero,
|
|
470
|
+
lazy,
|
|
452
471
|
mapOf,
|
|
453
472
|
narrowKeyTo,
|
|
454
473
|
nonEmptyArrayOf,
|
|
@@ -464,6 +483,7 @@ export {
|
|
|
464
483
|
predicateToRefine,
|
|
465
484
|
recordOf,
|
|
466
485
|
required,
|
|
486
|
+
safeJsonParse,
|
|
467
487
|
safeParse,
|
|
468
488
|
safeParseWith,
|
|
469
489
|
setOf,
|