@isentinel/jest-roblox 0.2.1 → 0.2.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.
@@ -57,7 +57,7 @@ type Argv = Partial<{
57
57
  version: boolean;
58
58
  }>;
59
59
  //#endregion
60
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/is-any.d.ts
60
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/is-any.d.ts
61
61
  /**
62
62
  Returns a boolean for whether the given type is `any`.
63
63
 
@@ -72,8 +72,8 @@ import type {IsAny} from 'type-fest';
72
72
  const typedObject = {a: 1, b: 2} as const;
73
73
  const anyObject: any = {a: 1, b: 2};
74
74
 
75
- function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(obj: O, key: K) {
76
- return obj[key];
75
+ function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(object: O, key: K) {
76
+ return object[key];
77
77
  }
78
78
 
79
79
  const typedA = get(typedObject, 'a');
@@ -88,7 +88,7 @@ const anyA = get(anyObject, 'a');
88
88
  */
89
89
  type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false;
90
90
  //#endregion
91
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/is-optional-key-of.d.ts
91
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/is-optional-key-of.d.ts
92
92
  /**
93
93
  Returns a boolean for whether the given key is an optional key of type.
94
94
 
@@ -98,17 +98,17 @@ This is useful when writing utility types or schema validators that need to diff
98
98
  ```
99
99
  import type {IsOptionalKeyOf} from 'type-fest';
100
100
 
101
- interface User {
101
+ type User = {
102
102
  name: string;
103
103
  surname: string;
104
104
 
105
105
  luckyNumber?: number;
106
- }
106
+ };
107
107
 
108
- interface Admin {
108
+ type Admin = {
109
109
  name: string;
110
110
  surname?: string;
111
- }
111
+ };
112
112
 
113
113
  type T1 = IsOptionalKeyOf<User, 'luckyNumber'>;
114
114
  //=> true
@@ -131,7 +131,7 @@ type T5 = IsOptionalKeyOf<User | Admin, 'surname'>;
131
131
  */
132
132
  type IsOptionalKeyOf<Type extends object, Key extends keyof Type> = IsAny<Type | Key> extends true ? never : Key extends keyof Type ? Type extends Record<Key, Type[Key]> ? false : true : false;
133
133
  //#endregion
