is-kit 1.6.3 → 1.7.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
@@ -166,7 +166,7 @@ Use `not(...)` when you want the complement of an existing guard or refinement.
166
166
  Use `struct` for plain-object payloads. Keys are required by default.
167
167
 
168
168
  ```ts
169
- import { isNumber, isString, optionalKey, struct } from 'is-kit';
169
+ import { isNumber, isString, optional, optionalKey, struct } from 'is-kit';
170
170
 
171
171
  const isProfile = struct(
172
172
  {
@@ -176,14 +176,6 @@ const isProfile = struct(
176
176
  },
177
177
  { exact: true }
178
178
  );
179
- ```
180
-
181
- `optionalKey(guard)` means the property may be missing.
182
-
183
- If the property must exist but the value may be `undefined`, use `optional(guard)` instead.
184
-
185
- ```ts
186
- import { isString, optional, optionalKey, struct } from 'is-kit';
187
179
 
188
180
  const isConfig = struct({
189
181
  label: isString,
@@ -192,6 +184,12 @@ const isConfig = struct({
192
184
  });
193
185
  ```
194
186
 
187
+ `optionalKey(guard)` means the property may be missing.
188
+
189
+ Use `struct(schema, { exact: true })` when extra keys should be rejected.
190
+
191
+ If the property must exist but the value may be `undefined`, use `optional(guard)` instead.
192
+
195
193
  ### 5. Validate arrays, tuples, maps, sets, and records
196
194
 
197
195
  Collection combinators keep your element guards reusable.
@@ -202,12 +200,14 @@ import {
202
200
  isNumber,
203
201
  isString,
204
202
  mapOf,
203
+ nonEmptyArrayOf,
205
204
  recordOf,
206
205
  setOf,
207
206
  tupleOf
208
207
  } from 'is-kit';
209
208
 
210
209
  const isStringArray = arrayOf(isString);
210
+ const isNonEmptyTagList = nonEmptyArrayOf(isString);
211
211
  const isPoint = tupleOf(isNumber, isNumber);
212
212
  const isTagSet = setOf(isString);
213
213
  const isScoreMap = mapOf(isString, isNumber);
@@ -356,7 +356,7 @@ The library is organized around a few small building blocks:
356
356
  - **Primitives**: `isString`, `isNumber`, `isBoolean`, `isInteger`, ...
357
357
  - **Composition**: `define`, `and`, `andAll`, `or`, `not`, `oneOf`
358
358
  - **Object shapes**: `struct`, `optionalKey`, `hasKey`, `hasKeys`, `narrowKeyTo`
359
- - **Collections**: `arrayOf`, `tupleOf`, `setOf`, `mapOf`, `recordOf`
359
+ - **Collections**: `arrayOf`, `nonEmptyArrayOf`, `tupleOf`, `setOf`, `mapOf`, `recordOf`
360
360
  - **Literals**: `oneOfValues`, `equals`, `equalsBy`, `equalsKey`
361
361
  - **Nullish handling**: `nullable`, `nonNull`, `nullish`, `optional`, `required`
362
362
  - **Result helpers**: `safeParse`, `safeParseWith`, `assert`
package/dist/index.d.mts CHANGED
@@ -324,6 +324,13 @@ declare const isPrimitive: Guard<string | number | bigint | boolean | symbol | n
324
324
  * @returns Predicate narrowing to a readonly array of the guarded element type.
325
325
  */
326
326
  declare function arrayOf<F extends Predicate<unknown>>(elementGuard: F): Predicate<readonly GuardedOf<F>[]>;
327
+ /**
328
+ * Validates a non-empty array where every element satisfies the provided guard.
329
+ *
330
+ * @param elementGuard Guard applied to each array element.
331
+ * @returns Predicate narrowing to a readonly non-empty array of the guarded element type.
332
+ */
333
+ declare function nonEmptyArrayOf<F extends Predicate<unknown>>(elementGuard: F): Predicate<readonly [GuardedOf<F>, ...GuardedOf<F>[]]>;
327
334
 
328
335
  /**
329
336
  * Validates a set where every value satisfies the provided guard.
@@ -555,6 +562,49 @@ declare const hasKeys: <const KS extends readonly [PropertyKey, ...PropertyKey[]
555
562
  */
556
563
  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>>;
557
564
 
