bupkis 0.7.2 → 0.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.
Files changed (215) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +19 -2
  3. package/dist/commonjs/assertion/assertion-async.d.ts.map +1 -1
  4. package/dist/commonjs/assertion/assertion-async.js +37 -7
  5. package/dist/commonjs/assertion/assertion-async.js.map +1 -1
  6. package/dist/commonjs/assertion/assertion-sync.d.ts.map +1 -1
  7. package/dist/commonjs/assertion/assertion-sync.js +32 -8
  8. package/dist/commonjs/assertion/assertion-sync.js.map +1 -1
  9. package/dist/commonjs/assertion/assertion-types.d.ts +37 -31
  10. package/dist/commonjs/assertion/assertion-types.d.ts.map +1 -1
  11. package/dist/commonjs/assertion/assertion-types.js +0 -32
  12. package/dist/commonjs/assertion/assertion-types.js.map +1 -1
  13. package/dist/commonjs/assertion/assertion.d.ts +3 -21
  14. package/dist/commonjs/assertion/assertion.d.ts.map +1 -1
  15. package/dist/commonjs/assertion/assertion.js +42 -27
  16. package/dist/commonjs/assertion/assertion.js.map +1 -1
  17. package/dist/commonjs/assertion/create.d.ts +2 -0
  18. package/dist/commonjs/assertion/create.d.ts.map +1 -1
  19. package/dist/commonjs/assertion/create.js +38 -42
  20. package/dist/commonjs/assertion/create.js.map +1 -1
  21. package/dist/commonjs/assertion/impl/assertion-util.d.ts +16 -4
  22. package/dist/commonjs/assertion/impl/assertion-util.d.ts.map +1 -1
  23. package/dist/commonjs/assertion/impl/assertion-util.js +20 -15
  24. package/dist/commonjs/assertion/impl/assertion-util.js.map +1 -1
  25. package/dist/commonjs/assertion/impl/async-parametric.d.ts +63 -11
  26. package/dist/commonjs/assertion/impl/async-parametric.d.ts.map +1 -1
  27. package/dist/commonjs/assertion/impl/async-parametric.js +89 -52
  28. package/dist/commonjs/assertion/impl/async-parametric.js.map +1 -1
  29. package/dist/commonjs/assertion/impl/async.d.ts +116 -12
  30. package/dist/commonjs/assertion/impl/async.d.ts.map +1 -1
  31. package/dist/commonjs/assertion/impl/async.js +1 -1
  32. package/dist/commonjs/assertion/impl/sync-basic.d.ts.map +1 -1
  33. package/dist/commonjs/assertion/impl/sync-basic.js +6 -4
  34. package/dist/commonjs/assertion/impl/sync-basic.js.map +1 -1
  35. package/dist/commonjs/assertion/impl/sync-collection.d.ts.map +1 -1
  36. package/dist/commonjs/assertion/impl/sync-collection.js +24 -14
  37. package/dist/commonjs/assertion/impl/sync-collection.js.map +1 -1
  38. package/dist/commonjs/assertion/impl/sync-esoteric.d.ts +1 -5
  39. package/dist/commonjs/assertion/impl/sync-esoteric.d.ts.map +1 -1
  40. package/dist/commonjs/assertion/impl/sync-esoteric.js +11 -13
  41. package/dist/commonjs/assertion/impl/sync-esoteric.js.map +1 -1
  42. package/dist/commonjs/assertion/impl/sync-parametric.d.ts +27 -7
  43. package/dist/commonjs/assertion/impl/sync-parametric.d.ts.map +1 -1
  44. package/dist/commonjs/assertion/impl/sync-parametric.js +75 -51
  45. package/dist/commonjs/assertion/impl/sync-parametric.js.map +1 -1
  46. package/dist/commonjs/assertion/impl/sync.d.ts +54 -22
  47. package/dist/commonjs/assertion/impl/sync.d.ts.map +1 -1
  48. package/dist/commonjs/assertion/impl/sync.js +1 -1
  49. package/dist/commonjs/assertion/impl/sync.js.map +1 -1
  50. package/dist/commonjs/assertion/index.d.ts +1 -1
  51. package/dist/commonjs/assertion/index.d.ts.map +1 -1
  52. package/dist/commonjs/assertion/index.js +0 -1
  53. package/dist/commonjs/assertion/index.js.map +1 -1
  54. package/dist/commonjs/assertion/slotify.d.ts +1 -13
  55. package/dist/commonjs/assertion/slotify.d.ts.map +1 -1
  56. package/dist/commonjs/assertion/slotify.js +49 -16
  57. package/dist/commonjs/assertion/slotify.js.map +1 -1
  58. package/dist/commonjs/bootstrap.d.ts +85 -17
  59. package/dist/commonjs/bootstrap.d.ts.map +1 -1
  60. package/dist/commonjs/bootstrap.js +1 -0
  61. package/dist/commonjs/bootstrap.js.map +1 -1
  62. package/dist/commonjs/diff.d.ts +51 -0
  63. package/dist/commonjs/diff.d.ts.map +1 -0
  64. package/dist/commonjs/diff.js +279 -0
  65. package/dist/commonjs/diff.js.map +1 -0
  66. package/dist/commonjs/error.d.ts +37 -18
  67. package/dist/commonjs/error.d.ts.map +1 -1
  68. package/dist/commonjs/error.js +44 -30
  69. package/dist/commonjs/error.js.map +1 -1
  70. package/dist/commonjs/expect.d.ts.map +1 -1
  71. package/dist/commonjs/expect.js +131 -78
  72. package/dist/commonjs/expect.js.map +1 -1
  73. package/dist/commonjs/guards.d.ts +24 -10
  74. package/dist/commonjs/guards.d.ts.map +1 -1
  75. package/dist/commonjs/guards.js +56 -39
  76. package/dist/commonjs/guards.js.map +1 -1
  77. package/dist/commonjs/index.d.ts +85 -17
  78. package/dist/commonjs/index.d.ts.map +1 -1
  79. package/dist/commonjs/internal-schema.d.ts +25 -0
  80. package/dist/commonjs/internal-schema.d.ts.map +1 -0
  81. package/dist/commonjs/internal-schema.js +209 -0
  82. package/dist/commonjs/internal-schema.js.map +1 -0
  83. package/dist/commonjs/schema.d.ts.map +1 -1
  84. package/dist/commonjs/schema.js +3 -2
  85. package/dist/commonjs/schema.js.map +1 -1
  86. package/dist/commonjs/use.js +22 -8
  87. package/dist/commonjs/use.js.map +1 -1
  88. package/dist/commonjs/util.d.ts +1 -0
  89. package/dist/commonjs/util.d.ts.map +1 -1
  90. package/dist/commonjs/util.js +14 -10
  91. package/dist/commonjs/util.js.map +1 -1
  92. package/dist/commonjs/value-to-schema.d.ts +1 -0
  93. package/dist/commonjs/value-to-schema.d.ts.map +1 -1
  94. package/dist/commonjs/value-to-schema.js +19 -12
  95. package/dist/commonjs/value-to-schema.js.map +1 -1
  96. package/dist/esm/assertion/assertion-async.d.ts.map +1 -1
  97. package/dist/esm/assertion/assertion-async.js +37 -7
  98. package/dist/esm/assertion/assertion-async.js.map +1 -1
  99. package/dist/esm/assertion/assertion-sync.d.ts.map +1 -1
  100. package/dist/esm/assertion/assertion-sync.js +32 -8
  101. package/dist/esm/assertion/assertion-sync.js.map +1 -1
  102. package/dist/esm/assertion/assertion-types.d.ts +37 -31
  103. package/dist/esm/assertion/assertion-types.d.ts.map +1 -1
  104. package/dist/esm/assertion/assertion-types.js +1 -31
  105. package/dist/esm/assertion/assertion-types.js.map +1 -1
  106. package/dist/esm/assertion/assertion.d.ts +3 -21
  107. package/dist/esm/assertion/assertion.d.ts.map +1 -1
  108. package/dist/esm/assertion/assertion.js +42 -27
  109. package/dist/esm/assertion/assertion.js.map +1 -1
  110. package/dist/esm/assertion/create.d.ts +2 -0
  111. package/dist/esm/assertion/create.d.ts.map +1 -1
  112. package/dist/esm/assertion/create.js +37 -41
  113. package/dist/esm/assertion/create.js.map +1 -1
  114. package/dist/esm/assertion/impl/assertion-util.d.ts +16 -4
  115. package/dist/esm/assertion/impl/assertion-util.d.ts.map +1 -1
  116. package/dist/esm/assertion/impl/assertion-util.js +20 -15
  117. package/dist/esm/assertion/impl/assertion-util.js.map +1 -1
  118. package/dist/esm/assertion/impl/async-parametric.d.ts +63 -11
  119. package/dist/esm/assertion/impl/async-parametric.d.ts.map +1 -1
  120. package/dist/esm/assertion/impl/async-parametric.js +89 -52
  121. package/dist/esm/assertion/impl/async-parametric.js.map +1 -1
  122. package/dist/esm/assertion/impl/async.d.ts +116 -12
  123. package/dist/esm/assertion/impl/async.d.ts.map +1 -1
  124. package/dist/esm/assertion/impl/async.js +2 -2
  125. package/dist/esm/assertion/impl/async.js.map +1 -1
  126. package/dist/esm/assertion/impl/sync-basic.d.ts.map +1 -1
  127. package/dist/esm/assertion/impl/sync-basic.js +6 -4
  128. package/dist/esm/assertion/impl/sync-basic.js.map +1 -1
  129. package/dist/esm/assertion/impl/sync-collection.d.ts.map +1 -1
  130. package/dist/esm/assertion/impl/sync-collection.js +24 -14
  131. package/dist/esm/assertion/impl/sync-collection.js.map +1 -1
  132. package/dist/esm/assertion/impl/sync-esoteric.d.ts +1 -5
  133. package/dist/esm/assertion/impl/sync-esoteric.d.ts.map +1 -1
  134. package/dist/esm/assertion/impl/sync-esoteric.js +11 -13
  135. package/dist/esm/assertion/impl/sync-esoteric.js.map +1 -1
  136. package/dist/esm/assertion/impl/sync-parametric.d.ts +27 -7
  137. package/dist/esm/assertion/impl/sync-parametric.d.ts.map +1 -1
  138. package/dist/esm/assertion/impl/sync-parametric.js +75 -51
  139. package/dist/esm/assertion/impl/sync-parametric.js.map +1 -1
  140. package/dist/esm/assertion/impl/sync.d.ts +54 -22
  141. package/dist/esm/assertion/impl/sync.d.ts.map +1 -1
  142. package/dist/esm/assertion/impl/sync.js +2 -2
  143. package/dist/esm/assertion/impl/sync.js.map +1 -1
  144. package/dist/esm/assertion/index.d.ts +1 -1
  145. package/dist/esm/assertion/index.d.ts.map +1 -1
  146. package/dist/esm/assertion/index.js +0 -1
  147. package/dist/esm/assertion/index.js.map +1 -1
  148. package/dist/esm/assertion/slotify.d.ts +1 -13
  149. package/dist/esm/assertion/slotify.d.ts.map +1 -1
  150. package/dist/esm/assertion/slotify.js +50 -17
  151. package/dist/esm/assertion/slotify.js.map +1 -1
  152. package/dist/esm/bootstrap.d.ts +85 -17
  153. package/dist/esm/bootstrap.d.ts.map +1 -1
  154. package/dist/esm/bootstrap.js +1 -0
  155. package/dist/esm/bootstrap.js.map +1 -1
  156. package/dist/esm/diff.d.ts +51 -0
  157. package/dist/esm/diff.d.ts.map +1 -0
  158. package/dist/esm/diff.js +273 -0
  159. package/dist/esm/diff.js.map +1 -0
  160. package/dist/esm/error.d.ts +37 -18
  161. package/dist/esm/error.d.ts.map +1 -1
  162. package/dist/esm/error.js +41 -27
  163. package/dist/esm/error.js.map +1 -1
  164. package/dist/esm/expect.d.ts.map +1 -1
  165. package/dist/esm/expect.js +133 -80
  166. package/dist/esm/expect.js.map +1 -1
  167. package/dist/esm/guards.d.ts +24 -10
  168. package/dist/esm/guards.d.ts.map +1 -1
  169. package/dist/esm/guards.js +52 -36
  170. package/dist/esm/guards.js.map +1 -1
  171. package/dist/esm/index.d.ts +85 -17
  172. package/dist/esm/index.d.ts.map +1 -1
  173. package/dist/esm/internal-schema.d.ts +25 -0
  174. package/dist/esm/internal-schema.d.ts.map +1 -0
  175. package/dist/esm/internal-schema.js +203 -0
  176. package/dist/esm/internal-schema.js.map +1 -0
  177. package/dist/esm/schema.d.ts.map +1 -1
  178. package/dist/esm/schema.js +3 -2
  179. package/dist/esm/schema.js.map +1 -1
  180. package/dist/esm/use.js +19 -6
  181. package/dist/esm/use.js.map +1 -1
  182. package/dist/esm/util.d.ts +1 -0
  183. package/dist/esm/util.d.ts.map +1 -1
  184. package/dist/esm/util.js +14 -10
  185. package/dist/esm/util.js.map +1 -1
  186. package/dist/esm/value-to-schema.d.ts +1 -0
  187. package/dist/esm/value-to-schema.d.ts.map +1 -1
  188. package/dist/esm/value-to-schema.js +20 -13
  189. package/dist/esm/value-to-schema.js.map +1 -1
  190. package/package.json +29 -11
  191. package/src/assertion/assertion-async.ts +42 -14
  192. package/src/assertion/assertion-sync.ts +40 -17
  193. package/src/assertion/assertion-types.ts +55 -45
  194. package/src/assertion/assertion.ts +49 -32
  195. package/src/assertion/create.ts +46 -65
  196. package/src/assertion/impl/assertion-util.ts +31 -18
  197. package/src/assertion/impl/async-parametric.ts +93 -52
  198. package/src/assertion/impl/async.ts +2 -2
  199. package/src/assertion/impl/sync-basic.ts +7 -4
  200. package/src/assertion/impl/sync-collection.ts +34 -14
  201. package/src/assertion/impl/sync-esoteric.ts +17 -13
  202. package/src/assertion/impl/sync-parametric.ts +79 -52
  203. package/src/assertion/impl/sync.ts +2 -2
  204. package/src/assertion/index.ts +1 -1
  205. package/src/assertion/slotify.ts +67 -21
  206. package/src/bootstrap.ts +1 -0
  207. package/src/diff.ts +343 -0
  208. package/src/error.ts +66 -31
  209. package/src/expect.ts +195 -129
  210. package/src/guards.ts +74 -48
  211. package/src/internal-schema.ts +246 -0
  212. package/src/schema.ts +4 -2
  213. package/src/use.ts +21 -7
  214. package/src/util.ts +15 -12
  215. package/src/value-to-schema.ts +21 -13