134
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/optional-keys-of.d.ts
134
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/optional-keys-of.d.ts
135
135
  /**
136
136
  Extract all optional keys from the given type.
137
137
 
@@ -141,12 +141,12 @@ This is useful when you want to create a new type that contains different type v
141
141
  ```
142
142
  import type {OptionalKeysOf, Except} from 'type-fest';
143
143
 
144
- interface User {
144
+ type User = {
145
145
  name: string;
146
146
  surname: string;
147
147
 
148
148
  luckyNumber?: number;
149
- }
149
+ };
150
150
 
151
151
  const REMOVE_FIELD = Symbol('remove field symbol');
152
152
  type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & {
@@ -154,12 +154,12 @@ type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKe
154
154
  };
155
155
 
156
156
  const update1: UpdateOperation<User> = {
157
- name: 'Alice'
157
+ name: 'Alice',
158
158
  };
159
159
 
160
160
  const update2: UpdateOperation<User> = {
161
161
  name: 'Bob',
162
- luckyNumber: REMOVE_FIELD
162
+ luckyNumber: REMOVE_FIELD,
163
163
  };
164
164
  ```
165
165
 
@@ -169,7 +169,7 @@ type OptionalKeysOf<Type extends object> = Type extends unknown // For distribut
169
169
  ? (keyof { [Key in keyof Type as IsOptionalKeyOf<Type, Key> extends false ? never : Key]: never }) & keyof Type // Intersect with `keyof Type` to ensure result of `OptionalKeysOf<Type>` is always assignable to `keyof Type`
170
170
  : never;
171
171
  //#endregion
172
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/required-keys-of.d.ts
172
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/required-keys-of.d.ts
173
173
  /**
174
174
  Extract all required keys from the given type.
175
175
 
@@ -179,17 +179,23 @@ This is useful when you want to create a new type that contains different type v
179
179
  ```
180
180
  import type {RequiredKeysOf} from 'type-fest';
181
181
 
182
- declare function createValidation<Entity extends object, Key extends RequiredKeysOf<Entity> = RequiredKeysOf<Entity>>(field: Key, validator: (value: Entity[Key]) => boolean): ValidatorFn;
182
+ declare function createValidation<
183
+ Entity extends object,
184
+ Key extends RequiredKeysOf<Entity> = RequiredKeysOf<Entity>,
185
+ >(field: Key, validator: (value: Entity[Key]) => boolean): (entity: Entity) => boolean;
183
186
 
184
- interface User {
187
+ type User = {
185
188
  name: string;
186
189
  surname: string;
187
-
188
190
  luckyNumber?: number;
189
- }
191
+ };
190
192
 
191
193
  const validator1 = createValidation<User>('name', value => value.length < 25);
192
194
  const validator2 = createValidation<User>('surname', value => value.length < 25);
195
+
196
+ // @ts-expect-error
197
+ const validator3 = createValidation<User>('luckyNumber', value => value > 0);
198
+ // Error: Argument of type '"luckyNumber"' is not assignable to parameter of type '"name" | "surname"'.
193
199
  ```
194
200
 
195
201
  @category Utilities
@@ -197,7 +203,7 @@ const validator2 = createValidation<User>('surname', value => value.length < 25)
197
203
  type RequiredKeysOf<Type extends object> = Type extends unknown // For distributing `Type`
198
204
  ? Exclude<keyof Type, OptionalKeysOf<Type>> : never;
199
205
  //#endregion
200
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/is-never.d.ts
206
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/is-never.d.ts
201
207
  /**
202
208
  Returns a boolean for whether the given type is `never`.
203
209
 
@@ -211,29 +217,41 @@ Useful in type utilities, such as checking if something does not occur.
211
217
  ```
212
218
  import type {IsNever, And} from 'type-fest';
213
219
 
214
- // https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
215
- type AreStringsEqual<A extends string, B extends string> =
216
- And<
217
- IsNever<Exclude<A, B>> extends true ? true : false,
218
- IsNever<Exclude<B, A>> extends true ? true : false
219
- >;
220
-
221
- type EndIfEqual<I extends string, O extends string> =
222
- AreStringsEqual<I, O> extends true
223
- ? never
224
- : void;
225
-
226
- function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
227
- if (input === output) {
228
- process.exit(0);
229
- }
230
- }
220
+ type A = IsNever<never>;
221
+ //=> true
222
+
223
+ type B = IsNever<any>;
224
+ //=> false
225
+
226
+ type C = IsNever<unknown>;
227
+ //=> false
228
+
229
+ type D = IsNever<never[]>;
230
+ //=> false
231
+
232
+ type E = IsNever<object>;
233
+ //=> false
231
234
 
232
- endIfEqual('abc', 'abc');
235
+ type F = IsNever<string>;
236
+ //=> false
237
+ ```
238
+
239
+ @example
240
+ ```
241
+ import type {IsNever} from 'type-fest';
242
+
243
+ type IsTrue<T> = T extends true ? true : false;
244
+
245
+ // When a distributive conditional is instantiated with `never`, the entire conditional results in `never`.
246
+ type A = IsTrue<never>;
233
247
  //=> never
234
248
 
235
- endIfEqual('abc', '123');
236
- //=> void
249
+ // If you don't want that behaviour, you can explicitly add an `IsNever` check before the distributive conditional.
250
+ type IsTrueFixed<T> =
251
+ IsNever<T> extends true ? false : T extends true ? true : false;
252
+
253
+ type B = IsTrueFixed<never>;
254
+ //=> false
237
255
  ```
238
256
 
239
257
  @category Type Guard
@@ -241,7 +259,7 @@ endIfEqual('abc', '123');
241
259
  */
242
260
  type IsNever<T> = [T] extends [never] ? true : false;
243
261
  //#endregion
