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.
- package/CHANGELOG.md +20 -0
- package/LICENSE.md +55 -0
- package/README.md +170 -0
- package/package.json +164 -0
- package/src/api.ts +149 -0
- package/src/assertion/assertion-async.ts +203 -0
- package/src/assertion/assertion-sync.ts +351 -0
- package/src/assertion/assertion-types.ts +964 -0
- package/src/assertion/assertion.ts +234 -0
- package/src/assertion/create.ts +226 -0
- package/src/assertion/impl/README.md +13 -0
- package/src/assertion/impl/async.ts +284 -0
- package/src/assertion/impl/index.ts +2 -0
- package/src/assertion/impl/sync-basic.ts +111 -0
- package/src/assertion/impl/sync-collection.ts +108 -0
- package/src/assertion/impl/sync-esoteric.ts +25 -0
- package/src/assertion/impl/sync-parametric.ts +488 -0
- package/src/assertion/impl/sync.ts +29 -0
- package/src/assertion/index.ts +15 -0
- package/src/assertion/slotify.ts +89 -0
- package/src/bootstrap.ts +55 -0
- package/src/constant.ts +37 -0
- package/src/error.ts +47 -0
- package/src/expect.ts +364 -0
- package/src/guards.ts +223 -0
- package/src/index.ts +29 -0
- package/src/metadata.ts +60 -0
- package/src/schema.md +15 -0
- package/src/schema.ts +464 -0
- package/src/types.ts +159 -0
- package/src/use.ts +63 -0
- package/src/util.ts +264 -0
|
@@ -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>>;
|