package/src/util.ts CHANGED
@@ -17,6 +17,10 @@ import { type Keypath } from './types.js';
17
17
 
18
18
  export * from './value-to-schema.js';
19
19
 
20
+ const { hasOwn, keys, values } = Object;
21
+ const { isInteger, isNaN } = Number;
22
+ const { isArray } = Array;
23
+
20
24
  /**
21
25
  * Retrieves the value at a given keypath from an object using dot or bracket
22
26
  * notation.
@@ -191,18 +195,18 @@ export const hasKeyDeep = (
191
195
  visited.add(obj);
192
196
 
193
197
  try {
194
- if (Object.hasOwn(obj, key)) {
198
+ if (hasOwn(obj, key)) {
195
199
  return true;
196
200
  }
197
201
 
198
- if (Array.isArray(obj)) {
202
+ if (isArray(obj)) {
199
203
  for (const item of obj) {
200
204
  if (hasKeyDeep(item, key, visited)) {
201
205
  return true;
202
206
  }
203
207
  }
204
208
  } else {
205
- for (const propValue of Object.values(obj)) {
209
+ for (const propValue of values(obj)) {
206
210
  if (hasKeyDeep(propValue, key, visited)) {
207
211
  return true;
208
212
  }
@@ -255,13 +259,13 @@ export const hasValueDeep = (
255
259
  if (
256
260
  typeof obj === 'object' &&
257
261
  obj !== null &&
258
- !Array.isArray(obj) &&
262
+ !isArray(obj) &&
259
263
  typeof value === 'object' &&
260
264
  value !== null &&
261
- !Array.isArray(value)
265
+ !isArray(value)
262
266
  ) {
263
- const objKeys = Object.keys(obj);
264
- const valueKeys = Object.keys(value);
267
+ const objKeys = keys(obj);
268
+ const valueKeys = keys(value);
265
269
 
266
270
  if (objKeys.length === 0 && valueKeys.length === 0) {
267
271
  return true;
@@ -278,14 +282,14 @@ export const hasValueDeep = (
278
282
  visited.add(obj);
279
283
 
280
284
  try {
281
- if (Array.isArray(obj)) {
285
+ if (isArray(obj)) {
282
286
  for (const item of obj) {
283
287
  if (hasValueDeep(item, value, visited)) {
284
288
  return true;
285
289
  }
286
290
  }
287
291
  } else {
288
- for (const propValue of Object.values(obj)) {
292
+ for (const propValue of values(obj)) {
289
293
  if (hasValueDeep(propValue, value, visited)) {
290
294
  return true;
291
295
  }
@@ -364,6 +368,7 @@ export const keyBy = <
364
368
  * parseKeypath("arr[10]['spam']"); // ['arr', 10, 'spam']
365
369
  * ```
366
370
  *
371
+ * @function
367
372
  * @param keypath The keypath string to parse, using dot and/or bracket
368
373
  * notation.
369
374
  * @returns An array of keys, where each key is a string or number. Bracketed
@@ -401,9 +406,7 @@ export const parseKeypath = <S extends string = string>(
401
406
  i++;
402
407
 
403
408
  const numKey = Number(key);
404
- keys.push(
405
- Number.isInteger(numKey) && !Number.isNaN(numKey) ? numKey : key,
406
- );
409
+ keys.push(isInteger(numKey) && !isNaN(numKey) ? numKey : key);
407
410
  } else if (keypath[i] === '.') {
408
411
  i++;
409
412
  } else {
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod/v4';
2
2
 
3
- import { ValueToSchemaError } from './error.js';
3
+ import { SatisfactionError } from './error.js';
4
4
  import {
5
5
  isExpectItExecutor,
6
6
  isNonNullObject,
@@ -11,6 +11,10 @@ import {
11
11
  } from './guards.js';
12
12
  import { RegExpSchema, WrappedPromiseLikeSchema } from './schema.js';
13
13
 
14
+ const { isNaN } = Number;
15
+ const { entries, freeze, hasOwn, keys } = Object;
16
+ const { isArray } = Array;
17
+
14
18
  /**
15
19
  * Recursively converts an arbitrary value to a Zod v4 schema that would
16
20
  * validate values with the same structure.
@@ -41,6 +45,7 @@ import { RegExpSchema, WrappedPromiseLikeSchema } from './schema.js';
41
45
  * // z.object({ users: z.array(z.object({ name: z.string() })) })
42
46
  * ```
43
47
  *
48
+ * @function
44
49
  * @param value - The value to convert to a schema
45
50
  * @param options - Configuration options for schema generation
46
51
  * @param visited - Internal WeakSet for circular reference detection
@@ -82,7 +87,7 @@ export const valueToSchema = (
82
87
  })
83
88
  : z.undefined();
84
89
  }
85
- if (Number.isNaN(value as number)) {
90
+ if (isNaN(value as number)) {
86
91
  return z.nan();
87
92
  }
88
93
  if (value === Infinity || value === -Infinity) {
@@ -101,7 +106,7 @@ export const valueToSchema = (
101
106
  if (isExpectItExecutor(value)) {
102
107
  // Only allow nested assertions when strict is false (e.g., "to satisfy" semantics)
103
108
  if (strict) {
104
- throw new ValueToSchemaError(
109
+ throw new SatisfactionError(
105
110
  'ExpectItExecutor (expect.it) functions are not allowed in strict mode. ' +
106
111
  'Use "to satisfy" assertions for nested expectations.',
107
112
  );
@@ -142,8 +147,8 @@ export const valueToSchema = (
142
147
 
143
148
  try {
144
149
  // Check for objects with own __proto__ property - these can cause unexpected behavior
145
- if (Object.hasOwn(value, '__proto__')) {
146
- throw new ValueToSchemaError(
150
+ if (hasOwn(value, '__proto__')) {
151
+ throw new SatisfactionError(
147
152
  'Objects with an own "__proto__" property are not supported by valueToSchema',
148
153
  );
149
154
  }
@@ -195,7 +200,7 @@ export const valueToSchema = (
195
200
  }
196
201
 
197
202
  // Handle arrays
198
- if (Array.isArray(value)) {
203
+ if (isArray(value)) {
199
204
  // For arrays, we need to preserve undefined values while allowing
200
205
  // other elements to use the original literalPrimitives setting
201
206
  const filteredValue = value; // Always process all elements
@@ -232,6 +237,9 @@ export const valueToSchema = (
232
237
 
233
238
  if (!noMixedArrays) {
234
239
  // Helper function to generate structural keys for schemas
240
+ /**
241
+ * @function
242
+ */
235
243
  const getSchemaKey = <T extends z.core.SomeType | z.ZodType>(
236
244
  zodType: T,
237
245
  ): string => {
@@ -253,7 +261,7 @@ export const valueToSchema = (
253
261
  string,
254
262
  z.ZodType
255
263
  >;
256
- const shapeKeys = Object.keys(shape)
264
+ const shapeKeys = keys(shape)
257
265
  .sort()
258
266
  .map((key) => {
259
267
  const propSchema = shape[key]!;
@@ -304,7 +312,7 @@ export const valueToSchema = (
304
312
  const schemaShape: Record<string, z.ZodType<any>> = {};
305
313
  const undefinedKeys: string[] = [];
306
314
 
307
- for (const [key, val] of Object.entries(value)) {
315
+ for (const [key, val] of entries(value)) {
308
316
  if (isString(key)) {
309
317
  // Skip undefined values unless we're in literalPrimitives mode
310
318
  // This prevents objects with only undefined values from matching any object
@@ -347,7 +355,7 @@ export const valueToSchema = (
347
355
 
348
356
  const obj = data as Record<string, unknown>;
349
357
  for (const key of undefinedKeys) {
350
- if (!Object.hasOwn(obj, key)) {
358
+ if (!hasOwn(obj, key)) {
351
359
  ctx.addIssue({
352
360
  code: z.ZodIssueCode.custom,
353
361
  message: `Expected property "${key}" to exist with value undefined`,
@@ -359,10 +367,10 @@ export const valueToSchema = (
359
367
  }
360
368
 
361
369
  // Check if this is an empty object and literalEmptyObjects is enabled
362
- if (Object.keys(schemaShape).length === 0 && literalEmptyObjects) {
370
+ if (keys(schemaShape).length === 0 && literalEmptyObjects) {
363
371
  // Create a schema that only matches empty objects
364
372
  return z.custom<Record<string, never>>(
365
- (val) => isObject(val) && Object.keys(val).length === 0,
373
+ (val) => isObject(val) && keys(val).length === 0,
366
374
  {
367
375
  message: 'Expected an empty object with no own properties',
368
376
  },
@@ -461,7 +469,7 @@ export interface ValueToSchemaOptions {
461
469
  * Uses literal primitives and tuples for exact matching while allowing extra
462
470
  * properties.
463
471
  */
464
- export const valueToSchemaOptionsForSatisfies = Object.freeze({
472
+ export const valueToSchemaOptionsForSatisfies = freeze({
465
473
  literalEmptyObjects: true,
466
474
  literalPrimitives: true,
467
475
  literalRegExp: false,
@@ -476,7 +484,7 @@ export const valueToSchemaOptionsForSatisfies = Object.freeze({
476
484
  * Uses literal primitives, regexp, and tuples with strict validation for exact
477
485
  * matching.
478
486
  */
479
- export const valueToSchemaOptionsForDeepEqual = Object.freeze({
487
+ export const valueToSchemaOptionsForDeepEqual = freeze({
480
488
  literalEmptyObjects: true,
481
489
  literalPrimitives: true,
482
490
  literalRegExp: true,