244
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/if.d.ts
262
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/if.d.ts
245
263
  /**
246
264
  An if-else-like type that resolves depending on whether the given `boolean` type is `true` or `false`.
247
265
 
@@ -254,7 +272,7 @@ Note:
254
272
 
255
273
  @example
256
274
  ```
257
- import {If} from 'type-fest';
275
+ import type {If} from 'type-fest';
258
276
 
259
277
  type A = If<true, 'yes', 'no'>;
260
278
  //=> 'yes'
@@ -274,7 +292,7 @@ type E = If<never, 'yes', 'no'>;
274
292
 
275
293
  @example
276
294
  ```
277
- import {If, IsAny, IsNever} from 'type-fest';
295
+ import type {If, IsAny, IsNever} from 'type-fest';
278
296
 
279
297
  type A = If<IsAny<unknown>, 'is any', 'not any'>;
280
298
  //=> 'not any'
@@ -285,7 +303,7 @@ type B = If<IsNever<never>, 'is never', 'not never'>;
285
303
 
286
304
  @example
287
305
  ```
288
- import {If, IsEqual} from 'type-fest';
306
+ import type {If, IsEqual} from 'type-fest';
289
307
 
290
308
  type IfEqual<T, U, IfBranch, ElseBranch> = If<IsEqual<T, U>, IfBranch, ElseBranch>;
291
309
 
@@ -336,7 +354,7 @@ type Works = IncludesWithoutIf<HundredZeroes, '1'>;
336
354
  */
337
355
  type If<Type extends boolean, IfBranch, ElseBranch> = IsNever<Type> extends true ? ElseBranch : Type extends true ? IfBranch : ElseBranch;
338
356
  //#endregion
339
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/simplify.d.ts
357
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/simplify.d.ts
340
358
  /**
341
359
  Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
342
360
 
@@ -382,10 +400,11 @@ const literal = {foo: 123, bar: 'hello', baz: 456};
382
400
  const someType: SomeType = literal;
383
401
  const someInterface: SomeInterface = literal;
384
402
 
385
- function fn(object: Record<string, unknown>): void {}
403
+ declare function fn(object: Record<string, unknown>): void;
386
404
 
387
405
  fn(literal); // Good: literal object type is sealed
388
406
  fn(someType); // Good: type is sealed
407
+ // @ts-expect-error
389
408
  fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened
390
409
  fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type`
391
410
  ```
@@ -396,7 +415,7 @@ fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface`
396
415
  */
397
416
  type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};
398
417
  //#endregion
399
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/is-equal.d.ts
418
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/is-equal.d.ts
400
419
  /**
401
420
  Returns a boolean for whether the two given types are equal.
402
421
 
@@ -423,11 +442,11 @@ type Includes<Value extends readonly any[], Item> =
423
442
  @category Type Guard
424
443
  @category Utilities
425
444
  */
426
- type IsEqual<A, B> = [A, B] extends [infer AA, infer BB] ? [AA] extends [never] ? [BB] extends [never] ? true : false : [BB] extends [never] ? false : _IsEqual<AA, BB> : false;
445
+ type IsEqual<A, B> = [A] extends [B] ? [B] extends [A] ? _IsEqual<A, B> : false : false;
427
446
  // This version fails the `equalWrappedTupleIntersectionToBeNeverAndNeverExpanded` test in `test-d/is-equal.ts`.
428
447
  type _IsEqual<A, B> = (<G>() => G extends A & G | G ? 1 : 2) extends (<G>() => G extends B & G | G ? 1 : 2) ? true : false;
429
448
  //#endregion
