@seedcord/utils 0.3.8 → 0.4.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +490 -273
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -265
- package/dist/index.d.mts +759 -0
- package/dist/index.mjs +461 -254
- package/dist/index.mjs.map +1 -1
- package/package.json +24 -20
- package/dist/index.d.ts +0 -265
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,759 @@
|
|
|
1
|
+
import { ILogger } from "@seedcord/types";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
|
|
4
|
+
//#region src/misc/assertNever.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Exhaustiveness guard for discriminated unions. Place in the `default` branch of a `switch` over a
|
|
7
|
+
* union's discriminant: if a new variant is added without a matching case, the call fails to compile.
|
|
8
|
+
* Throws at runtime if reached with a value the types said was impossible.
|
|
9
|
+
*/
|
|
10
|
+
declare function assertNever(value: never): never;
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/misc/directory.d.ts
|
|
13
|
+
/**
|
|
14
|
+
* Determines if a directory entry is a TypeScript or JavaScript file.
|
|
15
|
+
*
|
|
16
|
+
* @param entry - The directory entry to check.
|
|
17
|
+
* @returns True if the entry is a file ending with .ts or .js.
|
|
18
|
+
*/
|
|
19
|
+
declare function isTsOrJsFile(entry: fs.Dirent): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Recursively traverses through a directory, importing all .ts and .js files and applying a callback to each import.
|
|
22
|
+
*
|
|
23
|
+
* @param dir - The directory path to traverse.
|
|
24
|
+
* @param callback - A function that will be called for each imported module. It receives the full file path, the file's relative path, and the imported module as arguments.
|
|
25
|
+
* @returns A Promise that resolves when the traversal is complete.
|
|
26
|
+
*/
|
|
27
|
+
declare function traverseDirectory(dir: string, callback: (fullPath: string, relativePath: string, imported: Record<string, unknown>) => Promise<void> | void, logger: ILogger): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Options for formatting file paths.
|
|
30
|
+
*/
|
|
31
|
+
interface FormatFileOptions {
|
|
32
|
+
/**
|
|
33
|
+
* Whether to return only the directory part of the path. {@default false}
|
|
34
|
+
*/
|
|
35
|
+
onlyDir?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* A prefix to prepend to the formatted path. {@default ./}
|
|
38
|
+
*/
|
|
39
|
+
prefix?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Formats a file path relative to the current working directory.
|
|
43
|
+
* @param filePath - The file path to format.
|
|
44
|
+
* @param options - Formatting options.
|
|
45
|
+
* @returns The formatted file path.
|
|
46
|
+
*/
|
|
47
|
+
declare function formatFilePath(filePath: string, options?: FormatFileOptions): string;
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/misc/fyShuffle.d.ts
|
|
50
|
+
/**
|
|
51
|
+
* Shuffles an array using the Fisher-Yates algorithm.
|
|
52
|
+
* This function creates a new array with the same elements in a random order,
|
|
53
|
+
* without modifying the original array.
|
|
54
|
+
*
|
|
55
|
+
* @typeParam TArray - The type of elements in the array
|
|
56
|
+
* @param items - The array to shuffle
|
|
57
|
+
* @returns A new array with the same elements in a random order
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const numbers = [1, 2, 3, 4, 5];
|
|
62
|
+
* const shuffled = fyShuffle(numbers);
|
|
63
|
+
* // shuffled might be [3, 1, 5, 2, 4]
|
|
64
|
+
* // numbers is still [1, 2, 3, 4, 5]
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
declare function fyShuffle<TArray>(items: TArray[]): TArray[];
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/numbers/currentTime.d.ts
|
|
70
|
+
/**
|
|
71
|
+
* Return current time in seconds
|
|
72
|
+
*/
|
|
73
|
+
declare function currentTime(): number;
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/numbers/generateCode.d.ts
|
|
76
|
+
/**
|
|
77
|
+
* Generates a random numeric code with the specified number of digits.
|
|
78
|
+
*
|
|
79
|
+
* @param digits - The number of digits for the generated code.
|
|
80
|
+
* @returns A random numeric code with the specified number of digits.
|
|
81
|
+
*/
|
|
82
|
+
declare function generateCode(digits: number): number;
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/numbers/ordinal.d.ts
|
|
85
|
+
/**
|
|
86
|
+
* Returns the ordinal suffix for a given number.
|
|
87
|
+
*
|
|
88
|
+
* @param n - The number to get the ordinal for
|
|
89
|
+
* @returns The number with its ordinal suffix
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ordinal(1); // "1st"
|
|
93
|
+
* ordinal(22); // "22nd"
|
|
94
|
+
* ordinal(13); // "13th"
|
|
95
|
+
*/
|
|
96
|
+
declare function ordinal(n: number): string;
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/numbers/percentage.d.ts
|
|
99
|
+
/**
|
|
100
|
+
* Takes two numbers and returns the percentage of the first number in the second number with two decimal places.
|
|
101
|
+
*
|
|
102
|
+
* @param num1 - The first number.
|
|
103
|
+
* @param num2 - The second number.
|
|
104
|
+
*
|
|
105
|
+
* @returns The percentage of the first number in the second number with two decimal places.
|
|
106
|
+
*/
|
|
107
|
+
declare function percentage(num1: number, num2: number): number;
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/numbers/round.d.ts
|
|
110
|
+
/**
|
|
111
|
+
* Rounds a number to a specified number of decimal places.
|
|
112
|
+
*
|
|
113
|
+
* @param num - The number to be rounded.
|
|
114
|
+
* @param precision - The number of decimal places to round to.
|
|
115
|
+
* @returns The rounded number.
|
|
116
|
+
*/
|
|
117
|
+
declare function round(num: number, precision: number): number;
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region ../../node_modules/.pnpm/type-fest@5.6.0/node_modules/type-fest/source/json-value.d.ts
|
|
120
|
+
/**
|
|
121
|
+
Matches any valid JSON primitive value.
|
|
122
|
+
|
|
123
|
+
@category JSON
|
|
124
|
+
*/
|
|
125
|
+
type JsonPrimitive = string | number | boolean | null;
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region ../../node_modules/.pnpm/type-fest@5.6.0/node_modules/type-fest/source/union-to-intersection.d.ts
|
|
128
|
+
/**
|
|
129
|
+
Convert a union type to an intersection type.
|
|
130
|
+
|
|
131
|
+
Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
|
|
132
|
+
|
|
133
|
+
@example
|
|
134
|
+
```
|
|
135
|
+
import type {UnionToIntersection} from 'type-fest';
|
|
136
|
+
|
|
137
|
+
type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
|
|
138
|
+
|
|
139
|
+
type Intersection = UnionToIntersection<Union>;
|
|
140
|
+
//=> {the(): void} & {great(arg: string): void} & {escape: boolean}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
@category Type
|
|
144
|
+
*/
|
|
145
|
+
type UnionToIntersection<Union> = (// `extends unknown` is always going to be the case and is used to convert the
|
|
146
|
+
// `Union` into a [distributive conditional
|
|
147
|
+
// type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
148
|
+
Union extends unknown // The union type is used as the only argument to a function since the union
|
|
149
|
+
// of function arguments is an intersection.
|
|
150
|
+
? (distributedUnion: Union) => void // This won't happen.
|
|
151
|
+
: never // Infer the `Intersection` type since TypeScript represents the positional
|
|
152
|
+
// arguments of unions of functions as an intersection of the union.
|
|
153
|
+
) extends ((mergedIntersection: infer Intersection) => void) // The `& Union` is to ensure result of `UnionToIntersection<A | B>` is always assignable to `A | B`
|
|
154
|
+
? Intersection & Union : never;
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region ../../node_modules/.pnpm/type-fest@5.6.0/node_modules/type-fest/source/is-any.d.ts
|
|
157
|
+
/**
|
|
158
|
+
Returns a boolean for whether the given type is `any`.
|
|
159
|
+
|
|
160
|
+
@link https://stackoverflow.com/a/49928360/1490091
|
|
161
|
+
|
|
162
|
+
Useful in type utilities, such as disallowing `any`s to be passed to a function.
|
|
163
|
+
|
|
164
|
+
@example
|
|
165
|
+
```
|
|
166
|
+
import type {IsAny} from 'type-fest';
|
|
167
|
+
|
|
168
|
+
const typedObject = {a: 1, b: 2} as const;
|
|
169
|
+
const anyObject: any = {a: 1, b: 2};
|
|
170
|
+
|
|
171
|
+
function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(object: O, key: K) {
|
|
172
|
+
return object[key];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const typedA = get(typedObject, 'a');
|
|
176
|
+
//=> 1
|
|
177
|
+
|
|
178
|
+
const anyA = get(anyObject, 'a');
|
|
179
|
+
//=> any
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
@category Type Guard
|
|
183
|
+
@category Utilities
|
|
184
|
+
*/
|
|
185
|
+
type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false;
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region ../../node_modules/.pnpm/type-fest@5.6.0/node_modules/type-fest/source/is-never.d.ts
|
|
188
|
+
/**
|
|
189
|
+
Returns a boolean for whether the given type is `never`.
|
|
190
|
+
|
|
191
|
+
@link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
|
|
192
|
+
@link https://stackoverflow.com/a/53984913/10292952
|
|
193
|
+
@link https://www.zhenghao.io/posts/ts-never
|
|
194
|
+
|
|
195
|
+
Useful in type utilities, such as checking if something does not occur.
|
|
196
|
+
|
|
197
|
+
@example
|
|
198
|
+
```
|
|
199
|
+
import type {IsNever, And} from 'type-fest';
|
|
200
|
+
|
|
201
|
+
type A = IsNever<never>;
|
|
202
|
+
//=> true
|
|
203
|
+
|
|
204
|
+
type B = IsNever<any>;
|
|
205
|
+
//=> false
|
|
206
|
+
|
|
207
|
+
type C = IsNever<unknown>;
|
|
208
|
+
//=> false
|
|
209
|
+
|
|
210
|
+
type D = IsNever<never[]>;
|
|
211
|
+
//=> false
|
|
212
|
+
|
|
213
|
+
type E = IsNever<object>;
|
|
214
|
+
//=> false
|
|
215
|
+
|
|
216
|
+
type F = IsNever<string>;
|
|
217
|
+
//=> false
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
@example
|
|
221
|
+
```
|
|
222
|
+
import type {IsNever} from 'type-fest';
|
|
223
|
+
|
|
224
|
+
type IsTrue<T> = T extends true ? true : false;
|
|
225
|
+
|
|
226
|
+
// When a distributive conditional is instantiated with `never`, the entire conditional results in `never`.
|
|
227
|
+
type A = IsTrue<never>;
|
|
228
|
+
//=> never
|
|
229
|
+
|
|
230
|
+
// If you don't want that behaviour, you can explicitly add an `IsNever` check before the distributive conditional.
|
|
231
|
+
type IsTrueFixed<T> =
|
|
232
|
+
IsNever<T> extends true ? false : T extends true ? true : false;
|
|
233
|
+
|
|
234
|
+
type B = IsTrueFixed<never>;
|
|
235
|
+
//=> false
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
@category Type Guard
|
|
239
|
+
@category Utilities
|
|
240
|
+
*/
|
|
241
|
+
type IsNever<T> = [T] extends [never] ? true : false;
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region ../../node_modules/.pnpm/type-fest@5.6.0/node_modules/type-fest/source/if.d.ts
|
|
244
|
+
/**
|
|
245
|
+
An if-else-like type that resolves depending on whether the given `boolean` type is `true` or `false`.
|
|
246
|
+
|
|
247
|
+
Use-cases:
|
|
248
|
+
- You can use this in combination with `Is*` types to create an if-else-like experience. For example, `If<IsAny<any>, 'is any', 'not any'>`.
|
|
249
|
+
|
|
250
|
+
Note:
|
|
251
|
+
- Returns a union of if branch and else branch if the given type is `boolean` or `any`. For example, `If<boolean, 'Y', 'N'>` will return `'Y' | 'N'`.
|
|
252
|
+
- Returns the else branch if the given type is `never`. For example, `If<never, 'Y', 'N'>` will return `'N'`.
|
|
253
|
+
|
|
254
|
+
@example
|
|
255
|
+
```
|
|
256
|
+
import type {If} from 'type-fest';
|
|
257
|
+
|
|
258
|
+
type A = If<true, 'yes', 'no'>;
|
|
259
|
+
//=> 'yes'
|
|
260
|
+
|
|
261
|
+
type B = If<false, 'yes', 'no'>;
|
|
262
|
+
//=> 'no'
|
|
263
|
+
|
|
264
|
+
type C = If<boolean, 'yes', 'no'>;
|
|
265
|
+
//=> 'yes' | 'no'
|
|
266
|
+
|
|
267
|
+
type D = If<any, 'yes', 'no'>;
|
|
268
|
+
//=> 'yes' | 'no'
|
|
269
|
+
|
|
270
|
+
type E = If<never, 'yes', 'no'>;
|
|
271
|
+
//=> 'no'
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
@example
|
|
275
|
+
```
|
|
276
|
+
import type {If, IsAny, IsNever} from 'type-fest';
|
|
277
|
+
|
|
278
|
+
type A = If<IsAny<unknown>, 'is any', 'not any'>;
|
|
279
|
+
//=> 'not any'
|
|
280
|
+
|
|
281
|
+
type B = If<IsNever<never>, 'is never', 'not never'>;
|
|
282
|
+
//=> 'is never'
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
@example
|
|
286
|
+
```
|
|
287
|
+
import type {If, IsEqual} from 'type-fest';
|
|
288
|
+
|
|
289
|
+
type IfEqual<T, U, IfBranch, ElseBranch> = If<IsEqual<T, U>, IfBranch, ElseBranch>;
|
|
290
|
+
|
|
291
|
+
type A = IfEqual<string, string, 'equal', 'not equal'>;
|
|
292
|
+
//=> 'equal'
|
|
293
|
+
|
|
294
|
+
type B = IfEqual<string, number, 'equal', 'not equal'>;
|
|
295
|
+
//=> 'not equal'
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Note: Sometimes using the `If` type can make an implementation non–tail-recursive, which can impact performance. In such cases, it’s better to use a conditional directly. Refer to the following example:
|
|
299
|
+
|
|
300
|
+
@example
|
|
301
|
+
```
|
|
302
|
+
import type {If, IsEqual, StringRepeat} from 'type-fest';
|
|
303
|
+
|
|
304
|
+
type HundredZeroes = StringRepeat<'0', 100>;
|
|
305
|
+
|
|
306
|
+
// The following implementation is not tail recursive
|
|
307
|
+
type Includes<S extends string, Char extends string> =
|
|
308
|
+
S extends `${infer First}${infer Rest}`
|
|
309
|
+
? If<IsEqual<First, Char>,
|
|
310
|
+
'found',
|
|
311
|
+
Includes<Rest, Char>>
|
|
312
|
+
: 'not found';
|
|
313
|
+
|
|
314
|
+
// Hence, instantiations with long strings will fail
|
|
315
|
+
// @ts-expect-error
|
|
316
|
+
type Fails = Includes<HundredZeroes, '1'>;
|
|
317
|
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
318
|
+
// Error: Type instantiation is excessively deep and possibly infinite.
|
|
319
|
+
|
|
320
|
+
// However, if we use a simple conditional instead of `If`, the implementation becomes tail-recursive
|
|
321
|
+
type IncludesWithoutIf<S extends string, Char extends string> =
|
|
322
|
+
S extends `${infer First}${infer Rest}`
|
|
323
|
+
? IsEqual<First, Char> extends true
|
|
324
|
+
? 'found'
|
|
325
|
+
: IncludesWithoutIf<Rest, Char>
|
|
326
|
+
: 'not found';
|
|
327
|
+
|
|
328
|
+
// Now, instantiations with long strings will work
|
|
329
|
+
type Works = IncludesWithoutIf<HundredZeroes, '1'>;
|
|
330
|
+
//=> 'not found'
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
@category Type Guard
|
|
334
|
+
@category Utilities
|
|
335
|
+
*/
|
|
336
|
+
type If<Type extends boolean, IfBranch, ElseBranch> = IsNever<Type> extends true ? ElseBranch : Type extends true ? IfBranch : ElseBranch;
|
|
337
|
+
//#endregion
|
|
338
|
+
//#region ../../node_modules/.pnpm/type-fest@5.6.0/node_modules/type-fest/source/unknown-array.d.ts
|
|
339
|
+
/**
|
|
340
|
+
Represents an array with `unknown` value.
|
|
341
|
+
|
|
342
|
+
Use case: You want a type that all arrays can be assigned to, but you don't care about the value.
|
|
343
|
+
|
|
344
|
+
@example
|
|
345
|
+
```
|
|
346
|
+
import type {UnknownArray} from 'type-fest';
|
|
347
|
+
|
|
348
|
+
type IsArray<T> = T extends UnknownArray ? true : false;
|
|
349
|
+
|
|
350
|
+
type A = IsArray<['foo']>;
|
|
351
|
+
//=> true
|
|
352
|
+
|
|
353
|
+
type B = IsArray<readonly number[]>;
|
|
354
|
+
//=> true
|
|
355
|
+
|
|
356
|
+
type C = IsArray<string>;
|
|
357
|
+
//=> false
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
@category Type
|
|
361
|
+
@category Array
|
|
362
|
+
*/
|
|
363
|
+
type UnknownArray = readonly unknown[];
|
|
364
|
+
//#endregion
|
|
365
|
+
//#region ../../node_modules/.pnpm/type-fest@5.6.0/node_modules/type-fest/source/internal/type.d.ts
|
|
366
|
+
/**
|
|
367
|
+
An if-else-like type that resolves depending on whether the given type is `any` or `never`.
|
|
368
|
+
|
|
369
|
+
@example
|
|
370
|
+
```
|
|
371
|
+
// When `T` is a NOT `any` or `never` (like `string`) => Returns `IfNotAnyOrNever` branch
|
|
372
|
+
type A = IfNotAnyOrNever<string, 'VALID', 'IS_ANY', 'IS_NEVER'>;
|
|
373
|
+
//=> 'VALID'
|
|
374
|
+
|
|
375
|
+
// When `T` is `any` => Returns `IfAny` branch
|
|
376
|
+
type B = IfNotAnyOrNever<any, 'VALID', 'IS_ANY', 'IS_NEVER'>;
|
|
377
|
+
//=> 'IS_ANY'
|
|
378
|
+
|
|
379
|
+
// When `T` is `never` => Returns `IfNever` branch
|
|
380
|
+
type C = IfNotAnyOrNever<never, 'VALID', 'IS_ANY', 'IS_NEVER'>;
|
|
381
|
+
//=> 'IS_NEVER'
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Note: Wrapping a tail-recursive type with `IfNotAnyOrNever` makes the implementation non-tail-recursive. To fix this, move the recursion into a helper type. Refer to the following example:
|
|
385
|
+
|
|
386
|
+
@example
|
|
387
|
+
```ts
|
|
388
|
+
import type {StringRepeat} from 'type-fest';
|
|
389
|
+
|
|
390
|
+
type NineHundredNinetyNineSpaces = StringRepeat<' ', 999>;
|
|
391
|
+
|
|
392
|
+
// The following implementation is not tail recursive
|
|
393
|
+
type TrimLeft<S extends string> = IfNotAnyOrNever<S, S extends ` ${infer R}` ? TrimLeft<R> : S>;
|
|
394
|
+
|
|
395
|
+
// Hence, instantiations with long strings will fail
|
|
396
|
+
// @ts-expect-error
|
|
397
|
+
type T1 = TrimLeft<NineHundredNinetyNineSpaces>;
|
|
398
|
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
399
|
+
// Error: Type instantiation is excessively deep and possibly infinite.
|
|
400
|
+
|
|
401
|
+
// To fix this, move the recursion into a helper type
|
|
402
|
+
type TrimLeftOptimised<S extends string> = IfNotAnyOrNever<S, _TrimLeftOptimised<S>>;
|
|
403
|
+
|
|
404
|
+
type _TrimLeftOptimised<S extends string> = S extends ` ${infer R}` ? _TrimLeftOptimised<R> : S;
|
|
405
|
+
|
|
406
|
+
type T2 = TrimLeftOptimised<NineHundredNinetyNineSpaces>;
|
|
407
|
+
//=> ''
|
|
408
|
+
```
|
|
409
|
+
*/
|
|
410
|
+
type IfNotAnyOrNever<T, IfNotAnyOrNever, IfAny = any, IfNever = never> = If<IsAny<T>, IfAny, If<IsNever<T>, IfNever, IfNotAnyOrNever>>;
|
|
411
|
+
//#endregion
|
|
412
|
+
//#region ../../node_modules/.pnpm/type-fest@5.6.0/node_modules/type-fest/source/numeric.d.ts
|
|
413
|
+
type _Numeric = number | bigint;
|
|
414
|
+
type Zero = 0 | 0n;
|
|
415
|
+
/**
|
|
416
|
+
Matches the hidden `Infinity` type.
|
|
417
|
+
|
|
418
|
+
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript.
|
|
419
|
+
|
|
420
|
+
@see {@link NegativeInfinity}
|
|
421
|
+
|
|
422
|
+
@category Numeric
|
|
423
|
+
*/
|
|
424
|
+
// See https://github.com/microsoft/TypeScript/issues/31752
|
|
425
|
+
// eslint-disable-next-line no-loss-of-precision
|
|
426
|
+
/**
|
|
427
|
+
A negative `number`/`bigint` (`-∞ < x < 0`)
|
|
428
|
+
|
|
429
|
+
Use-case: Validating and documenting parameters.
|
|
430
|
+
|
|
431
|
+
@see {@link NegativeInteger}
|
|
432
|
+
@see {@link NonNegative}
|
|
433
|
+
|
|
434
|
+
@category Numeric
|
|
435
|
+
*/
|
|
436
|
+
type Negative<T extends _Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never;
|
|
437
|
+
/**
|
|
438
|
+
Returns a boolean for whether the given number is a negative number.
|
|
439
|
+
|
|
440
|
+
@see {@link Negative}
|
|
441
|
+
|
|
442
|
+
@example
|
|
443
|
+
```
|
|
444
|
+
import type {IsNegative} from 'type-fest';
|
|
445
|
+
|
|
446
|
+
type ShouldBeFalse = IsNegative<1>;
|
|
447
|
+
type ShouldBeTrue = IsNegative<-1>;
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
@category Numeric
|
|
451
|
+
*/
|
|
452
|
+
type IsNegative<T extends _Numeric> = T extends Negative<T> ? true : false;
|
|
453
|
+
//#endregion
|
|
454
|
+
//#region ../../node_modules/.pnpm/type-fest@5.6.0/node_modules/type-fest/source/tuple-of.d.ts
|
|
455
|
+
/**
|
|
456
|
+
Create a tuple type of the specified length with elements of the specified type.
|
|
457
|
+
|
|
458
|
+
@example
|
|
459
|
+
```
|
|
460
|
+
import type {TupleOf} from 'type-fest';
|
|
461
|
+
|
|
462
|
+
type RGB = TupleOf<3, number>;
|
|
463
|
+
//=> [number, number, number]
|
|
464
|
+
|
|
465
|
+
type Line = TupleOf<2, {x: number; y: number}>;
|
|
466
|
+
//=> [{x: number; y: number}, {x: number; y: number}]
|
|
467
|
+
|
|
468
|
+
type TicTacToeBoard = TupleOf<3, TupleOf<3, 'X' | 'O' | null>>;
|
|
469
|
+
//=> [['X' | 'O' | null, 'X' | 'O' | null, 'X' | 'O' | null], ['X' | 'O' | null, 'X' | 'O' | null, 'X' | 'O' | null], ['X' | 'O' | null, 'X' | 'O' | null, 'X' | 'O' | null]]
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
@example
|
|
473
|
+
```
|
|
474
|
+
import type {TupleOf} from 'type-fest';
|
|
475
|
+
|
|
476
|
+
type Range<Start extends number, End extends number> = Exclude<keyof TupleOf<End>, keyof TupleOf<Start>>;
|
|
477
|
+
|
|
478
|
+
type ZeroToFour = Range<0, 5>;
|
|
479
|
+
//=> '0' | '1' | '2' | '3' | '4'
|
|
480
|
+
|
|
481
|
+
type ThreeToEight = Range<3, 9>;
|
|
482
|
+
//=> '5' | '3' | '4' | '6' | '7' | '8'
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Note: If the specified length is the non-literal `number` type, the result will not be a tuple but a regular array.
|
|
486
|
+
|
|
487
|
+
@example
|
|
488
|
+
```
|
|
489
|
+
import type {TupleOf} from 'type-fest';
|
|
490
|
+
|
|
491
|
+
type StringArray = TupleOf<number, string>;
|
|
492
|
+
//=> string[]
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Note: If the type for elements is not specified, it will default to `unknown`.
|
|
496
|
+
|
|
497
|
+
@example
|
|
498
|
+
```
|
|
499
|
+
import type {TupleOf} from 'type-fest';
|
|
500
|
+
|
|
501
|
+
type UnknownTriplet = TupleOf<3>;
|
|
502
|
+
//=> [unknown, unknown, unknown]
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
Note: If the specified length is negative, the result will be an empty tuple.
|
|
506
|
+
|
|
507
|
+
@example
|
|
508
|
+
```
|
|
509
|
+
import type {TupleOf} from 'type-fest';
|
|
510
|
+
|
|
511
|
+
type EmptyTuple = TupleOf<-3, string>;
|
|
512
|
+
//=> []
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
Note: If you need a readonly tuple, simply wrap this type with `Readonly`, for example, to create `readonly [number, number, number]` use `Readonly<TupleOf<3, number>>`.
|
|
516
|
+
|
|
517
|
+
@category Array
|
|
518
|
+
*/
|
|
519
|
+
type TupleOf<Length extends number, Fill = unknown> = IfNotAnyOrNever<Length, _TupleOf<If<IsNegative<Length>, 0, Length>, Fill, []>, Fill[], []>;
|
|
520
|
+
type _TupleOf<L extends number, Fill, Accumulator extends UnknownArray> = number extends L ? Fill[] : L extends Accumulator['length'] ? Accumulator : _TupleOf<L, Fill, [...Accumulator, Fill]>;
|
|
521
|
+
//#endregion
|
|
522
|
+
//#region src/numbers/roundToDenomination.d.ts
|
|
523
|
+
interface RoundToDenomOptions {
|
|
524
|
+
/**
|
|
525
|
+
* Suffixes to use for each denomination level. Defaults to `['K', 'M', 'B', 'T', 'Q']`.
|
|
526
|
+
*/
|
|
527
|
+
suffixes?: TupleOf<5, string>;
|
|
528
|
+
/** Number of decimal places to include in the rounded result. Defaults to `1`. */
|
|
529
|
+
precision?: number;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Rounds a number to a string representation with a denomination suffix.
|
|
533
|
+
* @param num - The number to round.
|
|
534
|
+
* @example
|
|
535
|
+
* ```ts
|
|
536
|
+
* roundToDenomination(1234); // "1.2K"
|
|
537
|
+
* roundToDenomination(10000, ['k', 'm', 'b', 't', 'q']); // "10k"
|
|
538
|
+
* roundToDenomination(12345678); // "12.3M"
|
|
539
|
+
* ```
|
|
540
|
+
* @returns The rounded number as a string with a denomination suffix.
|
|
541
|
+
*/
|
|
542
|
+
declare function roundToDenomination(num: number, opts?: RoundToDenomOptions): string;
|
|
543
|
+
//#endregion
|
|
544
|
+
//#region src/objects/filterCirculars.d.ts
|
|
545
|
+
/**
|
|
546
|
+
* JSONify an arbitrary type while allowing any object position to be replaced
|
|
547
|
+
* by a circular marker. Optional keys stay optional.
|
|
548
|
+
*/
|
|
549
|
+
type JsonifyWithCirculars<BaseType, Marker extends string = '[Circular]'> = BaseType extends JsonPrimitive ? BaseType : BaseType extends bigint ? string : BaseType extends Date ? string : BaseType extends {
|
|
550
|
+
toJSON(): infer J;
|
|
551
|
+
} ? unknown extends J ? JsonifyObject<BaseType, Marker> : JsonifyWithCirculars<J, Marker> : BaseType extends readonly (infer U)[] ? (JsonifyWithCirculars<U, Marker> | Marker)[] : BaseType extends Map<infer K, infer V> ? [JsonifyWithCirculars<K, Marker> | Marker, JsonifyWithCirculars<V, Marker> | Marker][] : BaseType extends Set<infer U2> ? (JsonifyWithCirculars<U2, Marker> | Marker)[] : BaseType extends ((...args: unknown[]) => unknown) ? never : BaseType extends object ? JsonifyObject<BaseType, Marker> : never;
|
|
552
|
+
/**
|
|
553
|
+
* Helper to JSONify object types with circular markers.
|
|
554
|
+
*
|
|
555
|
+
* @internal
|
|
556
|
+
*/
|
|
557
|
+
type JsonifyObject<BaseType, Marker extends string> = { [K in keyof BaseType as K extends symbol ? never : BaseType[K] extends ((...args: unknown[]) => unknown) ? never : K]: JsonifyWithCirculars<Exclude<BaseType[K], undefined>, Marker> | Extract<BaseType[K], undefined> | Marker };
|
|
558
|
+
/**
|
|
559
|
+
* Returned by {@link filterCirculars} when a value cannot be made JSON-safe. The original value is
|
|
560
|
+
* never returned on failure, because it would re-throw in the caller's own `JSON.stringify`.
|
|
561
|
+
*/
|
|
562
|
+
interface UnserializableValue {
|
|
563
|
+
'[unserializable]': string;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Configuration for {@link filterCirculars}.
|
|
567
|
+
*/
|
|
568
|
+
interface FilterCircularsOptions<Marker extends string = '[Circular]'> {
|
|
569
|
+
/** Optional {@link ILogger} used to log stringify or parse errors. */
|
|
570
|
+
logger?: ILogger;
|
|
571
|
+
/** Override the circular placeholder. Default is `[Circular]`. */
|
|
572
|
+
marker?: Marker;
|
|
573
|
+
/** Processing mode. `json` uses stringify and parse (might end up using a `toJSON()` if found). `decycle` builds a safe clone first. Default is `decycle`. */
|
|
574
|
+
mode?: 'json' | 'decycle';
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Creates a clean, JSON safe copy of a value and replaces circular references with a marker.
|
|
578
|
+
*
|
|
579
|
+
* In `json` mode it behaves like stringify then parse with a replacer that handles cycles and BigInt.
|
|
580
|
+
* In `decycle` mode it first clones without using toJSON, then you can stringify the result later.
|
|
581
|
+
*
|
|
582
|
+
* @typeParam ObjType - Type of the input value.
|
|
583
|
+
* @typeParam Marker - Marker string used for circular references.
|
|
584
|
+
*
|
|
585
|
+
* @param value - The value to clone safely.
|
|
586
|
+
* @param options - Optional configuration.
|
|
587
|
+
*
|
|
588
|
+
* @returns A JSON safe structure with circular references replaced by the marker.
|
|
589
|
+
*
|
|
590
|
+
* @example
|
|
591
|
+
* ```ts
|
|
592
|
+
* interface Test {
|
|
593
|
+
* name: string;
|
|
594
|
+
* self?: Test;
|
|
595
|
+
* }
|
|
596
|
+
*
|
|
597
|
+
* const obj: Test = { name: 'seedcord' };
|
|
598
|
+
* obj.self = obj;
|
|
599
|
+
*
|
|
600
|
+
* const clean = filterCirculars(obj);
|
|
601
|
+
* // ^? { name: string; self?: "[Circular]" | { ... } }
|
|
602
|
+
* console.log(clean.self); // "[Circular]"
|
|
603
|
+
* ```
|
|
604
|
+
*/
|
|
605
|
+
declare function filterCirculars<ObjType, Marker extends string = '[Circular]'>(value: ObjType, options?: FilterCircularsOptions<Marker>): JsonifyWithCirculars<ObjType, Marker> | UnserializableValue;
|
|
606
|
+
//#endregion
|
|
607
|
+
//#region src/objects/hasKeys.d.ts
|
|
608
|
+
/**
|
|
609
|
+
* Extracts the type of a nested property, distributing over unions.
|
|
610
|
+
*
|
|
611
|
+
* @internal
|
|
612
|
+
*/
|
|
613
|
+
type DeepGet<Obj, Key extends string> = Obj extends unknown ? Key extends `${infer K}.${infer Rest}` ? K extends keyof Obj ? DeepGet<NonNullable<Obj[K]>, Rest> : never : Key extends keyof Obj ? Obj[Key] : never : never;
|
|
614
|
+
/**
|
|
615
|
+
* Converts a dot-notation path string into a nested object type with a specific leaf value.
|
|
616
|
+
*
|
|
617
|
+
* @internal
|
|
618
|
+
*/
|
|
619
|
+
type PathToObj<Path extends string, Value> = Path extends `${infer Head}.${infer Tail}` ? { [K in Head]: PathToObj<Tail, Value> } : { [K in Path]: Value };
|
|
620
|
+
/**
|
|
621
|
+
* Checks for the presence of nested keys in an object that's possibly a distributed union, narrowing the object type accordingly.
|
|
622
|
+
*
|
|
623
|
+
* Checks if an object has the specified nested keys and that their values are not null or undefined. If they are not, the object type is narrowed to reflect the presence of these keys with their respective types from the original distributed union object.
|
|
624
|
+
*
|
|
625
|
+
* @param obj - The object to check.
|
|
626
|
+
* @param keys - An array of dot-notation paths to check.
|
|
627
|
+
* @returns True if all keys exist and are non-null/defined, narrowing the object type.
|
|
628
|
+
*
|
|
629
|
+
* @example
|
|
630
|
+
* ```ts
|
|
631
|
+
* interface Test {
|
|
632
|
+
* a?: {
|
|
633
|
+
* b?: {
|
|
634
|
+
* c?: string;
|
|
635
|
+
* };
|
|
636
|
+
* } | null;
|
|
637
|
+
* x?: number | null;
|
|
638
|
+
* }
|
|
639
|
+
*
|
|
640
|
+
* const obj: Test = { a: { b: { c: 'hello' } }, x: 42 };
|
|
641
|
+
*
|
|
642
|
+
* if (hasKeys(obj, ['a.b.c', 'x'])) {
|
|
643
|
+
* // Here, obj is narrowed to:
|
|
644
|
+
* // {
|
|
645
|
+
* // a: { b: { c: string } };
|
|
646
|
+
* // x: number;
|
|
647
|
+
* // }
|
|
648
|
+
* console.log(obj.a.b.c.toUpperCase()); // Safe to access and use
|
|
649
|
+
* console.log(obj.x.toFixed(2)); // Safe to access and use
|
|
650
|
+
* }
|
|
651
|
+
* ```
|
|
652
|
+
*/
|
|
653
|
+
declare function hasKeys<Obj extends object, Keys extends string>(obj: Obj, keys: Keys[]): obj is Obj & UnionToIntersection<Keys extends unknown ? PathToObj<Keys, UnionToIntersection<NonNullable<DeepGet<Obj, Keys>>>> : never>;
|
|
654
|
+
//#endregion
|
|
655
|
+
//#region src/objects/keepDefined.d.ts
|
|
656
|
+
/**
|
|
657
|
+
* Copies only the keys whose values are defined.
|
|
658
|
+
*
|
|
659
|
+
* @typeParam TObject - the original object type you're pulling from
|
|
660
|
+
* @typeParam TKey - the keys to copy when defined
|
|
661
|
+
* @param source - the object to read values from
|
|
662
|
+
* @param keys - optional list of keys to include when present. If omitted, all keys are considered
|
|
663
|
+
*
|
|
664
|
+
* @example
|
|
665
|
+
* ```ts
|
|
666
|
+
* interface Config {
|
|
667
|
+
* host?: string;
|
|
668
|
+
* port?: number;
|
|
669
|
+
* user?: string;
|
|
670
|
+
* password?: string;
|
|
671
|
+
* }
|
|
672
|
+
*
|
|
673
|
+
* const config: Config = {
|
|
674
|
+
* host: 'localhost',
|
|
675
|
+
* port: undefined,
|
|
676
|
+
* user: 'admin',
|
|
677
|
+
* password: undefined
|
|
678
|
+
* };
|
|
679
|
+
*
|
|
680
|
+
* const definedConfig = keepDefined(config, 'host', 'port', 'user', 'password');
|
|
681
|
+
* // Result: { host: 'localhost', user: 'admin' }
|
|
682
|
+
* ```
|
|
683
|
+
*/
|
|
684
|
+
declare function keepDefined<TObject extends object, TKey extends keyof TObject>(source: TObject, ...keys: readonly TKey[]): Partial<Pick<TObject, TKey extends never ? keyof TObject : TKey>>;
|
|
685
|
+
//#endregion
|
|
686
|
+
//#region src/strings/capitalize.d.ts
|
|
687
|
+
/**
|
|
688
|
+
* Returns the word with its first letter capitalized and the rest in lowercase.
|
|
689
|
+
* @param word - The word to be formatted.
|
|
690
|
+
* @returns The formatted word.
|
|
691
|
+
*/
|
|
692
|
+
declare function capitalize(word: string): string;
|
|
693
|
+
//#endregion
|
|
694
|
+
//#region src/strings/longestStringLength.d.ts
|
|
695
|
+
/**
|
|
696
|
+
* Function takes an array of strings or numbers and returns the number of characters in the longest string/number
|
|
697
|
+
*
|
|
698
|
+
* @param arr - The array of strings or numbers
|
|
699
|
+
* @returns The length of the longest element when converted to string
|
|
700
|
+
*/
|
|
701
|
+
declare function longestStringLength(arr: (string | number)[]): number;
|
|
702
|
+
//#endregion
|
|
703
|
+
//#region src/strings/generateAsciiTable.d.ts
|
|
704
|
+
/**
|
|
705
|
+
* Generates an ASCII table from the provided data.
|
|
706
|
+
*
|
|
707
|
+
* @param data - The data to be displayed in the table.
|
|
708
|
+
* @returns The generated ASCII table as a string.
|
|
709
|
+
*/
|
|
710
|
+
declare function generateAsciiTable(data: string[][]): string;
|
|
711
|
+
//#endregion
|
|
712
|
+
//#region src/strings/prettify.d.ts
|
|
713
|
+
/**
|
|
714
|
+
* Options for the `prettify` function.
|
|
715
|
+
*/
|
|
716
|
+
interface PrettifyOptions {
|
|
717
|
+
capitalize?: boolean;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Converts a string from any common naming convention to human-readable format.
|
|
721
|
+
* Accepts camelCase, PascalCase, snake_case, and kebab-case input.
|
|
722
|
+
*
|
|
723
|
+
* @param key - The string to convert
|
|
724
|
+
* @param opts - Optional configuration
|
|
725
|
+
* @returns A space-separated, human-readable string
|
|
726
|
+
*
|
|
727
|
+
* @example
|
|
728
|
+
* prettify("camelCaseString") // "camel Case String"
|
|
729
|
+
* prettify("PascalCaseString") // "Pascal Case String"
|
|
730
|
+
* prettify("snake_case_string") // "snake case string"
|
|
731
|
+
* prettify("kebab-case-string") // "kebab case string"
|
|
732
|
+
* prettify("mixedCase_string-name") // "mixed Case string name"
|
|
733
|
+
*/
|
|
734
|
+
declare function prettify(key: string, opts?: PrettifyOptions): string;
|
|
735
|
+
//#endregion
|
|
736
|
+
//#region src/strings/prettyDifference.d.ts
|
|
737
|
+
/**
|
|
738
|
+
* Calculates the difference between two numbers and formats it as a string with a '+' prefix for positive differences.
|
|
739
|
+
*
|
|
740
|
+
* @param numBefore - The initial number value
|
|
741
|
+
* @param numAfter - The final number value
|
|
742
|
+
* @returns A string representing the difference, with a '+' sign for positive differences
|
|
743
|
+
*
|
|
744
|
+
* @example
|
|
745
|
+
* // Returns "+5"
|
|
746
|
+
* prettyDifference(10, 15);
|
|
747
|
+
*
|
|
748
|
+
* @example
|
|
749
|
+
* // Returns "-3"
|
|
750
|
+
* prettyDifference(10, 7);
|
|
751
|
+
*/
|
|
752
|
+
declare function prettyDifference(numBefore: number, numAfter: number): string;
|
|
753
|
+
//#endregion
|
|
754
|
+
//#region src/index.d.ts
|
|
755
|
+
/** Package version */
|
|
756
|
+
declare const version: string;
|
|
757
|
+
//#endregion
|
|
758
|
+
export { DeepGet, FilterCircularsOptions, FormatFileOptions, JsonifyObject, JsonifyWithCirculars, PathToObj, PrettifyOptions, RoundToDenomOptions, UnserializableValue, assertNever, capitalize, currentTime, filterCirculars, formatFilePath, fyShuffle, generateAsciiTable, generateCode, hasKeys, isTsOrJsFile, keepDefined, longestStringLength, ordinal, percentage, prettify, prettyDifference, round, roundToDenomination, traverseDirectory, version };
|
|
759
|
+
//# sourceMappingURL=index.d.mts.map
|