565
+ /**
566
+ * Checks whether every array element satisfies the provided predicate.
567
+ *
568
+ * @param values Array values to validate.
569
+ * @param predicate Predicate applied to each element.
570
+ * @returns Whether all elements satisfy `predicate`.
571
+ */
572
+ declare const everyArrayValue: (values: readonly unknown[], predicate: (value: unknown) => boolean) => boolean;
573
+ /**
574
+ * Checks whether a tuple matches the provided element predicates in order.
575
+ *
576
+ * @param values Tuple candidate values.
577
+ * @param predicates Predicates aligned to each tuple index.
578
+ * @returns Whether lengths match and each index passes.
579
+ */
580
+ declare const everyTupleValue: (values: readonly unknown[], predicates: readonly ((value: unknown) => boolean)[]) => boolean;
581
+ /**
582
+ * Checks whether every set value satisfies the provided predicate.
583
+ *
584
+ * @param values Set values to validate.
585
+ * @param predicate Predicate applied to each value.
586
+ * @returns Whether all set values satisfy `predicate`.
587
+ */
588
+ declare const everySetValue: (values: ReadonlySet<unknown>, predicate: (value: unknown) => boolean) => boolean;
589
+ /**
590
+ * Checks whether every map entry satisfies the provided key and value predicates.
591
+ *
592
+ * @param values Map values to validate.
593
+ * @param keyPredicate Predicate applied to each key.
594
+ * @param valuePredicate Predicate applied to each value.
595
+ * @returns Whether all keys and values satisfy their predicates.
596
+ */
597
+ declare const everyMapEntry: (values: ReadonlyMap<unknown, unknown>, keyPredicate: (key: unknown) => boolean, valuePredicate: (value: unknown) => boolean) => boolean;
598
+ /**
599
+ * Checks whether every own enumerable string key/value pair satisfies the provided predicates.
600
+ *
601
+ * @param values Plain object values to validate.
602
+ * @param keyPredicate Predicate applied to each enumerable own string key.
603
+ * @param valuePredicate Predicate applied to each corresponding value.
604
+ * @returns Whether all enumerable entries satisfy their predicates.
605
+ */
606
+ declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPredicate: (key: string) => boolean, valuePredicate: (value: unknown) => boolean) => boolean;
607
+
558
608
  /**
559
609
  * Converts predicates to plain boolean predicates for iteration helpers.
560
610
  *
@@ -563,4 +613,4 @@ declare function narrowKeyTo<A, K extends keyof A>(guard: Guard<A>, key: K): <co
563
613
  */
564
614
  declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
565
615
 
566
- 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, 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, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, optionalKey, or, predicateToRefine, recordOf, required, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf };
616
+ 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 };
package/dist/index.d.ts CHANGED
@@ -324,6 +324,13 @@ declare const isPrimitive: Guard<string | number | bigint | boolean | symbol | n
324
324
  * @returns Predicate narrowing to a readonly array of the guarded element type.
325
325
  */
326
326
  declare function arrayOf<F extends Predicate<unknown>>(elementGuard: F): Predicate<readonly GuardedOf<F>[]>;
327
+ /**
328
+ * Validates a non-empty array where every element satisfies the provided guard.
329
+ *
330
+ * @param elementGuard Guard applied to each array element.
331
+ * @returns Predicate narrowing to a readonly non-empty array of the guarded element type.
332
+ */
333
+ declare function nonEmptyArrayOf<F extends Predicate<unknown>>(elementGuard: F): Predicate<readonly [GuardedOf<F>, ...GuardedOf<F>[]]>;
327
334
 
328
335
  /**
329
336
  * Validates a set where every value satisfies the provided guard.
@@ -555,6 +562,49 @@ declare const hasKeys: <const KS extends readonly [PropertyKey, ...PropertyKey[]
555
562
  */
556
563
  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>>;
557
564
 