430
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/omit-index-signature.d.ts
449
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/omit-index-signature.d.ts
431
450
  /**
432
451
  Omit any index signatures from the given object type, leaving only explicitly defined properties.
433
452
 
@@ -445,8 +464,9 @@ It relies on the fact that an empty object (`{}`) is assignable to an object wit
445
464
  ```
446
465
  const indexed: Record<string, unknown> = {}; // Allowed
447
466
 
467
+ // @ts-expect-error
448
468
  const keyed: Record<'foo', unknown> = {}; // Error
449
- // => TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, bar
469
+ // TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, bar
450
470
  ```
451
471
 
452
472
  Instead of causing a type error like the above, you can also use a [conditional type](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html) to test whether a type is assignable to another:
@@ -455,19 +475,21 @@ Instead of causing a type error like the above, you can also use a [conditional
455
475
  type Indexed = {} extends Record<string, unknown>
456
476
  ? '✅ `{}` is assignable to `Record<string, unknown>`'
457
477
  : '❌ `{}` is NOT assignable to `Record<string, unknown>`';
458
- // => '✅ `{}` is assignable to `Record<string, unknown>`'
478
+
479
+ type IndexedResult = Indexed;
480
+ //=> '✅ `{}` is assignable to `Record<string, unknown>`'
459
481
 
460
482
  type Keyed = {} extends Record<'foo' | 'bar', unknown>
461
- ? "✅ `{}` is assignable to `Record<'foo' | 'bar', unknown>`"
462
- : "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`";
463
- // => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`"
483
+ ? '✅ `{}` is assignable to `Record<\'foo\' | \'bar\', unknown>`'
484
+ : '❌ `{}` is NOT assignable to `Record<\'foo\' | \'bar\', unknown>`';
485
+
486
+ type KeyedResult = Keyed;
487
+ //=> '❌ `{}` is NOT assignable to `Record<\'foo\' | \'bar\', unknown>`'
464
488
  ```
465
489
 
466
490
  Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each `KeyType` of `ObjectType`...
467
491
 
468
492
  ```
469
- import type {OmitIndexSignature} from 'type-fest';
470
-
471
493
  type OmitIndexSignature<ObjectType> = {
472
494
  [KeyType in keyof ObjectType // Map each key of `ObjectType`...
473
495
  ]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature<Foo> == Foo`.
@@ -477,14 +499,12 @@ type OmitIndexSignature<ObjectType> = {
477
499
  ...whether an empty object (`{}`) would be assignable to an object with that `KeyType` (`Record<KeyType, unknown>`)...
478
500
 
479
501
  ```
480
- import type {OmitIndexSignature} from 'type-fest';
481
-
482
502
  type OmitIndexSignature<ObjectType> = {
483
503
  [KeyType in keyof ObjectType
484
- // Is `{}` assignable to `Record<KeyType, unknown>`?
485
- as {} extends Record<KeyType, unknown>
486
- ? ... // ✅ `{}` is assignable to `Record<KeyType, unknown>`
487
- : ... // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>`
504
+ // Is `{}` assignable to `Record<KeyType, unknown>`?
505
+ as {} extends Record<KeyType, unknown>
506
+ ? never // ✅ `{}` is assignable to `Record<KeyType, unknown>`
507
+ : KeyType // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>`
488
508
  ]: ObjectType[KeyType];
489
509
  };
490
510
  ```
@@ -495,24 +515,24 @@ If `{}` is assignable, it means that `KeyType` is an index signature and we want
495
515
  ```
496
516
  import type {OmitIndexSignature} from 'type-fest';
497
517
 
498
- interface Example {
518
+ type Example = {
499
519
  // These index signatures will be removed.
500
- [x: string]: any
501
- [x: number]: any
502
- [x: symbol]: any
503
- [x: `head-${string}`]: string
504
- [x: `${string}-tail`]: string
505
- [x: `head-${string}-tail`]: string
506
- [x: `${bigint}`]: string
507
- [x: `embedded-${number}`]: string
520
+ [x: string]: any;
521
+ [x: number]: any;
522
+ [x: symbol]: any;
523
+ [x: `head-${string}`]: string;
524
+ [x: `${string}-tail`]: string;
525
+ [x: `head-${string}-tail`]: string;
526
+ [x: `${bigint}`]: string;
527
+ [x: `embedded-${number}`]: string;
508
528
 
509
529
  // These explicitly defined keys will remain.
510
530
  foo: 'bar';
511
531
  qux?: 'baz';
512
- }
532
+ };
513
533
 
514
534
  type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>;
515
- // => { foo: 'bar'; qux?: 'baz' | undefined; }
535
+ //=> {foo: 'bar'; qux?: 'baz'}
516
536
  ```
517
537
 
518
538
  @see {@link PickIndexSignature}
@@ -520,7 +540,7 @@ type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>;
520
540
  */
