bupkis 0.0.2

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.
@@ -0,0 +1,964 @@
1
+ /**
2
+ * Core type definitions for the assertion system.
3
+ *
4
+ * This module defines all the fundamental types used throughout the assertion
5
+ * framework, including assertion parts, implementation functions, parsed
6
+ * values, and type inference utilities. These types enable type-safe assertion
7
+ * creation and execution.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+
12
+ import { type ArrayValues, type NonEmptyTuple } from 'type-fest';
13
+ import { type z } from 'zod/v4';
14
+
15
+ import type { createAssertion as _createAssertion } from './create.js';
16
+ import type { AsyncAssertions, SyncAssertions } from './impl/index.js';
17
+
18
+ /**
19
+ * Union type representing any assertion, either synchronous or asynchronous.
20
+ *
21
+ * This type combines all possible assertion types into a single union for cases
22
+ * where the synchronous/asynchronous nature is not known at compile time.
23
+ *
24
+ * @see {@link AnyAsyncAssertion} for async-specific assertions
25
+ * @see {@link AnySyncAssertion} for sync-specific assertions
26
+ */
27
+ export type AnyAssertion = AnyAsyncAssertion | AnySyncAssertion;
28
+
29
+ /**
30
+ * Non-empty tuple type containing any assertions.
31
+ *
32
+ * Used to represent collections of assertions where at least one assertion must
33
+ * be present.
34
+ *
35
+ * @see {@link AnyAssertion} for individual assertion types
36
+ */
37
+ export type AnyAssertions = NonEmptyTuple<AnyAssertion>;
38
+
39
+ /**
40
+ * Union type representing any asynchronous assertion.
41
+ *
42
+ * This includes both function-based and schema-based async assertions but
43
+ * excludes synchronous assertions to maintain type safety.
44
+ *
45
+ * @see {@link AssertionFunctionAsync} for function-based async assertions
46
+ * @see {@link AssertionSchemaAsync} for schema-based async assertions
47
+ */
48
+ export type AnyAsyncAssertion =
49
+ // | AssertionAsync<any, any, any>
50
+ AssertionFunctionAsync<any, any, any> | AssertionSchemaAsync<any, any, any>;
51
+
52
+ /**
53
+ * Non-empty tuple type containing any asynchronous assertions.
54
+ *
55
+ * Used to represent collections of async assertions where at least one
56
+ * assertion must be present.
57
+ *
58
+ * @see {@link AnyAsyncAssertion} for individual async assertion types
59
+ */
60
+ export type AnyAsyncAssertions = NonEmptyTuple<AnyAsyncAssertion>;
61
+
62
+ /**
63
+ * Union type representing any synchronous assertion.
64
+ *
65
+ * This includes both function-based and schema-based sync assertions but
66
+ * excludes asynchronous assertions to maintain type safety.
67
+ *
68
+ * @see {@link AssertionFunctionSync} for function-based sync assertions
69
+ * @see {@link AssertionSchemaSync} for schema-based sync assertions
70
+ */
71
+ export type AnySyncAssertion =
72
+ | AssertionFunctionSync<any, any, any>
73
+ | AssertionSchemaSync<any, any, any>;
74
+ // | AssertionSync<any, any, any>;
75
+
76
+ /**
77
+ * Non-empty tuple type containing any synchronous assertions.
78
+ *
79
+ * Used to represent collections of sync assertions where at least one assertion
80
+ * must be present.
81
+ *
82
+ * @see {@link AnySyncAssertion} for individual sync assertion types
83
+ */
84
+ export type AnySyncAssertions = NonEmptyTuple<AnySyncAssertion>;
85
+
86
+ /**
87
+ * Interface for the base abstract `Assertion` class.
88
+ *
89
+ * This interface defines the contract for assertion instances, including
90
+ * properties for assertion parts, implementation, slots, and methods for
91
+ * parsing and executing assertions both synchronously and asynchronously.
92
+ */
93
+ export interface Assertion<
94
+ Parts extends AssertionParts,
95
+ Impl extends AssertionImpl<Parts>,
96
+ Slots extends AssertionSlots<Parts>,
97
+ > {
98
+ readonly id: string;
99
+
100
+ /**
101
+ * The implementation function or schema for this assertion.
102
+ */
103
+ readonly impl: Impl;
104
+
105
+ /**
106
+ * The assertion parts used to create this assertion.
107
+ *
108
+ * Available at runtime for introspection.
109
+ */
110
+ readonly parts: Parts;
111
+
112
+ /**
113
+ * The slots derived from assertion parts for validation.
114
+ */
115
+ readonly slots: Slots;
116
+
117
+ /**
118
+ * Returns the string representation of this assertion.
119
+ */
120
+ toString(): string;
121
+ }
122
+
123
+ export interface AssertionAsync<
124
+ Parts extends AssertionParts = AssertionParts,
125
+ Impl extends AssertionImplAsync<Parts> = AssertionImplAsync<Parts>,
126
+ Slots extends AssertionSlots<Parts> = AssertionSlots<Parts>,
127
+ > extends Assertion<Parts, Impl, Slots> {
128
+ /**
129
+ * Execute the assertion implementation asynchronously.
130
+ *
131
+ * @param parsedValues Parameters for the assertion implementation
132
+ * @param args Raw parameters passed to `expectAsync()`
133
+ * @param stackStartFn Function to use as stack start for error reporting
134
+ * @param parseResult Optional parse result containing cached validation data
135
+ */
136
+ executeAsync(
137
+ parsedValues: ParsedValues<Parts>,
138
+ args: unknown[],
139
+ stackStartFn: (...args: any[]) => any,
140
+ parseResult?: ParsedResult<Parts>,
141
+ ): Promise<void>;
142
+
143
+ /**
144
+ * Parses raw arguments asynchronously against this assertion's slots to
145
+ * determine if they match this assertion.
146
+ *
147
+ * @param args Raw arguments provided to `expectAsync()`
148
+ * @returns Result of parsing attempt
149
+ */
150
+ parseValuesAsync<Args extends readonly unknown[]>(
151
+ args: Args,
152
+ ): Promise<ParsedResult<Parts>>;
153
+ }
154
+
155
+ export interface AssertionFailure {
156
+ /**
157
+ * The actual value or condition that was encountered
158
+ */
159
+ actual?: unknown;
160
+ /**
161
+ * The expected value or condition that was not met
162
+ */
163
+ expected?: unknown;
164
+ /**
165
+ * A human-readable message describing the failure
166
+ */
167
+ message?: string | undefined;
168
+ }
169
+
170
+ /**
171
+ * An async assertion with a function implementation.
172
+ */
173
+ export interface AssertionFunctionAsync<
174
+ Parts extends AssertionParts,
175
+ Impl extends AssertionImplFnAsync<Parts>,
176
+ Slots extends AssertionSlots<Parts>,
177
+ > extends AssertionAsync<Parts, Impl, Slots> {
178
+ impl: Impl;
179
+ }
180
+
181
+ /**
182
+ * A synchronous assertion with a function implementation.
183
+ */
184
+ export interface AssertionFunctionSync<
185
+ Parts extends AssertionParts,
186
+ Impl extends AssertionImplFnSync<Parts>,
187
+ Slots extends AssertionSlots<Parts>,
188
+ > extends AssertionSync<Parts, Impl, Slots> {
189
+ impl: Impl;
190
+ }
191
+
192
+ /**
193
+ * Any type of assertion implementation.
194
+ */
195
+ export type AssertionImpl<Parts extends AssertionParts> =
196
+ | AssertionImplAsync<Parts>
197
+ | AssertionImplSync<Parts>;
198
+
199
+ /**
200
+ * Union type representing any async assertion implementation.
201
+ *
202
+ * This encompasses both function-based and schema-based implementations for
203
+ * asynchronous assertions, providing a type-safe way to handle async assertion
204
+ * logic.
205
+ *
206
+ * @typeParam Parts - The assertion parts defining the structure
207
+ * @see {@link AssertionImplFnAsync} for function-based async implementations
208
+ * @see {@link AssertionImplSchemaAsync} for schema-based async implementations
209
+ */
210
+ export type AssertionImplAsync<Parts extends AssertionParts> =
211
+ | AssertionImplFnAsync<Parts>
212
+ | AssertionImplSchemaAsync<Parts>;
213
+
214
+ /**
215
+ * The implementation of an assertion as an async function.
216
+ *
217
+ * An asynchronous implementation function that validates assertion arguments
218
+ * and returns a Promise resolving to validation results. The function receives
219
+ * parsed values from the assertion parts and can return various types
220
+ * indicating validation success or failure.
221
+ *
222
+ * @typeParam Parts - The assertion parts defining the structure
223
+ * @param values - The parsed values corresponding to assertion parts
224
+ * @returns Promise resolving to boolean indicating pass/fail, void for success,
225
+ * ZodType for dynamic validation, or AssertionFailure object for detailed
226
+ * error information
227
+ * @see {@link AssertionImplFnSync} for sync function implementations
228
+ * @see {@link ParsedValues} for the input parameter structure
229
+ */
230
+ export type AssertionImplFnAsync<Parts extends AssertionParts> = (
231
+ ...values: ParsedValues<Parts>
232
+ ) => Promise<
233
+ AssertionFailure | boolean | void | z.ZodType<ParsedSubject<Parts>>
234
+ >;
235
+
236
+ /**
237
+ * The implementation of an assertion as a sync function.
238
+ *
239
+ * A synchronous implementation function that validates assertion arguments and
240
+ * returns validation results. The function receives parsed values from the
241
+ * assertion parts and can return various types indicating validation success or
242
+ * failure.
243
+ *
244
+ * @typeParam Parts - The assertion parts defining the structure
245
+ * @param values - The parsed values corresponding to assertion parts
246
+ * @returns Boolean indicating pass/fail, void for success, ZodType for dynamic
247
+ * validation, or AssertionFailure object for detailed error information
248
+ * @see {@link AssertionImplFnAsync} for async function implementations
249
+ * @see {@link ParsedValues} for the input parameter structure
250
+ */
251
+ export type AssertionImplFnSync<Parts extends AssertionParts> = (
252
+ ...values: ParsedValues<Parts>
253
+ ) => AssertionFailure | boolean | void | z.ZodType<ParsedSubject<Parts>>;
254
+
255
+ /**
256
+ * Maps an {@link AssertionPart} to a parameter to an {@link AssertionImpl}.
257
+ *
258
+ * This omits {@link Phrase} parts, which are not received by the implementation.
259
+ *
260
+ * @knipignore
261
+ */
262
+ export type AssertionImplPart<Part extends AssertionPart> = Part extends
263
+ | PhraseLiteral
264
+ | PhraseLiteralChoice
265
+ ? never
266
+ : Part extends z.ZodPromise
267
+ ? Promise<z.infer<Part>>
268
+ : z.infer<Part>;
269
+
270
+ /**
271
+ * Maps {@link AssertionParts} to their corresponding {@link AssertionImplPart}.
272
+ *
273
+ * @knipignore
274
+ */
275
+ export type AssertionImplParts<Parts extends readonly AssertionPart[]> =
276
+ Parts extends readonly [
277
+ infer First extends AssertionPart,
278
+ ...infer Rest extends readonly AssertionPart[],
279
+ ]
280
+ ? readonly [AssertionImplPart<First>, ...AssertionImplParts<Rest>]
281
+ : readonly [];
282
+
283
+ /**
284
+ * A Zod schema implementation created with createAsync() - potentially
285
+ * asynchronous
286
+ */
287
+ /**
288
+ * Type for an async assertion implementation using a Zod schema.
289
+ *
290
+ * This represents a branded Zod schema that validates the assertion subject
291
+ * asynchronously. The schema must match the parsed subject type derived from
292
+ * the assertion parts and is branded with 'async-schema' for compile-time type
293
+ * safety.
294
+ *
295
+ * @typeParam Parts - The assertion parts tuple defining the assertion structure
296
+ * @see {@link AssertionImplSchemaSync} for synchronous schema implementations
297
+ * @see {@link AssertionImplFnAsync} for function-based async implementations
298
+ * @see {@link ParsedSubject} for subject type derivation
299
+ */
300
+ export type AssertionImplSchemaAsync<Parts extends AssertionParts> =
301
+ z.core.$ZodBranded<z.ZodType<ParsedSubject<Parts>>, 'async-schema'>;
302
+
303
+ /**
304
+ * Type for a synchronous assertion implementation using a Zod schema.
305
+ *
306
+ * This represents a branded Zod schema that validates the assertion subject
307
+ * synchronously. The schema must match the parsed subject type derived from the
308
+ * assertion parts and is branded with 'sync-schema' for compile-time type
309
+ * safety.
310
+ *
311
+ * @typeParam Parts - The assertion parts tuple defining the assertion structure
312
+ * @see {@link AssertionImplSchemaAsync} for asynchronous schema implementations
313
+ * @see {@link AssertionImplFnSync} for function-based sync implementations
314
+ * @see {@link ParsedSubject} for subject type derivation
315
+ */
316
+ export type AssertionImplSchemaSync<Parts extends AssertionParts> =
317
+ z.core.$ZodBranded<z.ZodType<ParsedSubject<Parts>>, 'sync-schema'>;
318
+
319
+ /**
320
+ * Union type for all synchronous assertion implementations.
321
+ *
322
+ * This represents either a function-based or schema-based implementation for
323
+ * synchronous assertions. Function implementations provide custom validation
324
+ * logic, while schema implementations use Zod schemas for validation.
325
+ *
326
+ * @typeParam Parts - The assertion parts tuple defining the assertion structure
327
+ * @see {@link AssertionImplFnSync} for function-based implementations
328
+ * @see {@link AssertionImplSchemaSync} for schema-based implementations
329
+ * @see {@link AssertionImplAsync} for async implementation unions
330
+ */
331
+ /**
332
+ * Union type for all synchronous assertion implementations.
333
+ *
334
+ * This represents either a function-based or schema-based implementation for
335
+ * synchronous assertions. Function implementations provide custom validation
336
+ * logic, while schema implementations use Zod schemas for validation.
337
+ *
338
+ * @typeParam Parts - The assertion parts tuple defining the assertion structure
339
+ * @see {@link AssertionImplFnSync} for function-based implementations
340
+ * @see {@link AssertionImplSchemaSync} for schema-based implementations
341
+ * @see {@link AssertionImplAsync} for async implementation unions
342
+ */
343
+ export type AssertionImplSync<Parts extends AssertionParts> =
344
+ | AssertionImplFnSync<Parts>
345
+ | AssertionImplSchemaSync<Parts>;
346
+
347
+ /**
348
+ * Union type representing the fundamental building blocks of an assertion.
349
+ *
350
+ * An assertion part can be either a phrase (string literal or choice of
351
+ * literals) that describes the natural language portion of the assertion, or a
352
+ * Zod schema that defines validation constraints for assertion arguments.
353
+ *
354
+ * @example
355
+ *
356
+ * ```ts
357
+ * // String literal phrase
358
+ * type Part1 = 'to be a string';
359
+ *
360
+ * // String literal choice
361
+ * type Part2 = ['to be', 'to equal'];
362
+ *
363
+ * // Zod schema for validation
364
+ * type Part3 = z.ZodString;
365
+ * ```
366
+ *
367
+ * @see {@link Phrase} for phrase-based parts
368
+ * @see {@link AssertionParts} for complete assertion structure
369
+ * @see {@link AssertionSlot} for compiled slot representation
370
+ */
371
+ export type AssertionPart = Phrase | z.ZodType;
372
+
373
+ /**
374
+ * Non-empty tuple type representing the complete structure of an assertion.
375
+ *
376
+ * This defines the signature of an assertion by combining phrases (natural
377
+ * language) and Zod schemas (validation constraints). The tuple must contain at
378
+ * least one element and typically starts with a subject schema followed by
379
+ * phrase literals and additional parameter schemas.
380
+ *
381
+ * @example
382
+ *
383
+ * ```ts
384
+ * // Basic assertion: expect(value, 'to be a string')
385
+ * type SimpleAssertion = ['to be a string'];
386
+ *
387
+ * // Parameterized assertion: expect(value, 'to be greater than', 5)
388
+ * type ParametricAssertion = [z.number(), 'to be greater than', z.number()];
389
+ *
390
+ * // Choice-based assertion: expect(value, ['to be', 'to equal'], expected)
391
+ * type ChoiceAssertion = [z.any(), ['to be', 'to equal'], z.any()];
392
+ * ```
393
+ *
394
+ * @typeParam Parts - Extends the base AssertionPart array with tuple
395
+ * constraints
396
+ * @see {@link AssertionPart} for individual part types
397
+ * @see {@link AssertionSlots} for compiled slot representation
398
+ * @see {@link _createAssertion} for assertion creation from parts
399
+ */
400
+ export type AssertionParts = NonEmptyTuple<AssertionPart>;
401
+
402
+ /**
403
+ * Type-level mapping from assertion parts to their corresponding validation
404
+ * slots.
405
+ *
406
+ * This recursive type processes each assertion part and converts it to a slot
407
+ * that can be used for runtime validation. Phrase literals become branded
408
+ * string schemas, while Zod types are preserved as-is. The resulting tuple may
409
+ * contain `never` entries for invalid parts that should be filtered out.
410
+ *
411
+ * @example
412
+ *
413
+ * ```ts
414
+ * // Input parts
415
+ * type Parts = ['to be a string', z.number()];
416
+ *
417
+ * // Resulting slots (simplified)
418
+ * type Slots = [PhraseLiteralSlot<'to be a string'>, z.ZodNumber];
419
+ * ```
420
+ *
421
+ * @typeParam Parts - The readonly array of assertion parts to process
422
+ * @see {@link AssertionSlot} for individual slot type mapping
423
+ * @see {@link AssertionSlots} for filtered and properly typed slot tuples
424
+ * @see {@link NoNeverTuple} for filtering never entries
425
+ */
426
+ export type AssertionPartsToSlots<Parts extends readonly AssertionPart[]> =
427
+ Parts extends readonly [
428
+ infer First extends AssertionPart,
429
+ ...infer Rest extends readonly AssertionPart[],
430
+ ]
431
+ ? readonly [AssertionSlot<First>, ...AssertionPartsToSlots<Rest>]
432
+ : readonly [];
433
+
434
+ export interface AssertionSchemaAsync<
435
+ Parts extends AssertionParts,
436
+ Impl extends AssertionImplSchemaAsync<Parts>,
437
+ Slots extends AssertionSlots<Parts>,
438
+ > extends AssertionAsync<Parts, Impl, Slots> {
439
+ impl: Impl;
440
+ }
441
+
442
+ export interface AssertionSchemaSync<
443
+ Parts extends AssertionParts,
444
+ Impl extends AssertionImplSchemaSync<Parts>,
445
+ Slots extends AssertionSlots<Parts>,
446
+ > extends AssertionSync<Parts, Impl, Slots> {
447
+ impl: Impl;
448
+ }
449
+
450
+ /**
451
+ * Type-level mapping that converts an assertion part to its corresponding
452
+ * validation slot.
453
+ *
454
+ * This maps each type of assertion part to a specific Zod schema that can be
455
+ * used for runtime validation:
456
+ *
457
+ * - String literals become branded phrase literal slots
458
+ * - String literal choices become branded phrase choice slots
459
+ * - Zod types are preserved as-is
460
+ * - Invalid parts become `never`
461
+ *
462
+ * @example
463
+ *
464
+ * ```ts
465
+ * // String literal -> branded slot
466
+ * type Slot1 = AssertionSlot<'to be a string'>; // PhraseLiteralSlot<'to be a string'>
467
+ *
468
+ * // Choice -> branded choice slot
469
+ * type Slot2 = AssertionSlot<['to be', 'to equal']>; // PhraseLiteralChoiceSlot<['to be', 'to equal']>
470
+ *
471
+ * // Zod type -> preserved
472
+ * type Slot3 = AssertionSlot<z.ZodString>; // z.ZodString
473
+ * ```
474
+ *
475
+ * @typeParam Part - The assertion part to convert to a slot
476
+ * @see {@link PhraseLiteralSlot} for string literal slots
477
+ * @see {@link PhraseLiteralChoiceSlot} for choice-based slots
478
+ * @see {@link AssertionSlots} for complete slot tuples
479
+ */
480
+ export type AssertionSlot<Part extends AssertionPart> = Part extends string
481
+ ? PhraseLiteralSlot<Part>
482
+ : Part extends readonly [string, ...string[]]
483
+ ? PhraseLiteralChoiceSlot<Part>
484
+ : Part extends z.ZodType
485
+ ? Part
486
+ : never;
487
+
488
+ /**
489
+ * Tuple type representing all validation slots derived from assertion parts.
490
+ *
491
+ * This type processes assertion parts to create a tuple of Zod schemas that can
492
+ * be used for runtime argument validation. If the first part is a phrase, a
493
+ * subject slot (`z.ZodUnknown`) is automatically prepended to accept the
494
+ * assertion subject.
495
+ *
496
+ * The resulting tuple:
497
+ *
498
+ * 1. Has `never` entries filtered out to maintain proper tuple structure
499
+ * 2. May include an implicit subject slot for phrase-first assertions
500
+ * 3. Contains branded slots for phrase literals to enable phrase matching
501
+ *
502
+ * @example
503
+ *
504
+ * ```ts
505
+ * // Phrase-first assertion gets subject slot
506
+ * type Slots1 = AssertionSlots<['to be a string']>;
507
+ * // Result: [z.ZodUnknown, PhraseLiteralSlot<'to be a string'>]
508
+ *
509
+ * // Schema-first assertion preserves structure
510
+ * type Slots2 = AssertionSlots<[z.string(), 'to match', z.regexp()]>;
511
+ * // Result: [z.ZodString, PhraseLiteralSlot<'to match'>, z.ZodRegExp]
512
+ * ```
513
+ *
514
+ * @typeParam Parts - The assertion parts to convert to slots
515
+ * @see {@link AssertionSlot} for individual slot mapping
516
+ * @see {@link AssertionPartsToSlots} for the underlying mapping logic
517
+ * @see {@link NoNeverTuple} for never filtering
518
+ */
519
+ export type AssertionSlots<Parts extends AssertionParts = AssertionParts> =
520
+ Parts extends readonly [
521
+ infer First extends AssertionPart,
522
+ ...infer _ extends AssertionParts,
523
+ ]
524
+ ? First extends PhraseLiteral | PhraseLiteralChoice
525
+ ? NoNeverTuple<readonly [z.ZodUnknown, ...AssertionPartsToSlots<Parts>]>
526
+ : NoNeverTuple<AssertionPartsToSlots<Parts>>
527
+ : never;
528
+
529
+ export interface AssertionSync<
530
+ Parts extends AssertionParts = AssertionParts,
531
+ Impl extends AssertionImplSync<Parts> = AssertionImplSync<Parts>,
532
+ Slots extends AssertionSlots<Parts> = AssertionSlots<Parts>,
533
+ > extends Assertion<Parts, Impl, Slots> {
534
+ /**
535
+ * Execute the assertion implementation synchronously.
536
+ *
537
+ * @param parsedValues Parameters for the assertion implementation
538
+ * @param args Raw parameters passed to `expectSync()`
539
+ * @param stackStartFn Function to use as stack start for error reporting
540
+ * @param parseResult Optional parse result containing cached validation data
541
+ */
542
+ execute(
543
+ parsedValues: ParsedValues<Parts>,
544
+ args: unknown[],
545
+ stackStartFn: (...args: any[]) => any,
546
+ parseResult?: ParsedResult<Parts>,
547
+ ): void;
548
+
549
+ /**
550
+ * Parses raw arguments synchronously against this assertion's slots to
551
+ * determine if they match this assertion.
552
+ *
553
+ * @param args Raw arguments provided to `expectSync()`
554
+ * @returns Result of parsing attempt
555
+ */
556
+ parseValues<Args extends readonly unknown[]>(args: Args): ParsedResult<Parts>;
557
+ }
558
+
559
+ /**
560
+ * The base structure for parsed assertion results.
561
+ *
562
+ * @knipignore
563
+ */
564
+ export interface BaseParsedResult<Parts extends AssertionParts> {
565
+ /**
566
+ * If success is `true`, then this will be `true` if all args matched the
567
+ * slots _and_ none of those args infer as `unknown` or `any`.
568
+ */
569
+ exactMatch?: boolean;
570
+
571
+ /**
572
+ * Present only if `success` is `true`. The parsed values mapped to the slots
573
+ * of {@link assertion}.
574
+ */
575
+ parsedValues?: ParsedValues<Parts>;
576
+
577
+ /**
578
+ * Whether the args were successfully parsed against the slots of
579
+ * {@link assertion}.
580
+ */
581
+ success: boolean;
582
+ }
583
+
584
+ /**
585
+ * Type for extracting individual builtin async assertion types.
586
+ *
587
+ * This type extracts the element types from the builtin async assertions array,
588
+ * providing a union of all available async assertion types in the framework.
589
+ *
590
+ * @see {@link BuiltinAsyncAssertions} for the full array type
591
+ * @see {@link AsyncAssertions} for the actual assertion implementations
592
+ */
593
+ export type BuiltinAsyncAssertion = ArrayValues<BuiltinAsyncAssertions>;
594
+
595
+ /**
596
+ * Type representing the collection of all builtin async assertions.
597
+ *
598
+ * This type represents the compile-time type of the `AsyncAssertions` constant,
599
+ * providing type information for all async assertion implementations included
600
+ * in the framework by default.
601
+ *
602
+ * @see {@link AsyncAssertions} for the actual assertion implementations
603
+ * @see {@link BuiltinAsyncAssertion} for individual assertion types
604
+ */
605
+ export type BuiltinAsyncAssertions = typeof AsyncAssertions;
606
+
607
+ /**
608
+ * Type for extracting individual builtin sync assertion types.
609
+ *
610
+ * This type extracts the element types from the builtin sync assertions array,
611
+ * providing a union of all available synchronous assertion types in the
612
+ * framework.
613
+ *
614
+ * @see {@link BuiltinSyncAssertions} for the full array type
615
+ * @see {@link SyncAssertions} for the actual assertion implementations
616
+ */
617
+ export type BuiltinSyncAssertion = ArrayValues<BuiltinSyncAssertions>;
618
+
619
+ /**
620
+ * Type representing the collection of all builtin sync assertions.
621
+ *
622
+ * This type represents the compile-time type of the `SyncAssertions` constant,
623
+ * providing type information for all synchronous assertion implementations
624
+ * included in the framework by default.
625
+ *
626
+ * @see {@link SyncAssertions} for the actual assertion implementations
627
+ * @see {@link BuiltinSyncAssertion} for individual assertion types
628
+ */
629
+ export type BuiltinSyncAssertions = typeof SyncAssertions;
630
+
631
+ /**
632
+ * Utility type for parsed values that may be empty.
633
+ *
634
+ * This type processes assertion parts recursively to produce parsed values,
635
+ * handling the case where no assertion parts are present (resulting in an empty
636
+ * tuple). It uses `NoNeverTuple` to filter out `never` types that may arise
637
+ * during the recursive processing.
638
+ *
639
+ * @typeParam Parts - The assertion parts to process
640
+ * @see {@link ParsedValues} for the standard parsed values type
641
+ * @see {@link NoNeverTuple} for never-type filtering
642
+ */
643
+ export type MaybeEmptyParsedValues<Parts extends readonly AssertionPart[]> =
644
+ NoNeverTuple<
645
+ Parts extends readonly [
646
+ infer First extends AssertionPart,
647
+ ...infer Rest extends readonly AssertionPart[],
648
+ ]
649
+ ? First extends PhraseLiteral | PhraseLiteralChoice
650
+ ? readonly [
651
+ unknown,
652
+ AssertionImplPart<First>,
653
+ ...AssertionImplParts<Rest>,
654
+ ]
655
+ : readonly [AssertionImplPart<First>, ...AssertionImplParts<Rest>]
656
+ : readonly []
657
+ >;
658
+
659
+ /**
660
+ * Utility type that removes `never` entries from a tuple while preserving tuple
661
+ * structure.
662
+ *
663
+ * This recursive type filters out `never` types from tuple types, which can
664
+ * occur during type-level transformations. It maintains the readonly tuple
665
+ * structure while removing invalid entries.
666
+ *
667
+ * @example
668
+ *
669
+ * ```ts
670
+ * type WithNever = readonly [string, never, number, never];
671
+ * type Filtered = NoNeverTuple<WithNever>; // readonly [string, number]
672
+ *
673
+ * type Empty = NoNeverTuple<readonly [never, never]>; // readonly []
674
+ * type Mixed = NoNeverTuple<readonly [boolean, never, string]>; // readonly [boolean, string]
675
+ * ```
676
+ *
677
+ * @typeParam T - The readonly tuple type to filter
678
+ * @see {@link AssertionPartsToSlots} for usage in slot processing
679
+ * @see {@link AssertionSlots} for filtered slot tuples
680
+ */
681
+ export type NoNeverTuple<T extends readonly unknown[]> = T extends readonly [
682
+ infer First,
683
+ ...infer Rest,
684
+ ]
685
+ ? [First] extends [never]
686
+ ? readonly [...NoNeverTuple<Rest>]
687
+ : readonly [First, ...NoNeverTuple<Rest>]
688
+ : readonly [];
689
+ /**
690
+ * Union type representing the result of parsing assertion arguments.
691
+ *
692
+ * This represents either a successful parse (containing validated arguments) or
693
+ * a parse failure (indicating arguments don't match the assertion). Used by
694
+ * `parseValues()` and `parseValuesAsync()` methods to communicate whether the
695
+ * assertion can be executed with the given arguments.
696
+ *
697
+ * @example
698
+ *
699
+ * ```ts
700
+ * // Successful parse
701
+ * const success: ParsedResult<Parts> = {
702
+ * success: true,
703
+ * exactMatch: true,
704
+ * parsedValues: [subject, ...params],
705
+ * };
706
+ *
707
+ * // Parse failure
708
+ * const failure: ParsedResult<Parts> = {
709
+ * success: false,
710
+ * };
711
+ * ```
712
+ *
713
+ * @typeParam Parts - The assertion parts tuple defining expected structure
714
+ * @see {@link ParsedResultSuccess} for successful parse results
715
+ * @see {@link ParsedResultFailure} for failed parse results
716
+ * @see {@link AssertionSync.parseValues} and {@link AssertionAsync.parseValuesAsync} for usage context
717
+ */
718
+ export type ParsedResult<Parts extends AssertionParts = AssertionParts> =
719
+ | ParsedResultFailure
720
+ | ParsedResultSuccess<Parts>;
721
+
722
+ /**
723
+ * Interface representing a failed argument parsing attempt.
724
+ *
725
+ * When assertion arguments don't match the expected slots (wrong number of
726
+ * arguments, type mismatches, phrase literal mismatches), parsing fails and
727
+ * returns this interface. The assertion cannot be executed with the provided
728
+ * arguments.
729
+ *
730
+ * @see {@link ParsedResultSuccess} for successful parsing results
731
+ * @see {@link BaseParsedResult} for shared result properties
732
+ */
733
+ export interface ParsedResultFailure extends BaseParsedResult<never> {
734
+ exactMatch?: never;
735
+ parsedValues?: never;
736
+ success: false;
737
+ }
738
+
739
+ /**
740
+ * Interface representing a successful argument parsing attempt.
741
+ *
742
+ * When assertion arguments successfully match the expected slots, this
743
+ * interface contains the validated arguments and metadata about the match
744
+ * quality. The assertion can be executed using the `parsedValues`.
745
+ *
746
+ * @typeParam Parts - The assertion parts tuple defining the expected structure
747
+ * @see {@link ParsedResultFailure} for failed parsing results
748
+ * @see {@link BaseParsedResult} for shared result properties
749
+ */
750
+ export interface ParsedResultSuccess<Parts extends AssertionParts>
751
+ extends BaseParsedResult<Parts> {
752
+ exactMatch: boolean;
753
+ parsedValues: ParsedValues<Parts>;
754
+ /**
755
+ * Optional cached subject validation result for optimized schema assertions.
756
+ * When present, indicates that subject validation was already performed
757
+ * during parseValues() and doesn't need to be repeated in execute().
758
+ */
759
+ subjectValidationResult?:
760
+ | {
761
+ data: any;
762
+ success: true;
763
+ }
764
+ | {
765
+ error: z.ZodError;
766
+ success: false;
767
+ };
768
+ success: true;
769
+ }
770
+
771
+ /**
772
+ * Type extracting the subject (first argument) from parsed assertion values.
773
+ *
774
+ * This utility type extracts the subject of an assertion from the parsed values
775
+ * tuple. The subject is always the first element and represents the value being
776
+ * tested by the assertion.
777
+ *
778
+ * @example
779
+ *
780
+ * ```ts
781
+ * // For assertion: expect(value, 'to be a string')
782
+ * type Subject = ParsedSubject<Parts>; // typeof value
783
+ *
784
+ * // For assertion: expect(42, 'to be greater than', 10)
785
+ * type NumericSubject = ParsedSubject<NumericParts>; // number
786
+ * ```
787
+ *
788
+ * @typeParam Parts - The assertion parts tuple defining the assertion structure
789
+ * @see {@link ParsedValues} for the complete parsed values tuple
790
+ * @see {@link AssertionImpl} for how subjects are used in implementations
791
+ */
792
+ export type ParsedSubject<Parts extends AssertionParts> =
793
+ ParsedValues<Parts> extends readonly [infer Subject, ...any[]]
794
+ ? Subject
795
+ : never;
796
+
797
+ /**
798
+ * Tuple type containing validated arguments for assertion execution.
799
+ *
800
+ * This represents the final processed arguments that will be passed to an
801
+ * assertion implementation function. The tuple contains the subject (first)
802
+ * followed by any additional parameters, with phrase literals filtered out
803
+ * since they're not passed to implementations.
804
+ *
805
+ * @example
806
+ *
807
+ * ```ts
808
+ * // For assertion: expect(value, 'to be greater than', 10)
809
+ * // ParsedValues = [typeof value, 10] (phrase literal removed)
810
+ *
811
+ * // For assertion: expect(obj, 'to satisfy', shape)
812
+ * // ParsedValues = [typeof obj, typeof shape]
813
+ * ```
814
+ *
815
+ * @typeParam Parts - The assertion parts tuple defining the expected structure
816
+ * @see {@link ParsedSubject} for extracting just the subject
817
+ * @see {@link MaybeEmptyParsedValues} for the underlying value processing
818
+ * @see {@link AssertionImpl} for how these values are consumed
819
+ */
820
+ export type ParsedValues<Parts extends AssertionParts = AssertionParts> =
821
+ MaybeEmptyParsedValues<Parts> extends readonly []
822
+ ? never
823
+ : MaybeEmptyParsedValues<Parts>;
824
+
825
+ /**
826
+ * Union type combining both phrase literal types.
827
+ *
828
+ * A phrase represents the natural language portion of an assertion that
829
+ * describes the expected behavior. It can be either a single string literal or
830
+ * a choice between multiple string literals.
831
+ *
832
+ * @example
833
+ *
834
+ * ```ts
835
+ * // Single phrase literal
836
+ * type Phrase1 = PhraseLiteral; // "to be a string"
837
+ *
838
+ * // Choice phrase literal
839
+ * type Phrase2 = PhraseLiteralChoice; // ["to be", "to equal"]
840
+ * ```
841
+ *
842
+ * @see {@link PhraseLiteral} for single string phrases
843
+ * @see {@link PhraseLiteralChoice} for choice-based phrases
844
+ * @see {@link AssertionPart} for how phrases fit into assertion structure
845
+ */
846
+ export type Phrase = PhraseLiteral | PhraseLiteralChoice;
847
+
848
+ /**
849
+ * Type representing a single phrase literal string.
850
+ *
851
+ * This is a string literal that `expect()` will match exactly in its parameter
852
+ * position. The phrase describes the natural language expectation for the
853
+ * assertion. If the first item in assertion parts is a phrase literal, a
854
+ * subject slot (`unknown`) is automatically added.
855
+ *
856
+ * Phrases cannot start with "not " as this would conflict with negation logic.
857
+ *
858
+ * @example
859
+ *
860
+ * ```ts
861
+ * // Valid phrase literals
862
+ * type Phrase1 = 'to be a string';
863
+ * type Phrase2 = 'to have length';
864
+ * type Phrase3 = 'to contain';
865
+ *
866
+ * // Usage in assertion
867
+ * createAssertion(['to be a string'], z.string());
868
+ * // expect(value, 'to be a string') ✓
869
+ * ```
870
+ *
871
+ * @see {@link PhraseLiteralChoice} for multi-option phrases
872
+ * @see {@link PhraseLiteralSlot} for compiled slot representation
873
+ * @see {@link AssertionPart} for how phrases fit into assertion structure
874
+ */
875
+ export type PhraseLiteral = string;
876
+
877
+ /**
878
+ * Type representing a choice between multiple phrase literals.
879
+ *
880
+ * This allows an assertion to accept any of several equivalent phrase options,
881
+ * providing flexibility in natural language expression. The type is a non-empty
882
+ * readonly tuple of strings.
883
+ *
884
+ * @example
885
+ *
886
+ * ```ts
887
+ * // Choice phrase literal
888
+ * type Choice = ['to be', 'to equal'];
889
+ *
890
+ * // Usage in assertion
891
+ * createAssertion(
892
+ * [z.any(), ['to be', 'to equal'], z.any()],
893
+ * (subject, expected) => subject === expected,
894
+ * );
895
+ *
896
+ * // Both work:
897
+ * // expect(value, 'to be', expected) ✓
898
+ * // expect(value, 'to equal', expected) ✓
899
+ * ```
900
+ *
901
+ * @see {@link PhraseLiteral} for single phrase options
902
+ * @see {@link PhraseLiteralChoiceSlot} for compiled slot representation
903
+ * @see {@link AssertionPart} for how phrases fit into assertion structure
904
+ */
905
+ export type PhraseLiteralChoice = NonEmptyTuple<string>;
906
+
907
+ /**
908
+ * Branded Zod type representing a compiled choice phrase slot.
909
+ *
910
+ * This is the runtime representation of a {@link PhraseLiteralChoice} that has
911
+ * been processed into a validation slot. It includes metadata about the
912
+ * available choice values for runtime phrase matching.
913
+ *
914
+ * @privateRemarks
915
+ * The `__values` property might be redundant since values should be derivable
916
+ * from the ZodLiteral metadata, but it provides type-level access to the
917
+ * choices.
918
+ * @typeParam H - The readonly tuple of string choices
919
+ * @see {@link PhraseLiteralChoice} for the source type
920
+ * @see {@link PhraseLiteralSlot} for single phrase slots
921
+ * @see {@link AssertionSlot} for slot type mapping
922
+ */
923
+ export type PhraseLiteralChoiceSlot<H extends readonly [string, ...string[]]> =
924
+ z.core.$ZodBranded<z.ZodType, 'string-literal'> & {
925
+ readonly __values: H;
926
+ };
927
+ /**
928
+ * Branded Zod type representing a compiled phrase literal slot.
929
+ *
930
+ * This is the runtime representation of a {@link PhraseLiteral} that has been
931
+ * processed into a validation slot. The slot is branded with 'string-literal'
932
+ * to distinguish it from regular string validation during assertion matching.
933
+ *
934
+ * @privateRemarks
935
+ * This type might be redundant since the value should be derivable from the
936
+ * ZodLiteral's value property, but it provides type-level access to the
937
+ * literal.
938
+ * @typeParam T - The string literal type
939
+ * @see {@link PhraseLiteral} for the source type
940
+ * @see {@link PhraseLiteralChoiceSlot} for choice phrase slots
941
+ * @see {@link AssertionSlot} for slot type mapping
942
+ */
943
+ export type PhraseLiteralSlot<T extends string> = z.core.$ZodBranded<
944
+ z.ZodLiteral<T>,
945
+ 'string-literal'
946
+ >; /**
947
+ * Object which can returned by assertion implementation functions to provide
948
+ * contextual information to an `AssertionError`
949
+ */
950
+
951
+ /**
952
+ * Type for a raw (unbranded) synchronous schema assertion implementation.
953
+ *
954
+ * This represents a standard Zod schema without branding that validates the
955
+ * assertion subject synchronously. Unlike {@link AssertionImplSchemaSync}, this
956
+ * type is not branded and represents the underlying schema before it is
957
+ * processed by the assertion creation system.
958
+ *
959
+ * @typeParam Parts - The assertion parts tuple defining the assertion structure
960
+ * @see {@link AssertionImplSchemaSync} for the branded version
961
+ * @see {@link ParsedSubject} for subject type derivation
962
+ */
963
+ export type RawAssertionImplSchemaSync<Parts extends AssertionParts> =
964
+ z.ZodType<ParsedSubject<Parts>>;