565
+ /**
566
+ * Checks whether every array element satisfies the provided predicate.
567
+ *
568
+ * @param values Array values to validate.
569
+ * @param predicate Predicate applied to each element.
570
+ * @returns Whether all elements satisfy `predicate`.
571
+ */
572
+ declare const everyArrayValue: (values: readonly unknown[], predicate: (value: unknown) => boolean) => boolean;
573
+ /**
574
+ * Checks whether a tuple matches the provided element predicates in order.
575
+ *
576
+ * @param values Tuple candidate values.
577
+ * @param predicates Predicates aligned to each tuple index.
578
+ * @returns Whether lengths match and each index passes.
579
+ */
580
+ declare const everyTupleValue: (values: readonly unknown[], predicates: readonly ((value: unknown) => boolean)[]) => boolean;
581
+ /**
582
+ * Checks whether every set value satisfies the provided predicate.
583
+ *
584
+ * @param values Set values to validate.
585
+ * @param predicate Predicate applied to each value.
586
+ * @returns Whether all set values satisfy `predicate`.
587
+ */
588
+ declare const everySetValue: (values: ReadonlySet<unknown>, predicate: (value: unknown) => boolean) => boolean;
589
+ /**
590
+ * Checks whether every map entry satisfies the provided key and value predicates.
591
+ *
592
+ * @param values Map values to validate.
593
+ * @param keyPredicate Predicate applied to each key.
594
+ * @param valuePredicate Predicate applied to each value.
595
+ * @returns Whether all keys and values satisfy their predicates.
596
+ */
597
+ declare const everyMapEntry: (values: ReadonlyMap<unknown, unknown>, keyPredicate: (key: unknown) => boolean, valuePredicate: (value: unknown) => boolean) => boolean;
598
+ /**
599
+ * Checks whether every own enumerable string key/value pair satisfies the provided predicates.
600
+ *
601
+ * @param values Plain object values to validate.
602
+ * @param keyPredicate Predicate applied to each enumerable own string key.
603
+ * @param valuePredicate Predicate applied to each corresponding value.
604
+ * @returns Whether all enumerable entries satisfy their predicates.
605
+ */
606
+ declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPredicate: (key: string) => boolean, valuePredicate: (value: unknown) => boolean) => boolean;
607
+
558
608
  /**
559
609
  * Converts predicates to plain boolean predicates for iteration helpers.
560
610
  *
@@ -563,4 +613,4 @@ declare function narrowKeyTo<A, K extends keyof A>(guard: Guard<A>, key: K): <co
563
613
  */
564
614
  declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
565
615
 