521
541
  type OmitIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? never : KeyType]: ObjectType[KeyType] };
522
542
  //#endregion
523
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/pick-index-signature.d.ts
543
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/pick-index-signature.d.ts
524
544
  /**
525
545
  Pick only index signatures from the given object type, leaving out all explicitly defined properties.
526
546
 
@@ -568,22 +588,47 @@ type ExampleIndexSignature = PickIndexSignature<Example>;
568
588
  */
569
589
  type PickIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? KeyType : never]: ObjectType[KeyType] };
570
590
  //#endregion
571
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/merge.d.ts
591
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/merge.d.ts
572
592
  // Merges two objects without worrying about index signatures.
573
- type SimpleMerge<Destination, Source> = { [Key in keyof Destination as Key extends keyof Source ? never : Key]: Destination[Key] } & Source;
593
+ type SimpleMerge<Destination, Source> = Simplify<{ [Key in keyof Destination as Key extends keyof Source ? never : Key]: Destination[Key] } & Source>;
574
594
  /**
575
595
  Merge two types into a new type. Keys of the second type overrides keys of the first type.
576
596
 
597
+ This is different from the TypeScript `&` (intersection) operator. With `&`, conflicting property types are intersected, which often results in `never`. For example, `{a: string} & {a: number}` makes `a` become `string & number`, which resolves to `never`. With `Merge`, the second type's keys cleanly override the first, so `Merge<{a: string}, {a: number}>` gives `{a: number}` as expected. `Merge` also produces a flattened type (via `Simplify`), making it more readable in IDE tooltips compared to `A & B`.
598
+
577
599
  @example
578
600
  ```
579
601
  import type {Merge} from 'type-fest';
580
602
 
581
- interface Foo {
603
+ type Foo = {
604
+ a: string;
605
+ b: number;
606
+ };
607
+
608
+ type Bar = {
609
+ a: number; // Conflicts with Foo['a']
610
+ c: boolean;
611
+ };
612
+
613
+ // With `&`, `a` becomes `string & number` which is `never`. Not what you want.
614
+ type WithIntersection = (Foo & Bar)['a'];
615
+ //=> never
616
+
617
+ // With `Merge`, `a` is cleanly overridden to `number`.
618
+ type WithMerge = Merge<Foo, Bar>['a'];
619
+ //=> number
620
+ ```
621
+
622
+ @example
623
+ ```
624
+ import type {Merge} from 'type-fest';
625
+
626
+ type Foo = {
582
627
  [x: string]: unknown;
583
628
  [x: number]: unknown;
584
629
  foo: string;
585
630
  bar: symbol;
586
- }
631
+ };
587
632
 
588
633
  type Bar = {
589
634
  [x: number]: number;
@@ -593,7 +638,7 @@ type Bar = {
593
638
  };
594
639
 
595
640
  export type FooBar = Merge<Foo, Bar>;
596
- // => {
641
+ //=> {
597
642
  // [x: string]: unknown;
598
643
  // [x: number]: number;
599
644
  // [x: symbol]: unknown;
@@ -603,11 +648,19 @@ export type FooBar = Merge<Foo, Bar>;
603
648
  // }
604
649
  ```
605
650
 
651
+ Note: If you want a merge type that more accurately reflects the runtime behavior of object spread or `Object.assign`, refer to the {@link ObjectMerge} type.
652
+
653
+ @see {@link ObjectMerge}
606
654
  @category Object
607
655
  */
608
- type Merge<Destination, Source> = Simplify<SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>> & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>;
656
+ type Merge<Destination, Source> = Destination extends unknown // For distributing `Destination`
657
+ ? Source extends unknown // For distributing `Source`
658
+ ? If<IsEqual<Destination, Source>, Destination, _Merge<Destination, Source>> : never // Should never happen
659
+ : never;
660
+ // Should never happen
661
+ type _Merge<Destination, Source> = Simplify<SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>> & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>;
609
662
  //#endregion
610
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/internal/object.d.ts
663
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/internal/object.d.ts
611
664
  /**
612
665
  Merges user specified options with default options.
613
666
 
@@ -662,7 +715,7 @@ type Result = ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, SpecifiedOp
662
715
  */
