is-kit 1.8.1 → 1.9.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 CHANGED
@@ -186,7 +186,9 @@ const isConfig = struct({
186
186
 
187
187
  `optionalKey(guard)` means the property may be missing.
188
188
 
189
- Use `struct(schema, { exact: true })` when extra keys should be rejected.
189
+ Use `struct(schema, { exact: true })` when extra own enumerable string keys
190
+ should be rejected. Exact mode follows `Object.keys(...)` semantics, so symbol
191
+ keys and non-enumerable properties are outside its key matching.
190
192
 
191
193
  If the property must exist but the value may be `undefined`, use `optional(guard)` instead.
192
194
 
@@ -262,7 +264,39 @@ assert(isString, input, 'Expected a string');
262
264
  input.toUpperCase();
263
265
  ```
264
266
 
265
- ### 8. Narrow object keys
267
+ ### 8. Decode and validate JSON input
268
+
269
+ Use `safeJsonParse` at a JSON text boundary. It decodes the text, treats the
270
+ result as `unknown`, and only returns the value after the guard accepts it.
271
+ Invalid JSON and guard mismatches both return `{ valid: false }`; values are not
272
+ coerced to satisfy the guard.
273
+
274
+ ```ts
275
+ import { isString, safeJsonParse, typedStruct } from 'is-kit';
276
+
277
+ type User = {
278
+ id: string;
279
+ name: string;
280
+ };
281
+
282
+ const isUser = typedStruct<User>()({
283
+ id: isString,
284
+ name: isString
285
+ });
286
+
287
+ declare const input: string;
288
+ const result = safeJsonParse(input, isUser);
289
+
290
+ if (result.valid) {
291
+ result.value.name.toUpperCase();
292
+ }
293
+ ```
294
+
295
+ `safeJsonParse` is a decode-then-guard helper. It does not perform schema
296
+ coercion and does not depend on a transport or schema format such as HTTP or
297
+ OpenAPI.
298
+
299
+ ### 9. Narrow object keys
266
300
 
267
301
  Use key helpers when the important part of a value is one property.
268
302
 
@@ -312,7 +346,13 @@ Here are the kinds of problems `is-kit` is especially good at solving:
312
346
  ### Typed object guard checks
313
347
 
314
348
  ```ts
315
- import { isNumber, isString, optionalKey, safeParse, typedStruct } from 'is-kit';
349
+ import {
350
+ isNumber,
351
+ isString,
352
+ optionalKey,
353
+ safeParse,
354
+ typedStruct
355
+ } from 'is-kit';
316
356
 
317
357
  type PostResponse = ApiResponse<'/posts/{id}', 'get'>;
318
358
 
@@ -370,7 +410,7 @@ The library is organized around a few small building blocks:
370
410
  - **Collections**: `arrayOf`, `nonEmptyArrayOf`, `tupleOf`, `setOf`, `mapOf`, `recordOf`
371
411
  - **Literals**: `oneOfValues`, `equals`, `equalsBy`, `equalsKey`
372
412
  - **Nullish handling**: `nullable`, `nonNull`, `nullish`, `optional`, `required`
373
- - **Result helpers**: `safeParse`, `safeParseWith`, `assert`
413
+ - **Result helpers**: `safeParse`, `safeParseWith`, `safeJsonParse`, `assert`
374
414
 
375
415
  For the full API list and dedicated pages, use the docs site below.
376
416
 
package/dist/index.d.mts CHANGED
@@ -232,6 +232,14 @@ declare function safeParse(fn: (value: unknown) => boolean, value: unknown): Par
232
232
  */
233
233
  declare function safeParseWith<T>(guard: Guard<T>): (value: unknown) => ParseResult<T>;
234
234
  declare function safeParseWith<A, B extends A>(refine: Refine<A, B>): (value: A) => ParseResult<B>;
235
+ /**
236
+ * Decodes JSON text and validates the decoded value without coercion.
237
+ *
238
+ * @param input JSON text to decode.
239
+ * @param guard Guard used to validate the decoded `unknown` value.
240
+ * @returns The decoded value when valid; `{ valid: false }` for invalid JSON or a guard mismatch.
241
+ */
242
+ declare function safeJsonParse<T>(input: string, guard: Predicate<T>): ParseResult<T>;
235
243
 
236
244
  /**
237
245
  * Converts a boolean predicate into a refinement preserving the input type.
@@ -552,7 +560,8 @@ declare function optionalKey<G extends Predicate<unknown>>(guard: G): OptionalSc
552
560
  * rejects extra keys when `exact: true`.
553
561
  *
554
562
  * @param schema Record of property guards.
555
- * @param options When `{ exact: true }`, disallows properties not in `schema`.
563
+ * @param options When `{ exact: true }`, disallows own enumerable string-key
564
+ * properties not in `schema`.
556
565
  * @returns Predicate that narrows to the inferred struct type.
557
566
  */
558
567
  declare function struct<const S extends SchemaShape<S>>(schema: S, options?: {
@@ -644,4 +653,4 @@ declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPred
644
653
  */
645
654
  declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
646
655
 
647
- 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 };
656
+ 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, safeJsonParse, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf, typedStruct };
package/dist/index.d.ts CHANGED
@@ -232,6 +232,14 @@ declare function safeParse(fn: (value: unknown) => boolean, value: unknown): Par
232
232
  */
233
233
  declare function safeParseWith<T>(guard: Guard<T>): (value: unknown) => ParseResult<T>;
234
234
  declare function safeParseWith<A, B extends A>(refine: Refine<A, B>): (value: A) => ParseResult<B>;
235
+ /**
236
+ * Decodes JSON text and validates the decoded value without coercion.
237
+ *
238
+ * @param input JSON text to decode.
239
+ * @param guard Guard used to validate the decoded `unknown` value.
240
+ * @returns The decoded value when valid; `{ valid: false }` for invalid JSON or a guard mismatch.
241
+ */
242
+ declare function safeJsonParse<T>(input: string, guard: Predicate<T>): ParseResult<T>;
235
243
 
236
244
  /**
237
245
  * Converts a boolean predicate into a refinement preserving the input type.
@@ -552,7 +560,8 @@ declare function optionalKey<G extends Predicate<unknown>>(guard: G): OptionalSc
552
560
  * rejects extra keys when `exact: true`.
553
561
  *
554
562
  * @param schema Record of property guards.
555
- * @param options When `{ exact: true }`, disallows properties not in `schema`.
563
+ * @param options When `{ exact: true }`, disallows own enumerable string-key
564
+ * properties not in `schema`.
556
565
  * @returns Predicate that narrows to the inferred struct type.
557
566
  */
558
567
  declare function struct<const S extends SchemaShape<S>>(schema: S, options?: {
@@ -644,4 +653,4 @@ declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPred
644
653
  */
645
654
  declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
646
655
 
647
- 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 };
656
+ 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, safeJsonParse, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf, typedStruct };
package/dist/index.js CHANGED
@@ -88,6 +88,7 @@ __export(index_exports, {
88
88
  predicateToRefine: () => predicateToRefine,
89
89
  recordOf: () => recordOf,
90
90
  required: () => required,
91
+ safeJsonParse: () => safeJsonParse,
91
92
  safeParse: () => safeParse,
92
93
  safeParseWith: () => safeParseWith,
93
94
  setOf: () => setOf,
@@ -317,6 +318,15 @@ function safeParse(fn, value) {
317
318
  function safeParseWith(fn) {
318
319
  return (value) => safeParse(fn, value);
319
320
  }
321
+ function safeJsonParse(input, guard) {
322
+ let value;
323
+ try {
324
+ value = JSON.parse(input);
325
+ } catch {
326
+ return { valid: false };
327
+ }
328
+ return safeParse(guard, value);
329
+ }
320
330
 
321
331
  // src/core/predicate.ts
322
332
  var predicateToRefine = (fn) => (value) => fn(value);
@@ -565,6 +575,7 @@ function tupleOf(...guards) {
565
575
  predicateToRefine,
566
576
  recordOf,
567
577
  required,
578
+ safeJsonParse,
568
579
  safeParse,
569
580
  safeParseWith,
570
581
  setOf,
package/dist/index.mjs CHANGED
@@ -217,6 +217,15 @@ function safeParse(fn, value) {
217
217
  function safeParseWith(fn) {
218
218
  return (value) => safeParse(fn, value);
219
219
  }
220
+ function safeJsonParse(input, guard) {
221
+ let value;
222
+ try {
223
+ value = JSON.parse(input);
224
+ } catch {
225
+ return { valid: false };
226
+ }
227
+ return safeParse(guard, value);
228
+ }
220
229
 
221
230
  // src/core/predicate.ts
222
231
  var predicateToRefine = (fn) => (value) => fn(value);
@@ -464,6 +473,7 @@ export {
464
473
  predicateToRefine,
465
474
  recordOf,
466
475
  required,
476
+ safeJsonParse,
467
477
  safeParse,
468
478
  safeParseWith,
469
479
  setOf,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "is-kit",
3
- "version": "1.8.1",
3
+ "version": "1.9.0",
4
4
  "description": "Make 'isXXX' easier. Let's make your code type safe and more readable!",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -38,20 +38,21 @@
38
38
  "license": "MIT",
39
39
  "devDependencies": {
40
40
  "@types/jest": "^30.0.0",
41
- "jest": "^30.0.5",
42
- "lefthook": "^2.0.13",
43
- "oxfmt": "^0.52.0",
44
- "oxlint": "^1.67.0",
45
- "ts-jest": "^29.4.1",
41
+ "jest": "^30.4.2",
42
+ "lefthook": "^2.1.9",
43
+ "oxfmt": "^0.55.0",
44
+ "oxlint": "^1.70.0",
45
+ "ts-jest": "^29.4.11",
46
46
  "tsd": "^0.33.0",
47
47
  "tsup": "^8.5.0",
48
- "typedoc": "^0.28.12",
49
- "typescript": "^5.9.2"
48
+ "typedoc": "^0.28.19",
49
+ "typescript": "^6.0.3"
50
50
  },
51
51
  "tsd": {
52
52
  "directory": "tests-d",
53
53
  "compilerOptions": {
54
- "baseUrl": "."
54
+ "baseUrl": ".",
55
+ "ignoreDeprecations": "6.0"
55
56
  }
56
57
  },
57
58
  "scripts": {