566
- 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, 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, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, optionalKey, or, predicateToRefine, recordOf, required, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf };
616
+ 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 };
package/dist/index.js CHANGED
@@ -28,6 +28,11 @@ __export(index_exports, {
28
28
  equals: () => equals,
29
29
  equalsBy: () => equalsBy,
30
30
  equalsKey: () => equalsKey,
31
+ everyArrayValue: () => everyArrayValue,
32
+ everyMapEntry: () => everyMapEntry,
33
+ everyOwnEnumerableEntry: () => everyOwnEnumerableEntry,
34
+ everySetValue: () => everySetValue,
35
+ everyTupleValue: () => everyTupleValue,
31
36
  guardIn: () => guardIn,
32
37
  hasKey: () => hasKey,
33
38
  hasKeys: () => hasKeys,
@@ -70,6 +75,7 @@ __export(index_exports, {
70
75
  isZero: () => isZero,
71
76
  mapOf: () => mapOf,
72
77
  narrowKeyTo: () => narrowKeyTo,
78
+ nonEmptyArrayOf: () => nonEmptyArrayOf,
73
79
  nonNull: () => nonNull,
74
80
  not: () => not,
75
81
  nullable: () => nullable,
@@ -106,6 +112,39 @@ function assert(fn, value, message) {
106
112
  throw new Error(message ?? DEFAULT_ASSERT_MESSAGE);
107
113
  }
108
114
 
115
+ // src/utils/guard-collections.ts
116
+ var everyArrayValue = (values, predicate) => {
117
+ for (const value of values) {
118
+ if (!predicate(value)) return false;
119
+ }
120
+ return true;
121
+ };
122
+ var everyTupleValue = (values, predicates) => {
123
+ if (values.length !== predicates.length) return false;
124
+ for (const [index, predicate] of predicates.entries()) {
125
+ if (!predicate(values[index])) return false;
126
+ }
127
+ return true;
128
+ };
129
+ var everySetValue = (values, predicate) => {
130
+ for (const value of values) {
131
+ if (!predicate(value)) return false;
132
+ }
133
+ return true;
134
+ };
135
+ var everyMapEntry = (values, keyPredicate, valuePredicate) => {
136
+ for (const [key, value] of values) {
137
+ if (!keyPredicate(key) || !valuePredicate(value)) return false;
138
+ }
139
+ return true;
140
+ };
141
+ var everyOwnEnumerableEntry = (values, keyPredicate, valuePredicate) => {
142
+ for (const key of Object.keys(values)) {
143
+ if (!keyPredicate(key) || !valuePredicate(values[key])) return false;
144
+ }
145
+ return true;
146
+ };
147
+
109
148
  // src/utils/to-boolean-predicates.ts
110
149
  var toBooleanPredicates = (predicates) => predicates;
111
150
 
@@ -145,20 +184,22 @@ function applyRefinements(value, steps) {
145
184
  }
146
185
 
147
186
  // src/core/nullish.ts
187
+ var allowWhen = (acceptedValue, predicate) => (value) => acceptedValue(value) || predicate(value);
188
+ var requireWhen = (rejectedValue, predicate) => (value) => !rejectedValue(value) && predicate(value);
148
189
  function nullable(fn) {
149
- return (value) => value === null || fn(value);
190
+ return allowWhen((value) => value === null, fn);
150
191
  }
151
192
  function nonNull(fn) {
152
- return (value) => value !== null && fn(value);
193
+ return requireWhen((value) => value === null, fn);
153
194
  }
154
195
  function nullish(fn) {
155
- return (value) => value == null || fn(value);
196
+ return allowWhen((value) => value == null, fn);
156
197
  }
157
198
  function optional(fn) {
158
- return (value) => value === void 0 || fn(value);
199
+ return allowWhen((value) => value === void 0, fn);
159
200
  }
160
201
  function required(fn) {
161
- return (value) => value !== void 0 && fn(value);
202
+ return requireWhen((value) => value === void 0, fn);
162
203
  }
163
204
 
164
205
  // src/utils/object-tags.ts
@@ -251,7 +292,7 @@ function equalsBy(guard, selector) {
251
292
  }
252
293
  function equalsKey(key, target) {
253
294
  const hasMatchingKey = define((input) => {
254
- return isObject(input) && Object.prototype.hasOwnProperty.call(input, key) && Object.is(input[key], target);
295
+ return isObject(input) && Object.hasOwn(input, key) && Object.is(input[key], target);
255
296
  });
256
297
  return (input) => hasMatchingKey(input);
257
298
  }
@@ -308,69 +349,50 @@ var isPrimitive = or(
308
349
 
309
350
  // src/core/combinators/array.ts
310
351
  function arrayOf(elementGuard) {
311
- return define((input) => {
312
- if (!Array.isArray(input)) return false;
313
- for (const element of input) {
314
- if (!elementGuard(element)) return false;
315
- }
316
- return true;
317
- });
352
+ return define(
353
+ (input) => Array.isArray(input) && everyArrayValue(input, elementGuard)
354
+ );
355
+ }
356
+ function nonEmptyArrayOf(elementGuard) {
357
+ return define(
358
+ (input) => Array.isArray(input) && input.length > 0 && everyArrayValue(input, elementGuard)
359
+ );
318
360
  }
319
361
 
320
362
  // src/core/combinators/set.ts
321
363
  function setOf(valueGuard) {
322
- return define((input) => {
323
- if (!isSet(input)) return false;
324
- for (const value of input.values()) {
325
- if (!valueGuard(value)) return false;
326
- }
327
- return true;
328
- });
364
+ return define(
365
+ (input) => isSet(input) && everySetValue(input, valueGuard)
366
+ );
329
367
  }
330
368
 
331
369
  // src/core/combinators/map.ts
332
370
  function mapOf(keyGuard, valueGuard) {
333
- return define((input) => {
334
- if (!isMap(input)) return false;
335
- for (const [key, value] of input.entries()) {
336
- if (!keyGuard(key)) return false;
337
- if (!valueGuard(value)) return false;
338
- }
339
- return true;
340
- });
371
+ return define(
372
+ (input) => isMap(input) && everyMapEntry(input, keyGuard, valueGuard)
373
+ );
341
374
  }
342
375
 
343
376
  // src/core/combinators/tuple.ts
344
377
  function tupleOf(...guards) {
345
- return define((input) => {
346
- return Array.isArray(input) && input.length === guards.length && guards.every(
347
- (guard, index) => guard(input[index])
348
- );
349
- });
378
+ return define(
379
+ (input) => Array.isArray(input) && everyTupleValue(input, guards)
380
+ );
350
381
  }
351
382
 
352
383
  // src/core/combinators/one-of.ts
353
384
  function oneOf(...guards) {
354
- const predicates = toBooleanPredicates(guards);
355
- return (input) => predicates.some((guard) => guard(input));
385
+ return or(...guards);
356
386
  }
357
387
 
358
388
  // src/core/combinators/record.ts
359
389
  function recordOf(keyFunction, valueFunction) {
360
- return (input) => {
361
- if (!isPlainObject(input)) return false;
362
- const obj = input;
363
- for (const key of Object.keys(obj)) {
364
- if (!keyFunction(key)) return false;
365
- const value = obj[key];
366
- if (!valueFunction(value)) return false;
367
- }
368
- return true;
369
- };
390
+ return define(
391
+ (input) => isPlainObject(input) && everyOwnEnumerableEntry(input, keyFunction, valueFunction)
392
+ );
370
393
  }
371
394
 
372
395
  // src/core/combinators/struct.ts
373
- var hasOwnKey = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
374
396
  var isOptionalSchemaField = define(
375
397
  // WHY: Optional fields are represented as a small tagged object so `struct`
376
398
  // can distinguish schema metadata from plain predicate functions up front.
@@ -379,12 +401,12 @@ var isOptionalSchemaField = define(
379
401
  var hasRequiredKeys = (obj, entries) => (
380
402
  // WHY: Required fields must be own properties; inherited values should not
381
403
  // satisfy a schema because `struct` models object payload shape, not prototype chains.
382
- entries.every(([key, guard]) => hasOwnKey(obj, key) && guard(obj[key]))
404
+ entries.every(([key, guard]) => Object.hasOwn(obj, key) && guard(obj[key]))
383
405
  );
384
406
  var hasValidOptionalKeys = (obj, entries) => (
385
407
  // WHY: Optional keys are validated only when present. Missing keys stay valid
386
408
  // without forcing callers to encode `undefined` into the value guard.
387
- entries.every(([key, guard]) => !hasOwnKey(obj, key) || guard(obj[key]))
409
+ entries.every(([key, guard]) => !Object.hasOwn(obj, key) || guard(obj[key]))
388
410
  );
389
411
  var hasOnlyAllowedKeys = (obj, allowed) => Object.keys(obj).every((key) => allowed.has(key));
390
412
  function optionalKey(guard) {
@@ -450,14 +472,14 @@ function oneOfValues(...args) {
450
472
 
451
473
  // src/core/key.ts
452
474
  var hasKey = (key) => define(
453
- (input) => isObject(input) && Object.prototype.hasOwnProperty.call(input, key)
475
+ (input) => isObject(input) && Object.hasOwn(input, key)
454
476
  );
455
477
  var hasKeys = (...keys) => {
456
478
  if (keys.length === 0) {
457
479
  return define(() => false);
458
480
  }
459
481
  return define(
460
- (input) => isObject(input) && keys.every((key) => Object.prototype.hasOwnProperty.call(input, key))
482
+ (input) => isObject(input) && keys.every((key) => Object.hasOwn(input, key))
461
483
  );
462
484
  };
463
485
  function narrowKeyTo(guard, key) {
@@ -478,6 +500,11 @@ function narrowKeyTo(guard, key) {
478
500
  equals,
479
501
  equalsBy,
480
502
  equalsKey,
503
+ everyArrayValue,
504
+ everyMapEntry,
505
+ everyOwnEnumerableEntry,
506
+ everySetValue,
507
+ everyTupleValue,
481
508
  guardIn,
482
509
  hasKey,
483
510
  hasKeys,
@@ -520,6 +547,7 @@ function narrowKeyTo(guard, key) {
520
547
  isZero,
521
548
  mapOf,
522
549
  narrowKeyTo,
550
+ nonEmptyArrayOf,
523
551
  nonNull,
524
552
  not,
525
553
  nullable,
package/dist/index.mjs CHANGED
@@ -13,6 +13,39 @@ function assert(fn, value, message) {
13
13
  throw new Error(message ?? DEFAULT_ASSERT_MESSAGE);
14
14
  }
15
15
 
16
+ // src/utils/guard-collections.ts
17
+ var everyArrayValue = (values, predicate) => {
18
+ for (const value of values) {
19
+ if (!predicate(value)) return false;
20
+ }
21
+ return true;
22
+ };
23
+ var everyTupleValue = (values, predicates) => {
24
+ if (values.length !== predicates.length) return false;
25
+ for (const [index, predicate] of predicates.entries()) {
26
+ if (!predicate(values[index])) return false;
27
+ }
28
+ return true;
29
+ };
30
+ var everySetValue = (values, predicate) => {
31
+ for (const value of values) {
32
+ if (!predicate(value)) return false;
33
+ }
34
+ return true;
35
+ };
36
+ var everyMapEntry = (values, keyPredicate, valuePredicate) => {
37
+ for (const [key, value] of values) {
38
+ if (!keyPredicate(key) || !valuePredicate(value)) return false;
39
+ }
40
+ return true;
41
+ };
42
+ var everyOwnEnumerableEntry = (values, keyPredicate, valuePredicate) => {
43
+ for (const key of Object.keys(values)) {
44
+ if (!keyPredicate(key) || !valuePredicate(values[key])) return false;
45
+ }
46
+ return true;
47
+ };
48
+
16
49
  // src/utils/to-boolean-predicates.ts
17
50
  var toBooleanPredicates = (predicates) => predicates;
18
51
 
@@ -52,20 +85,22 @@ function applyRefinements(value, steps) {
52
85
  }
53
86
 
54
87
  // src/core/nullish.ts
88
+ var allowWhen = (acceptedValue, predicate) => (value) => acceptedValue(value) || predicate(value);
89
+ var requireWhen = (rejectedValue, predicate) => (value) => !rejectedValue(value) && predicate(value);
55
90
  function nullable(fn) {
56
- return (value) => value === null || fn(value);
91
+ return allowWhen((value) => value === null, fn);
57
92
  }
58
93
  function nonNull(fn) {
59
- return (value) => value !== null && fn(value);
94
+ return requireWhen((value) => value === null, fn);
60
95
  }
61
96
  function nullish(fn) {
62
- return (value) => value == null || fn(value);
97
+ return allowWhen((value) => value == null, fn);
63
98
  }
64
99
  function optional(fn) {
65
- return (value) => value === void 0 || fn(value);
100
+ return allowWhen((value) => value === void 0, fn);
66
101
  }
67
102
  function required(fn) {
68
- return (value) => value !== void 0 && fn(value);
103
+ return requireWhen((value) => value === void 0, fn);
69
104
  }
70
105
 
71
106
  // src/utils/object-tags.ts
@@ -158,7 +193,7 @@ function equalsBy(guard, selector) {
158
193
  }
159
194
  function equalsKey(key, target) {
160
195
  const hasMatchingKey = define((input) => {
161
- return isObject(input) && Object.prototype.hasOwnProperty.call(input, key) && Object.is(input[key], target);
196
+ return isObject(input) && Object.hasOwn(input, key) && Object.is(input[key], target);
162
197
  });
163
198
  return (input) => hasMatchingKey(input);
164
199
  }
@@ -215,69 +250,50 @@ var isPrimitive = or(
215
250
 
216
251
  // src/core/combinators/array.ts
217
252
  function arrayOf(elementGuard) {
218
- return define((input) => {
219
- if (!Array.isArray(input)) return false;
220
- for (const element of input) {
221
- if (!elementGuard(element)) return false;
222
- }
223
- return true;
224
- });
253
+ return define(
254
+ (input) => Array.isArray(input) && everyArrayValue(input, elementGuard)
255
+ );
256
+ }
257
+ function nonEmptyArrayOf(elementGuard) {
258
+ return define(
259
+ (input) => Array.isArray(input) && input.length > 0 && everyArrayValue(input, elementGuard)
260
+ );
225
261
  }
226
262
 
227
263
  // src/core/combinators/set.ts
228
264
  function setOf(valueGuard) {
229
- return define((input) => {
230
- if (!isSet(input)) return false;
231
- for (const value of input.values()) {
232
- if (!valueGuard(value)) return false;
233
- }
234
- return true;
235
- });
265
+ return define(
266
+ (input) => isSet(input) && everySetValue(input, valueGuard)
267
+ );
236
268
  }
237
269
 
238
270
  // src/core/combinators/map.ts
239
271
  function mapOf(keyGuard, valueGuard) {
240
- return define((input) => {
241
- if (!isMap(input)) return false;
242
- for (const [key, value] of input.entries()) {
243
- if (!keyGuard(key)) return false;
244
- if (!valueGuard(value)) return false;
245
- }
246
- return true;
247
- });
272
+ return define(
273
+ (input) => isMap(input) && everyMapEntry(input, keyGuard, valueGuard)
274
+ );
248
275
  }
249
276
 
250
277
  // src/core/combinators/tuple.ts
251
278
  function tupleOf(...guards) {
252
- return define((input) => {
253
- return Array.isArray(input) && input.length === guards.length && guards.every(
254
- (guard, index) => guard(input[index])
255
- );
256
- });
279
+ return define(
280
+ (input) => Array.isArray(input) && everyTupleValue(input, guards)
281
+ );
257
282
  }
258
283
 
259
284
  // src/core/combinators/one-of.ts
260
285
  function oneOf(...guards) {
261
- const predicates = toBooleanPredicates(guards);
262
- return (input) => predicates.some((guard) => guard(input));
286
+ return or(...guards);
263
287
  }
264
288
 
265
289
  // src/core/combinators/record.ts
266
290
  function recordOf(keyFunction, valueFunction) {
267
- return (input) => {
268
- if (!isPlainObject(input)) return false;
269
- const obj = input;
270
- for (const key of Object.keys(obj)) {
271
- if (!keyFunction(key)) return false;
272
- const value = obj[key];
273
- if (!valueFunction(value)) return false;
274
- }
275
- return true;
276
- };
291
+ return define(
292
+ (input) => isPlainObject(input) && everyOwnEnumerableEntry(input, keyFunction, valueFunction)
293
+ );
277
294
  }
278
295
 
279
296
  // src/core/combinators/struct.ts
280
- var hasOwnKey = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
281
297
  var isOptionalSchemaField = define(
282
298
  // WHY: Optional fields are represented as a small tagged object so `struct`
283
299
  // can distinguish schema metadata from plain predicate functions up front.
@@ -286,12 +302,12 @@ var isOptionalSchemaField = define(
286
302
  var hasRequiredKeys = (obj, entries) => (
287
303
  // WHY: Required fields must be own properties; inherited values should not
288
304
  // satisfy a schema because `struct` models object payload shape, not prototype chains.
289
- entries.every(([key, guard]) => hasOwnKey(obj, key) && guard(obj[key]))
305
+ entries.every(([key, guard]) => Object.hasOwn(obj, key) && guard(obj[key]))
290
306
  );
291
307
  var hasValidOptionalKeys = (obj, entries) => (
292
308
  // WHY: Optional keys are validated only when present. Missing keys stay valid
293
309
  // without forcing callers to encode `undefined` into the value guard.
294
- entries.every(([key, guard]) => !hasOwnKey(obj, key) || guard(obj[key]))
310
+ entries.every(([key, guard]) => !Object.hasOwn(obj, key) || guard(obj[key]))
295
311
  );
296
312
  var hasOnlyAllowedKeys = (obj, allowed) => Object.keys(obj).every((key) => allowed.has(key));
297
313
  function optionalKey(guard) {
@@ -357,14 +373,14 @@ function oneOfValues(...args) {
357
373
 
358
374
  // src/core/key.ts
359
375
  var hasKey = (key) => define(
360
- (input) => isObject(input) && Object.prototype.hasOwnProperty.call(input, key)
376
+ (input) => isObject(input) && Object.hasOwn(input, key)
361
377
  );
362
378
  var hasKeys = (...keys) => {
363
379
  if (keys.length === 0) {
364
380
  return define(() => false);
365
381
  }
366
382
  return define(
367
- (input) => isObject(input) && keys.every((key) => Object.prototype.hasOwnProperty.call(input, key))
383
+ (input) => isObject(input) && keys.every((key) => Object.hasOwn(input, key))
368
384
  );
369
385
  };
370
386
  function narrowKeyTo(guard, key) {
@@ -384,6 +400,11 @@ export {
384
400
  equals,
385
401
  equalsBy,
386
402
  equalsKey,
403
+ everyArrayValue,
404
+ everyMapEntry,
405
+ everyOwnEnumerableEntry,
406
+ everySetValue,
407
+ everyTupleValue,
387
408
  guardIn,
388
409
  hasKey,
389
410
  hasKeys,
@@ -426,6 +447,7 @@ export {
426
447
  isZero,
427
448
  mapOf,
428
449
  narrowKeyTo,
450
+ nonEmptyArrayOf,
429
451
  nonNull,
430
452
  not,
431
453
  nullable,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "is-kit",
3
- "version": "1.6.3",
3
+ "version": "1.7.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",