663
716
  type ApplyDefaultOptions<Options extends object, Defaults extends Simplify<Omit<Required<Options>, RequiredKeysOf<Options>> & Partial<Record<RequiredKeysOf<Options>, never>>>, SpecifiedOptions extends Options> = If<IsAny<SpecifiedOptions>, Defaults, If<IsNever<SpecifiedOptions>, Defaults, Simplify<Merge<Defaults, { [Key in keyof SpecifiedOptions as Key extends OptionalKeysOf<Options> ? undefined extends SpecifiedOptions[Key] ? never : Key : Key]: SpecifiedOptions[Key] }> & Required<Options>>>>;
664
717
  //#endregion
665
- //#region node_modules/.pnpm/type-fest@5.2.0/node_modules/type-fest/source/except.d.ts
718
+ //#region node_modules/.pnpm/type-fest@5.5.0/node_modules/type-fest/source/except.d.ts
666
719
  /**
667
720
  Filter out keys from an object.
668
721
 
@@ -723,14 +776,16 @@ type Foo = {
723
776
  type FooWithoutA = Except<Foo, 'a'>;
724
777
  //=> {b: string}
725
778
 
779
+ // @ts-expect-error
726
780
  const fooWithoutA: FooWithoutA = {a: 1, b: '2'};
727
- //=> errors: 'a' does not exist in type '{ b: string; }'
781
+ // errors: 'a' does not exist in type '{ b: string; }'
728
782
 
729
783
  type FooWithoutB = Except<Foo, 'b', {requireExactProps: true}>;
730
- //=> {a: number} & Partial<Record<"b", never>>
784
+ //=> {a: number} & Partial<Record<'b', never>>
731
785
 
786
+ // @ts-expect-error
732
787
  const fooWithoutB: FooWithoutB = {a: 1, b: '2'};
733
- //=> errors at 'b': Type 'string' is not assignable to type 'undefined'.
788
+ // errors at 'b': Type 'string' is not assignable to type 'undefined'.
734
789
 
735
790
  // The `Omit` utility type doesn't work when omitting specific keys from objects containing index signatures.
736
791
 
@@ -745,12 +800,12 @@ type UserData = {
745
800
 
746
801
  // `Omit` clearly doesn't behave as expected in this case:
747
802
  type PostPayload = Omit<UserData, 'email'>;
748
- //=> type PostPayload = { [x: string]: string; [x: number]: string; }
803
+ //=> {[x: string]: string; [x: number]: string}
749
804
 
750
805
  // In situations like this, `Except` works better.
751
806
  // It simply removes the `email` key while preserving all the other keys.
752
- type PostPayload = Except<UserData, 'email'>;
753
- //=> type PostPayload = { [x: string]: string; name: string; role: 'admin' | 'user'; }
807
+ type PostPayloadFixed = Except<UserData, 'email'>;
808
+ //=> {[x: string]: string; name: string; role: 'admin' | 'user'}
754
809
  ```
755
810
 
756
811
  @category Object
@@ -825,6 +880,7 @@ interface Config extends Except<Argv, "projects" | "rootDir" | "setupFiles" | "s
825
880
  gameOutput?: string;
826
881
  jestPath?: string;
827
882
  luauRoots?: Array<string>;
883
+ parallel?: "auto" | number;
828
884
  passWithNoTests?: boolean;
829
885
  placeFile?: string;
830
886
  pollInterval?: number;
@@ -887,6 +943,7 @@ interface CliOptions {
887
943
  gameOutput?: string;
888
944
  help?: boolean;
889
945
  outputFile?: string;
946
+ parallel?: "auto" | number;
890
947
  passWithNoTests?: boolean;
891
948
  pollInterval?: number;
892
949
  port?: number;
@@ -1001,30 +1058,53 @@ interface ParseResult {
1001
1058
  coverageData?: RawCoverageData;
1002
1059
  luauTiming?: Record<string, number>;
1003
1060
  result: JestResult;
1061
+ setupSeconds?: number;
1004
1062
  snapshotWrites?: SnapshotWrites;
1005
1063
  }
1006
1064
  declare function extractJsonFromOutput(output: string): string | undefined;
1007
1065
  declare function parseJestOutput(output: string): ParseResult;
1008
1066
  //#endregion
1009
1067
  //#region src/backends/interface.d.ts
1010
- interface BackendOptions {
1068
+ interface ProjectJob {
1011
1069
  config: ResolvedConfig;
1070
+ displayColor?: string;
1071
+ displayName: string;
1012
1072
  testFiles: Array<string>;
1013
1073
  }
1074
+ interface BackendOptions {
1075
+ jobs: Array<ProjectJob>;
1076
+ /**
1077
+ * Open-Cloud-only: number of concurrent Open Cloud Luau execution sessions
1078
+ * to fire. Unset or 1 means one session carrying all jobs. `"auto"` resolves
1079
+ * to min(jobs.length, 3). Studio backend must error when this is set to
1080
+ * anything other than undefined/1 (Phase 4 enforces at the CLI layer).
1081
+ */
1082
+ parallel?: "auto" | number;
1083
+ }
1014
1084
  interface BackendTiming {
1015
1085
  executionMs: number;
1016
1086
  uploadCached?: boolean;
1017
1087
  uploadMs?: number;
1018
1088
  }
1019
- interface BackendResult {
1089
+ interface ProjectBackendResult {
1020
1090
  coverageData?: RawCoverageData;
1091
+ displayColor?: string;
1092
+ displayName: string;
1093
+ elapsedMs: number;
1021
1094
  gameOutput?: string;
1022
1095
  luauTiming?: Record<string, number>;
1023
1096
  result: JestResult;
1097
+ setupMs?: number;
1024
1098
  snapshotWrites?: SnapshotWrites;
1099
+ }
1100
+ interface BackendResult {
1101
+ results: Array<ProjectBackendResult>;
1025
1102
  timing: BackendTiming;
1026
1103
  }
1104
+ type BackendKind = "open-cloud" | "studio";
1027
1105
  interface Backend {
1106
+ close?(): Promise<void> | void;
1107
+ readonly kind: BackendKind;
1028
1108
  runTests(options: BackendOptions): Promise<BackendResult>;
1029
1109
  }
1030
1110
  //#endregion
@@ -1051,6 +1131,7 @@ interface SourceMapper {
1051
1131
  interface TimingResult {
1052
1132
  coverageMs?: number;
1053
1133
  executionMs: number;
1134
+ setupMs?: number;
1054
1135
  startTime: number;
1055
1136
  testsMs: number;
1056
1137
  totalMs: number;
@@ -1083,6 +1164,12 @@ interface FormatOutputOptions {
1083
1164
  version: string;
1084
1165
  }
1085
1166
  declare function formatExecuteOutput(options: FormatOutputOptions): string;
1167
+ /**
1168
+ * Single-project convenience wrapper: builds a length-1 jobs array, fires
1169
+ * `executeBackend` once, and maps the single entry through
1170
+ * `processProjectResult`. Multi-project callers drive `executeBackend` +
1171
+ * `processProjectResult` directly from `cli.ts`.
1172
+ */
1086
1173
  declare function execute(options: ExecuteOptions): Promise<ExecuteResult>;
1087
1174
  //#endregion
1088
1175
  export { defineConfig as A, FormatterEntry as C, ROOT_ONLY_KEYS as D, ProjectTestConfig as E, Argv as M, ResolvedConfig as O, DisplayName as S, ProjectEntry as T, ResolvedProjectConfig as _, formatExecuteOutput as a, ConfigInput as b, Backend as c, extractJsonFromOutput as d, parseJestOutput as f, TestStatus as g, TestFileResult as h, execute as i, defineProject as j, SnapshotFormatOptions as k, BackendOptions as l, TestCaseResult as m, ExecuteResult as n, TimingResult as o, JestResult as p, FormatOutputOptions as r, SourceMapper as s, ExecuteOptions as t, BackendResult as u, CliOptions as v, InlineProjectConfig as w, DEFAULT_CONFIG as x, Config as y };