@forklaunch/common 0.3.14 → 0.4.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/lib/index.d.mts +311 -7
- package/lib/index.d.ts +311 -7
- package/lib/index.js +156 -16
- package/lib/index.mjs +137 -14
- package/package.json +7 -7
package/lib/index.d.mts
CHANGED
|
@@ -1,3 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility types for string manipulation and validation
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Remove leading separators from a string
|
|
6
|
+
*/
|
|
7
|
+
type RemoveLeadingSeparators<S extends string> = S extends `${' ' | '-' | '_' | '.' | '/' | ':'}${infer Rest}` ? RemoveLeadingSeparators<Rest> : S;
|
|
8
|
+
/**
|
|
9
|
+
* Split a string by separators (space, dash, underscore, dot, slash, colon)
|
|
10
|
+
*/
|
|
11
|
+
type SplitBySeparators<S extends string> = S extends `${infer First}${' ' | '-' | '_' | '.' | '/' | ':'}${infer Rest}` ? [First, ...SplitBySeparators<Rest>] : S extends '' ? [] : [S];
|
|
12
|
+
/**
|
|
13
|
+
* Capitalize the first letter of a string
|
|
14
|
+
*/
|
|
15
|
+
type Capitalize<S extends string> = S extends `${infer First}${infer Rest}` ? `${Uppercase<First>}${Rest}` : S;
|
|
16
|
+
/**
|
|
17
|
+
* Convert the first letter to lowercase
|
|
18
|
+
*/
|
|
19
|
+
type Uncapitalize<S extends string> = S extends `${infer First}${infer Rest}` ? `${Lowercase<First>}${Rest}` : S;
|
|
20
|
+
/**
|
|
21
|
+
* Remove all non-alphanumeric characters from a string
|
|
22
|
+
*/
|
|
23
|
+
type RemoveNonAlphanumeric<S extends string> = S extends `${infer First}${infer Rest}` ? First extends 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ? `${First}${RemoveNonAlphanumeric<Rest>}` : RemoveNonAlphanumeric<Rest> : '';
|
|
24
|
+
/**
|
|
25
|
+
* Remove leading numbers from a string to make it a valid identifier
|
|
26
|
+
*/
|
|
27
|
+
type RemoveLeadingNumbers<S extends string> = S extends `${infer First}${infer Rest}` ? First extends '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ? RemoveLeadingNumbers<Rest> : S : S;
|
|
28
|
+
/**
|
|
29
|
+
* Join an array of strings into camelCase
|
|
30
|
+
*/
|
|
31
|
+
type JoinCamelCase<T extends readonly string[]> = T extends readonly [
|
|
32
|
+
infer First,
|
|
33
|
+
...infer Rest
|
|
34
|
+
] ? First extends string ? Rest extends readonly string[] ? Rest['length'] extends 0 ? Uncapitalize<RemoveNonAlphanumeric<First>> : `${Uncapitalize<RemoveNonAlphanumeric<First>>}${JoinCamelCaseCapitalized<Rest>}` : never : never : '';
|
|
35
|
+
/**
|
|
36
|
+
* Join remaining parts with capitalized first letters
|
|
37
|
+
*/
|
|
38
|
+
type JoinCamelCaseCapitalized<T extends readonly string[]> = T extends readonly [infer First, ...infer Rest] ? First extends string ? Rest extends readonly string[] ? Rest['length'] extends 0 ? Capitalize<RemoveNonAlphanumeric<First>> : `${Capitalize<RemoveNonAlphanumeric<First>>}${JoinCamelCaseCapitalized<Rest>}` : never : never : '';
|
|
39
|
+
/**
|
|
40
|
+
* Convert a string to a valid TypeScript identifier in camelCase
|
|
41
|
+
* Always returns a string, defaulting to the input if transformation fails
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* type Example1 = CamelCaseIdentifier<"hello-world">; // "helloWorld"
|
|
46
|
+
* type Example2 = CamelCaseIdentifier<"my_var_name">; // "myVarName"
|
|
47
|
+
* type Example3 = CamelCaseIdentifier<"some.property.name">; // "somePropertyName"
|
|
48
|
+
* type Example4 = CamelCaseIdentifier<"123invalid">; // "invalid"
|
|
49
|
+
* type Example5 = CamelCaseIdentifier<"hello world">; // "helloWorld"
|
|
50
|
+
* type Example6 = CamelCaseIdentifier<"API-Key">; // "aPIKey"
|
|
51
|
+
* type Example7 = CamelCaseIdentifier<"/organization/base">; // "organizationBase"
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
type CamelCaseIdentifier<S extends string> = RemoveLeadingNumbers<JoinCamelCase<SplitBySeparators<RemoveLeadingSeparators<S>>>> extends infer Result ? Result extends string ? Result extends '' ? S : Result : S : S;
|
|
55
|
+
/**
|
|
56
|
+
* Improved version that handles consecutive uppercase letters better
|
|
57
|
+
* by converting them to proper camelCase
|
|
58
|
+
*/
|
|
59
|
+
type LowerCaseWord<S extends string> = Lowercase<S>;
|
|
60
|
+
/**
|
|
61
|
+
* More intuitive camelCase conversion that properly handles abbreviations
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* type Example1 = PrettyCamelCase<"API-Key">; // "apiKey"
|
|
66
|
+
* type Example2 = PrettyCamelCase<"HTTP-Response">; // "httpResponse"
|
|
67
|
+
* type Example3 = PrettyCamelCase<"user-ID">; // "userId"
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
type JoinPrettyCamelCase<T extends readonly string[]> = T extends readonly [
|
|
71
|
+
infer First,
|
|
72
|
+
...infer Rest
|
|
73
|
+
] ? First extends string ? Rest extends readonly string[] ? Rest['length'] extends 0 ? LowerCaseWord<RemoveNonAlphanumeric<First>> : `${LowerCaseWord<RemoveNonAlphanumeric<First>>}${JoinPrettyCamelCaseCapitalized<Rest>}` : never : never : '';
|
|
74
|
+
type JoinPrettyCamelCaseCapitalized<T extends readonly string[]> = T extends readonly [infer First, ...infer Rest] ? First extends string ? Rest extends readonly string[] ? Rest['length'] extends 0 ? Capitalize<LowerCaseWord<RemoveNonAlphanumeric<First>>> : `${Capitalize<LowerCaseWord<RemoveNonAlphanumeric<First>>>}${JoinPrettyCamelCaseCapitalized<Rest>}` : never : never : '';
|
|
75
|
+
/**
|
|
76
|
+
* Pretty camelCase conversion that handles abbreviations more intuitively
|
|
77
|
+
* Always returns a string, defaulting to the input if transformation fails
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* type Example1 = PrettyCamelCase<"API-Key">; // "apiKey"
|
|
82
|
+
* type Example2 = PrettyCamelCase<"HTTP-Response">; // "httpResponse"
|
|
83
|
+
* type Example3 = PrettyCamelCase<"user-ID">; // "userId"
|
|
84
|
+
* type Example4 = PrettyCamelCase<"get-user-by-id">; // "getUserById"
|
|
85
|
+
* type Example5 = PrettyCamelCase<"/organization/base">; // "organizationBase"
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
type PrettyCamelCase<S extends string> = RemoveLeadingNumbers<JoinPrettyCamelCase<SplitBySeparators<RemoveLeadingSeparators<S>>>> extends infer Result ? Result extends string ? Result extends '' ? S : Result : S : S;
|
|
89
|
+
/**
|
|
90
|
+
* Alternative implementation using a more comprehensive approach
|
|
91
|
+
* for complex cases with better handling of edge cases
|
|
92
|
+
*/
|
|
93
|
+
type ValidIdentifier<S extends string> = CamelCaseIdentifier<S>;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Runtime string utility functions that mirror the TypeScript utility types
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Remove leading separators from a string
|
|
101
|
+
*/
|
|
102
|
+
declare function removeLeadingSeparators(str: string): string;
|
|
103
|
+
/**
|
|
104
|
+
* Split a string by separators (space, dash, underscore, dot, slash, colon)
|
|
105
|
+
*/
|
|
106
|
+
declare function splitBySeparators(str: string): string[];
|
|
107
|
+
/**
|
|
108
|
+
* Remove all non-alphanumeric characters from a string
|
|
109
|
+
*/
|
|
110
|
+
declare function removeNonAlphanumeric(str: string): string;
|
|
111
|
+
/**
|
|
112
|
+
* Remove leading numbers from a string to make it a valid identifier
|
|
113
|
+
*/
|
|
114
|
+
declare function removeLeadingNumbers(str: string): string;
|
|
115
|
+
/**
|
|
116
|
+
* Capitalize the first letter of a string
|
|
117
|
+
*/
|
|
118
|
+
declare function capitalize(str: string): string;
|
|
119
|
+
/**
|
|
120
|
+
* Convert the first letter to lowercase
|
|
121
|
+
*/
|
|
122
|
+
declare function uncapitalize(str: string): string;
|
|
123
|
+
/**
|
|
124
|
+
* Convert a string to a valid TypeScript identifier in camelCase
|
|
125
|
+
* Always returns a string, defaulting to the input if transformation fails
|
|
126
|
+
*
|
|
127
|
+
* @param str - The input string to transform
|
|
128
|
+
* @returns The camelCase identifier or the original string if transformation fails
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* toCamelCaseIdentifier("hello-world"); // "helloWorld"
|
|
133
|
+
* toCamelCaseIdentifier("my_var_name"); // "myVarName"
|
|
134
|
+
* toCamelCaseIdentifier("some.property.name"); // "somePropertyName"
|
|
135
|
+
* toCamelCaseIdentifier("123invalid"); // "invalid"
|
|
136
|
+
* toCamelCaseIdentifier("hello world"); // "helloWorld"
|
|
137
|
+
* toCamelCaseIdentifier("API-Key"); // "aPIKey"
|
|
138
|
+
* toCamelCaseIdentifier("/organization/base"); // "organizationBase"
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
declare function toCamelCaseIdentifier<T extends string>(str: T): CamelCaseIdentifier<T>;
|
|
142
|
+
/**
|
|
143
|
+
* Pretty camelCase conversion that handles abbreviations more intuitively
|
|
144
|
+
* Always returns a string, defaulting to the input if transformation fails
|
|
145
|
+
*
|
|
146
|
+
* @param str - The input string to transform
|
|
147
|
+
* @returns The pretty camelCase identifier or the original string if transformation fails
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* toPrettyCamelCase("API-Key"); // "apiKey"
|
|
152
|
+
* toPrettyCamelCase("HTTP-Response"); // "httpResponse"
|
|
153
|
+
* toPrettyCamelCase("user-ID"); // "userId"
|
|
154
|
+
* toPrettyCamelCase("get-user-by-id"); // "getUserById"
|
|
155
|
+
* toPrettyCamelCase("/organization/base"); // "organizationBase"
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
declare function toPrettyCamelCase<T extends string>(str: T): PrettyCamelCase<T>;
|
|
159
|
+
/**
|
|
160
|
+
* Alternative implementation using a more comprehensive approach
|
|
161
|
+
* for complex cases with better handling of edge cases
|
|
162
|
+
*/
|
|
163
|
+
declare function toValidIdentifier<T extends string>(str: T): ValidIdentifier<T>;
|
|
164
|
+
/**
|
|
165
|
+
* Check if a string is a valid JavaScript/TypeScript identifier
|
|
166
|
+
*/
|
|
167
|
+
declare function isValidIdentifier(str: string): boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Get detailed information about the transformation process
|
|
170
|
+
* Useful for debugging and understanding how the transformation works
|
|
171
|
+
*/
|
|
172
|
+
declare function getTransformationInfo(str: string): {
|
|
173
|
+
original: string;
|
|
174
|
+
withoutLeadingSeparators: string;
|
|
175
|
+
parts: string[];
|
|
176
|
+
camelCase: string;
|
|
177
|
+
prettyCamelCase: string;
|
|
178
|
+
withoutLeadingNumbers: string;
|
|
179
|
+
prettyCamelCaseWithoutLeadingNumbers: string;
|
|
180
|
+
isValid: boolean;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* An empty object literal constant.
|
|
185
|
+
*
|
|
186
|
+
* This constant represents an empty object with no properties.
|
|
187
|
+
* It is commonly used as a default value or placeholder when
|
|
188
|
+
* an empty object is needed.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* const defaultConfig = emptyObject;
|
|
193
|
+
* const merged = { ...emptyObject, ...userConfig };
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
declare const emptyObject: {};
|
|
197
|
+
|
|
1
198
|
/**
|
|
2
199
|
* Extracts the names of arguments from a function's string representation.
|
|
3
200
|
* This is useful for reflection and debugging purposes.
|
|
@@ -48,13 +245,9 @@ declare function isRecord(obj: unknown): obj is Record<string, unknown>;
|
|
|
48
245
|
*/
|
|
49
246
|
declare function isTrue(value: true): true;
|
|
50
247
|
|
|
51
|
-
declare class
|
|
248
|
+
declare class InMemoryBlob extends Blob {
|
|
52
249
|
content: string;
|
|
53
|
-
constructor(content: string
|
|
54
|
-
type?: string;
|
|
55
|
-
endings?: 'transparent' | 'native';
|
|
56
|
-
lastModified?: number;
|
|
57
|
-
});
|
|
250
|
+
constructor(content: string);
|
|
58
251
|
}
|
|
59
252
|
|
|
60
253
|
/**
|
|
@@ -72,6 +265,26 @@ declare class InMemoryFile extends File {
|
|
|
72
265
|
*/
|
|
73
266
|
declare function noop(..._args: unknown[]): void;
|
|
74
267
|
|
|
268
|
+
/**
|
|
269
|
+
* Converts a path with Express-style parameters to OpenAPI-compliant format.
|
|
270
|
+
*
|
|
271
|
+
* Express-style parameters use the format `:paramName` (e.g., `/users/:id`),
|
|
272
|
+
* while OpenAPI uses curly braces `{paramName}` (e.g., `/users/{id}`).
|
|
273
|
+
*
|
|
274
|
+
* @param path - The path string containing Express-style parameters
|
|
275
|
+
* @returns The path string with OpenAPI-compliant parameter format
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```typescript
|
|
279
|
+
* openApiCompliantPath('/users/:id/posts/:postId')
|
|
280
|
+
* // Returns: '/users/{id}/posts/{postId}'
|
|
281
|
+
*
|
|
282
|
+
* openApiCompliantPath('/api/v1/products/:productId/reviews/:reviewId')
|
|
283
|
+
* // Returns: '/api/v1/products/{productId}/reviews/{reviewId}'
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
declare function openApiCompliantPath(path: string): string;
|
|
287
|
+
|
|
75
288
|
declare function readableStreamToAsyncIterable<T>(stream: ReadableStream<T>): AsyncIterable<T>;
|
|
76
289
|
|
|
77
290
|
declare function safeParse<T>(input: unknown): T;
|
|
@@ -104,6 +317,37 @@ declare function safeParse<T>(input: unknown): T;
|
|
|
104
317
|
*/
|
|
105
318
|
declare function safeStringify(arg: unknown): string;
|
|
106
319
|
|
|
320
|
+
/**
|
|
321
|
+
* Removes a trailing slash from a path string if present.
|
|
322
|
+
*
|
|
323
|
+
* @param path - The path string to process
|
|
324
|
+
* @returns The path string with trailing slash removed
|
|
325
|
+
* @example
|
|
326
|
+
* removeTrailingSlash('/users/'); // '/users'
|
|
327
|
+
* removeTrailingSlash('/users'); // '/users'
|
|
328
|
+
*/
|
|
329
|
+
declare function removeTrailingSlash(path: string): string;
|
|
330
|
+
/**
|
|
331
|
+
* Removes a double leading slash from a path string if present.
|
|
332
|
+
*
|
|
333
|
+
* @param path - The path string to process
|
|
334
|
+
* @returns The path string with double leading slash removed
|
|
335
|
+
* @example
|
|
336
|
+
* removeDoubleLeadingSlash('//users'); // '/users'
|
|
337
|
+
* removeDoubleLeadingSlash('/users'); // '/users'
|
|
338
|
+
*/
|
|
339
|
+
declare function removeDoubleLeadingSlash(path: string): string;
|
|
340
|
+
/**
|
|
341
|
+
* Sanitizes a path string by removing both trailing slashes and double leading slashes.
|
|
342
|
+
*
|
|
343
|
+
* @param path - The path string to process
|
|
344
|
+
* @returns The sanitized path string
|
|
345
|
+
* @example
|
|
346
|
+
* sanitizePathSlashes('//users/'); // '/users'
|
|
347
|
+
* sanitizePathSlashes('/users'); // '/users'
|
|
348
|
+
*/
|
|
349
|
+
declare function sanitizePathSlashes(path: string): string;
|
|
350
|
+
|
|
107
351
|
/**
|
|
108
352
|
* Recursively sorts the keys of an object and its nested objects alphabetically.
|
|
109
353
|
* This is useful for consistent object serialization and comparison.
|
|
@@ -125,6 +369,15 @@ declare function sortObjectKeys<T extends Record<string, unknown>>(obj: T): T;
|
|
|
125
369
|
*/
|
|
126
370
|
declare function stripUndefinedProperties<T extends Record<string, unknown>>(obj: T): Partial<T>;
|
|
127
371
|
|
|
372
|
+
/**
|
|
373
|
+
* Converts an object to a record.
|
|
374
|
+
*
|
|
375
|
+
* @template T - The type of the object to convert.
|
|
376
|
+
* @param obj - The object to convert.
|
|
377
|
+
* @returns The record.
|
|
378
|
+
*/
|
|
379
|
+
declare function toRecord<T>(obj: T): Record<string, unknown>;
|
|
380
|
+
|
|
128
381
|
/**
|
|
129
382
|
* Type representing a DTO (Data Transfer Object) with an id field.
|
|
130
383
|
*/
|
|
@@ -173,6 +426,19 @@ type InstanceTypeRecord<T extends Record<string, new (...args: never[]) => unkno
|
|
|
173
426
|
[K in keyof T]: InstanceType<T[K]>;
|
|
174
427
|
};
|
|
175
428
|
|
|
429
|
+
/**
|
|
430
|
+
* Type representing an empty object literal.
|
|
431
|
+
*
|
|
432
|
+
* This type is derived from the `emptyObject` constant and represents
|
|
433
|
+
* an object with no properties.
|
|
434
|
+
*
|
|
435
|
+
* @example
|
|
436
|
+
* ```typescript
|
|
437
|
+
* const obj: EmptyObject = {};
|
|
438
|
+
* ```
|
|
439
|
+
*/
|
|
440
|
+
type EmptyObject = typeof emptyObject;
|
|
441
|
+
|
|
176
442
|
type ExclusiveRecord<T, U> = T extends object ? U extends object ? T & Record<Exclude<keyof T, keyof U>, never> : T : T;
|
|
177
443
|
|
|
178
444
|
/**
|
|
@@ -230,6 +496,18 @@ type MakePropertyOptionalIfChildrenOptional<T> = {
|
|
|
230
496
|
[K in keyof T as AllPropertiesOptional<T[K]> extends true ? never : K]: T[K];
|
|
231
497
|
};
|
|
232
498
|
|
|
499
|
+
/**
|
|
500
|
+
* Merges two objects by unioning the values for duplicate keys
|
|
501
|
+
*/
|
|
502
|
+
type MergeUnionOnCollision<T, U> = {
|
|
503
|
+
[K in keyof T | keyof U]: K extends keyof T ? K extends keyof U ? T[K] | U[K] : T[K] : K extends keyof U ? U[K] : never;
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Recursively merges an array of fetchMap objects
|
|
508
|
+
*/
|
|
509
|
+
type MergeArrayOfMaps<T extends readonly Record<string, unknown>[]> = T extends readonly [infer First, ...infer Rest] ? First extends Record<string, unknown> ? Rest extends readonly Record<string, unknown>[] ? Rest extends readonly [] ? First : MergeUnionOnCollision<First, MergeArrayOfMaps<Rest>> : First : Record<string, never> : Record<string, never>;
|
|
510
|
+
|
|
233
511
|
type MimeType = 'application/json' | 'application/xml' | 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/html' | 'text/plain' | 'image/jpeg' | 'image/png' | 'video/mp4' | 'audio/mpeg' | 'application/pdf' | 'application/zip' | 'application/octet-stream' | string;
|
|
234
512
|
|
|
235
513
|
/**
|
|
@@ -254,9 +532,35 @@ type Prettify<T> = {
|
|
|
254
532
|
* type Route2 = RemoveTrailingSlash<'/users'>; // '/users'
|
|
255
533
|
*/
|
|
256
534
|
type RemoveTrailingSlash<T extends string> = T extends `${infer Route}/` ? Route : T;
|
|
535
|
+
/**
|
|
536
|
+
* Type that removes a double leading slash from a string type if present.
|
|
537
|
+
*
|
|
538
|
+
* @template T - The string type to process
|
|
539
|
+
* @example
|
|
540
|
+
* type Route1 = RemoveDoubleLeadingSlash<'//users'>; // '/users'
|
|
541
|
+
* type Route2 = RemoveDoubleLeadingSlash<'/users'>; // '/users'
|
|
542
|
+
*/
|
|
543
|
+
type RemoveDoubleLeadingSlash<T extends string> = T extends `//${infer Route}` ? `/${Route}` : T;
|
|
544
|
+
/**
|
|
545
|
+
* Type that sanitizes a path string by removing double leading slashes.
|
|
546
|
+
*
|
|
547
|
+
* @template T - The string type to process
|
|
548
|
+
* @example
|
|
549
|
+
* type Route1 = SanitizePathSlashes<'//users'>; // '/users'
|
|
550
|
+
* type Route2 = SanitizePathSlashes<'/users'>; // '/users'
|
|
551
|
+
*/
|
|
552
|
+
type SanitizePathSlashes<T extends string> = RemoveDoubleLeadingSlash<RemoveTrailingSlash<T>>;
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Utility type that excludes strings containing forward slashes
|
|
556
|
+
*/
|
|
557
|
+
type StringWithoutSlash<T extends string> = T extends `${string}/${string}` ? 'cannot contain forward slashes' : T;
|
|
257
558
|
|
|
258
559
|
type TypeSafeFunction = (...args: never[]) => unknown;
|
|
259
560
|
|
|
260
561
|
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
562
|
+
type UnionToIntersectionChildren<U> = {
|
|
563
|
+
[K in keyof U]: UnionToIntersection<U[K]>;
|
|
564
|
+
};
|
|
261
565
|
|
|
262
|
-
export { type ExclusiveRecord, type Flatten, type FlattenKeys, type FlattenValues, type IdDto, type IdsDto,
|
|
566
|
+
export { type CamelCaseIdentifier, type EmptyObject, type ExclusiveRecord, type Flatten, type FlattenKeys, type FlattenValues, type IdDto, type IdsDto, InMemoryBlob, type InstanceTypeRecord, type MakePropertyOptionalIfChildrenOptional, type MergeArrayOfMaps, type MergeUnionOnCollision, type MimeType, type Prettify, type PrettyCamelCase, type RecordTimingDto, type RemoveDoubleLeadingSlash, type RemoveTrailingSlash, type ReturnTypeRecord, type SanitizePathSlashes, type StringWithoutSlash, type TypeSafeFunction, type UnionToIntersection, type UnionToIntersectionChildren, type ValidIdentifier, capitalize, emptyObject, extractArgumentNames, getEnvVar, getTransformationInfo, isAsyncGenerator, isNever, isNodeJsWriteableStream, isRecord, isTrue, isValidIdentifier, noop, openApiCompliantPath, readableStreamToAsyncIterable, removeDoubleLeadingSlash, removeLeadingNumbers, removeLeadingSeparators, removeNonAlphanumeric, removeTrailingSlash, safeParse, safeStringify, sanitizePathSlashes, sortObjectKeys, splitBySeparators, stripUndefinedProperties, toCamelCaseIdentifier, toPrettyCamelCase, toRecord, toValidIdentifier, uncapitalize };
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility types for string manipulation and validation
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Remove leading separators from a string
|
|
6
|
+
*/
|
|
7
|
+
type RemoveLeadingSeparators<S extends string> = S extends `${' ' | '-' | '_' | '.' | '/' | ':'}${infer Rest}` ? RemoveLeadingSeparators<Rest> : S;
|
|
8
|
+
/**
|
|
9
|
+
* Split a string by separators (space, dash, underscore, dot, slash, colon)
|
|
10
|
+
*/
|
|
11
|
+
type SplitBySeparators<S extends string> = S extends `${infer First}${' ' | '-' | '_' | '.' | '/' | ':'}${infer Rest}` ? [First, ...SplitBySeparators<Rest>] : S extends '' ? [] : [S];
|
|
12
|
+
/**
|
|
13
|
+
* Capitalize the first letter of a string
|
|
14
|
+
*/
|
|
15
|
+
type Capitalize<S extends string> = S extends `${infer First}${infer Rest}` ? `${Uppercase<First>}${Rest}` : S;
|
|
16
|
+
/**
|
|
17
|
+
* Convert the first letter to lowercase
|
|
18
|
+
*/
|
|
19
|
+
type Uncapitalize<S extends string> = S extends `${infer First}${infer Rest}` ? `${Lowercase<First>}${Rest}` : S;
|
|
20
|
+
/**
|
|
21
|
+
* Remove all non-alphanumeric characters from a string
|
|
22
|
+
*/
|
|
23
|
+
type RemoveNonAlphanumeric<S extends string> = S extends `${infer First}${infer Rest}` ? First extends 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ? `${First}${RemoveNonAlphanumeric<Rest>}` : RemoveNonAlphanumeric<Rest> : '';
|
|
24
|
+
/**
|
|
25
|
+
* Remove leading numbers from a string to make it a valid identifier
|
|
26
|
+
*/
|
|
27
|
+
type RemoveLeadingNumbers<S extends string> = S extends `${infer First}${infer Rest}` ? First extends '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ? RemoveLeadingNumbers<Rest> : S : S;
|
|
28
|
+
/**
|
|
29
|
+
* Join an array of strings into camelCase
|
|
30
|
+
*/
|
|
31
|
+
type JoinCamelCase<T extends readonly string[]> = T extends readonly [
|
|
32
|
+
infer First,
|
|
33
|
+
...infer Rest
|
|
34
|
+
] ? First extends string ? Rest extends readonly string[] ? Rest['length'] extends 0 ? Uncapitalize<RemoveNonAlphanumeric<First>> : `${Uncapitalize<RemoveNonAlphanumeric<First>>}${JoinCamelCaseCapitalized<Rest>}` : never : never : '';
|
|
35
|
+
/**
|
|
36
|
+
* Join remaining parts with capitalized first letters
|
|
37
|
+
*/
|
|
38
|
+
type JoinCamelCaseCapitalized<T extends readonly string[]> = T extends readonly [infer First, ...infer Rest] ? First extends string ? Rest extends readonly string[] ? Rest['length'] extends 0 ? Capitalize<RemoveNonAlphanumeric<First>> : `${Capitalize<RemoveNonAlphanumeric<First>>}${JoinCamelCaseCapitalized<Rest>}` : never : never : '';
|
|
39
|
+
/**
|
|
40
|
+
* Convert a string to a valid TypeScript identifier in camelCase
|
|
41
|
+
* Always returns a string, defaulting to the input if transformation fails
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* type Example1 = CamelCaseIdentifier<"hello-world">; // "helloWorld"
|
|
46
|
+
* type Example2 = CamelCaseIdentifier<"my_var_name">; // "myVarName"
|
|
47
|
+
* type Example3 = CamelCaseIdentifier<"some.property.name">; // "somePropertyName"
|
|
48
|
+
* type Example4 = CamelCaseIdentifier<"123invalid">; // "invalid"
|
|
49
|
+
* type Example5 = CamelCaseIdentifier<"hello world">; // "helloWorld"
|
|
50
|
+
* type Example6 = CamelCaseIdentifier<"API-Key">; // "aPIKey"
|
|
51
|
+
* type Example7 = CamelCaseIdentifier<"/organization/base">; // "organizationBase"
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
type CamelCaseIdentifier<S extends string> = RemoveLeadingNumbers<JoinCamelCase<SplitBySeparators<RemoveLeadingSeparators<S>>>> extends infer Result ? Result extends string ? Result extends '' ? S : Result : S : S;
|
|
55
|
+
/**
|
|
56
|
+
* Improved version that handles consecutive uppercase letters better
|
|
57
|
+
* by converting them to proper camelCase
|
|
58
|
+
*/
|
|
59
|
+
type LowerCaseWord<S extends string> = Lowercase<S>;
|
|
60
|
+
/**
|
|
61
|
+
* More intuitive camelCase conversion that properly handles abbreviations
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* type Example1 = PrettyCamelCase<"API-Key">; // "apiKey"
|
|
66
|
+
* type Example2 = PrettyCamelCase<"HTTP-Response">; // "httpResponse"
|
|
67
|
+
* type Example3 = PrettyCamelCase<"user-ID">; // "userId"
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
type JoinPrettyCamelCase<T extends readonly string[]> = T extends readonly [
|
|
71
|
+
infer First,
|
|
72
|
+
...infer Rest
|
|
73
|
+
] ? First extends string ? Rest extends readonly string[] ? Rest['length'] extends 0 ? LowerCaseWord<RemoveNonAlphanumeric<First>> : `${LowerCaseWord<RemoveNonAlphanumeric<First>>}${JoinPrettyCamelCaseCapitalized<Rest>}` : never : never : '';
|
|
74
|
+
type JoinPrettyCamelCaseCapitalized<T extends readonly string[]> = T extends readonly [infer First, ...infer Rest] ? First extends string ? Rest extends readonly string[] ? Rest['length'] extends 0 ? Capitalize<LowerCaseWord<RemoveNonAlphanumeric<First>>> : `${Capitalize<LowerCaseWord<RemoveNonAlphanumeric<First>>>}${JoinPrettyCamelCaseCapitalized<Rest>}` : never : never : '';
|
|
75
|
+
/**
|
|
76
|
+
* Pretty camelCase conversion that handles abbreviations more intuitively
|
|
77
|
+
* Always returns a string, defaulting to the input if transformation fails
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* type Example1 = PrettyCamelCase<"API-Key">; // "apiKey"
|
|
82
|
+
* type Example2 = PrettyCamelCase<"HTTP-Response">; // "httpResponse"
|
|
83
|
+
* type Example3 = PrettyCamelCase<"user-ID">; // "userId"
|
|
84
|
+
* type Example4 = PrettyCamelCase<"get-user-by-id">; // "getUserById"
|
|
85
|
+
* type Example5 = PrettyCamelCase<"/organization/base">; // "organizationBase"
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
type PrettyCamelCase<S extends string> = RemoveLeadingNumbers<JoinPrettyCamelCase<SplitBySeparators<RemoveLeadingSeparators<S>>>> extends infer Result ? Result extends string ? Result extends '' ? S : Result : S : S;
|
|
89
|
+
/**
|
|
90
|
+
* Alternative implementation using a more comprehensive approach
|
|
91
|
+
* for complex cases with better handling of edge cases
|
|
92
|
+
*/
|
|
93
|
+
type ValidIdentifier<S extends string> = CamelCaseIdentifier<S>;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Runtime string utility functions that mirror the TypeScript utility types
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Remove leading separators from a string
|
|
101
|
+
*/
|
|
102
|
+
declare function removeLeadingSeparators(str: string): string;
|
|
103
|
+
/**
|
|
104
|
+
* Split a string by separators (space, dash, underscore, dot, slash, colon)
|
|
105
|
+
*/
|
|
106
|
+
declare function splitBySeparators(str: string): string[];
|
|
107
|
+
/**
|
|
108
|
+
* Remove all non-alphanumeric characters from a string
|
|
109
|
+
*/
|
|
110
|
+
declare function removeNonAlphanumeric(str: string): string;
|
|
111
|
+
/**
|
|
112
|
+
* Remove leading numbers from a string to make it a valid identifier
|
|
113
|
+
*/
|
|
114
|
+
declare function removeLeadingNumbers(str: string): string;
|
|
115
|
+
/**
|
|
116
|
+
* Capitalize the first letter of a string
|
|
117
|
+
*/
|
|
118
|
+
declare function capitalize(str: string): string;
|
|
119
|
+
/**
|
|
120
|
+
* Convert the first letter to lowercase
|
|
121
|
+
*/
|
|
122
|
+
declare function uncapitalize(str: string): string;
|
|
123
|
+
/**
|
|
124
|
+
* Convert a string to a valid TypeScript identifier in camelCase
|
|
125
|
+
* Always returns a string, defaulting to the input if transformation fails
|
|
126
|
+
*
|
|
127
|
+
* @param str - The input string to transform
|
|
128
|
+
* @returns The camelCase identifier or the original string if transformation fails
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* toCamelCaseIdentifier("hello-world"); // "helloWorld"
|
|
133
|
+
* toCamelCaseIdentifier("my_var_name"); // "myVarName"
|
|
134
|
+
* toCamelCaseIdentifier("some.property.name"); // "somePropertyName"
|
|
135
|
+
* toCamelCaseIdentifier("123invalid"); // "invalid"
|
|
136
|
+
* toCamelCaseIdentifier("hello world"); // "helloWorld"
|
|
137
|
+
* toCamelCaseIdentifier("API-Key"); // "aPIKey"
|
|
138
|
+
* toCamelCaseIdentifier("/organization/base"); // "organizationBase"
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
declare function toCamelCaseIdentifier<T extends string>(str: T): CamelCaseIdentifier<T>;
|
|
142
|
+
/**
|
|
143
|
+
* Pretty camelCase conversion that handles abbreviations more intuitively
|
|
144
|
+
* Always returns a string, defaulting to the input if transformation fails
|
|
145
|
+
*
|
|
146
|
+
* @param str - The input string to transform
|
|
147
|
+
* @returns The pretty camelCase identifier or the original string if transformation fails
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* toPrettyCamelCase("API-Key"); // "apiKey"
|
|
152
|
+
* toPrettyCamelCase("HTTP-Response"); // "httpResponse"
|
|
153
|
+
* toPrettyCamelCase("user-ID"); // "userId"
|
|
154
|
+
* toPrettyCamelCase("get-user-by-id"); // "getUserById"
|
|
155
|
+
* toPrettyCamelCase("/organization/base"); // "organizationBase"
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
declare function toPrettyCamelCase<T extends string>(str: T): PrettyCamelCase<T>;
|
|
159
|
+
/**
|
|
160
|
+
* Alternative implementation using a more comprehensive approach
|
|
161
|
+
* for complex cases with better handling of edge cases
|
|
162
|
+
*/
|
|
163
|
+
declare function toValidIdentifier<T extends string>(str: T): ValidIdentifier<T>;
|
|
164
|
+
/**
|
|
165
|
+
* Check if a string is a valid JavaScript/TypeScript identifier
|
|
166
|
+
*/
|
|
167
|
+
declare function isValidIdentifier(str: string): boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Get detailed information about the transformation process
|
|
170
|
+
* Useful for debugging and understanding how the transformation works
|
|
171
|
+
*/
|
|
172
|
+
declare function getTransformationInfo(str: string): {
|
|
173
|
+
original: string;
|
|
174
|
+
withoutLeadingSeparators: string;
|
|
175
|
+
parts: string[];
|
|
176
|
+
camelCase: string;
|
|
177
|
+
prettyCamelCase: string;
|
|
178
|
+
withoutLeadingNumbers: string;
|
|
179
|
+
prettyCamelCaseWithoutLeadingNumbers: string;
|
|
180
|
+
isValid: boolean;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* An empty object literal constant.
|
|
185
|
+
*
|
|
186
|
+
* This constant represents an empty object with no properties.
|
|
187
|
+
* It is commonly used as a default value or placeholder when
|
|
188
|
+
* an empty object is needed.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* const defaultConfig = emptyObject;
|
|
193
|
+
* const merged = { ...emptyObject, ...userConfig };
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
declare const emptyObject: {};
|
|
197
|
+
|
|
1
198
|
/**
|
|
2
199
|
* Extracts the names of arguments from a function's string representation.
|
|
3
200
|
* This is useful for reflection and debugging purposes.
|
|
@@ -48,13 +245,9 @@ declare function isRecord(obj: unknown): obj is Record<string, unknown>;
|
|
|
48
245
|
*/
|
|
49
246
|
declare function isTrue(value: true): true;
|
|
50
247
|
|
|
51
|
-
declare class
|
|
248
|
+
declare class InMemoryBlob extends Blob {
|
|
52
249
|
content: string;
|
|
53
|
-
constructor(content: string
|
|
54
|
-
type?: string;
|
|
55
|
-
endings?: 'transparent' | 'native';
|
|
56
|
-
lastModified?: number;
|
|
57
|
-
});
|
|
250
|
+
constructor(content: string);
|
|
58
251
|
}
|
|
59
252
|
|
|
60
253
|
/**
|
|
@@ -72,6 +265,26 @@ declare class InMemoryFile extends File {
|
|
|
72
265
|
*/
|
|
73
266
|
declare function noop(..._args: unknown[]): void;
|
|
74
267
|
|
|
268
|
+
/**
|
|
269
|
+
* Converts a path with Express-style parameters to OpenAPI-compliant format.
|
|
270
|
+
*
|
|
271
|
+
* Express-style parameters use the format `:paramName` (e.g., `/users/:id`),
|
|
272
|
+
* while OpenAPI uses curly braces `{paramName}` (e.g., `/users/{id}`).
|
|
273
|
+
*
|
|
274
|
+
* @param path - The path string containing Express-style parameters
|
|
275
|
+
* @returns The path string with OpenAPI-compliant parameter format
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```typescript
|
|
279
|
+
* openApiCompliantPath('/users/:id/posts/:postId')
|
|
280
|
+
* // Returns: '/users/{id}/posts/{postId}'
|
|
281
|
+
*
|
|
282
|
+
* openApiCompliantPath('/api/v1/products/:productId/reviews/:reviewId')
|
|
283
|
+
* // Returns: '/api/v1/products/{productId}/reviews/{reviewId}'
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
declare function openApiCompliantPath(path: string): string;
|
|
287
|
+
|
|
75
288
|
declare function readableStreamToAsyncIterable<T>(stream: ReadableStream<T>): AsyncIterable<T>;
|
|
76
289
|
|
|
77
290
|
declare function safeParse<T>(input: unknown): T;
|
|
@@ -104,6 +317,37 @@ declare function safeParse<T>(input: unknown): T;
|
|
|
104
317
|
*/
|
|
105
318
|
declare function safeStringify(arg: unknown): string;
|
|
106
319
|
|
|
320
|
+
/**
|
|
321
|
+
* Removes a trailing slash from a path string if present.
|
|
322
|
+
*
|
|
323
|
+
* @param path - The path string to process
|
|
324
|
+
* @returns The path string with trailing slash removed
|
|
325
|
+
* @example
|
|
326
|
+
* removeTrailingSlash('/users/'); // '/users'
|
|
327
|
+
* removeTrailingSlash('/users'); // '/users'
|
|
328
|
+
*/
|
|
329
|
+
declare function removeTrailingSlash(path: string): string;
|
|
330
|
+
/**
|
|
331
|
+
* Removes a double leading slash from a path string if present.
|
|
332
|
+
*
|
|
333
|
+
* @param path - The path string to process
|
|
334
|
+
* @returns The path string with double leading slash removed
|
|
335
|
+
* @example
|
|
336
|
+
* removeDoubleLeadingSlash('//users'); // '/users'
|
|
337
|
+
* removeDoubleLeadingSlash('/users'); // '/users'
|
|
338
|
+
*/
|
|
339
|
+
declare function removeDoubleLeadingSlash(path: string): string;
|
|
340
|
+
/**
|
|
341
|
+
* Sanitizes a path string by removing both trailing slashes and double leading slashes.
|
|
342
|
+
*
|
|
343
|
+
* @param path - The path string to process
|
|
344
|
+
* @returns The sanitized path string
|
|
345
|
+
* @example
|
|
346
|
+
* sanitizePathSlashes('//users/'); // '/users'
|
|
347
|
+
* sanitizePathSlashes('/users'); // '/users'
|
|
348
|
+
*/
|
|
349
|
+
declare function sanitizePathSlashes(path: string): string;
|
|
350
|
+
|
|
107
351
|
/**
|
|
108
352
|
* Recursively sorts the keys of an object and its nested objects alphabetically.
|
|
109
353
|
* This is useful for consistent object serialization and comparison.
|
|
@@ -125,6 +369,15 @@ declare function sortObjectKeys<T extends Record<string, unknown>>(obj: T): T;
|
|
|
125
369
|
*/
|
|
126
370
|
declare function stripUndefinedProperties<T extends Record<string, unknown>>(obj: T): Partial<T>;
|
|
127
371
|
|
|
372
|
+
/**
|
|
373
|
+
* Converts an object to a record.
|
|
374
|
+
*
|
|
375
|
+
* @template T - The type of the object to convert.
|
|
376
|
+
* @param obj - The object to convert.
|
|
377
|
+
* @returns The record.
|
|
378
|
+
*/
|
|
379
|
+
declare function toRecord<T>(obj: T): Record<string, unknown>;
|
|
380
|
+
|
|
128
381
|
/**
|
|
129
382
|
* Type representing a DTO (Data Transfer Object) with an id field.
|
|
130
383
|
*/
|
|
@@ -173,6 +426,19 @@ type InstanceTypeRecord<T extends Record<string, new (...args: never[]) => unkno
|
|
|
173
426
|
[K in keyof T]: InstanceType<T[K]>;
|
|
174
427
|
};
|
|
175
428
|
|
|
429
|
+
/**
|
|
430
|
+
* Type representing an empty object literal.
|
|
431
|
+
*
|
|
432
|
+
* This type is derived from the `emptyObject` constant and represents
|
|
433
|
+
* an object with no properties.
|
|
434
|
+
*
|
|
435
|
+
* @example
|
|
436
|
+
* ```typescript
|
|
437
|
+
* const obj: EmptyObject = {};
|
|
438
|
+
* ```
|
|
439
|
+
*/
|
|
440
|
+
type EmptyObject = typeof emptyObject;
|
|
441
|
+
|
|
176
442
|
type ExclusiveRecord<T, U> = T extends object ? U extends object ? T & Record<Exclude<keyof T, keyof U>, never> : T : T;
|
|
177
443
|
|
|
178
444
|
/**
|
|
@@ -230,6 +496,18 @@ type MakePropertyOptionalIfChildrenOptional<T> = {
|
|
|
230
496
|
[K in keyof T as AllPropertiesOptional<T[K]> extends true ? never : K]: T[K];
|
|
231
497
|
};
|
|
232
498
|
|
|
499
|
+
/**
|
|
500
|
+
* Merges two objects by unioning the values for duplicate keys
|
|
501
|
+
*/
|
|
502
|
+
type MergeUnionOnCollision<T, U> = {
|
|
503
|
+
[K in keyof T | keyof U]: K extends keyof T ? K extends keyof U ? T[K] | U[K] : T[K] : K extends keyof U ? U[K] : never;
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Recursively merges an array of fetchMap objects
|
|
508
|
+
*/
|
|
509
|
+
type MergeArrayOfMaps<T extends readonly Record<string, unknown>[]> = T extends readonly [infer First, ...infer Rest] ? First extends Record<string, unknown> ? Rest extends readonly Record<string, unknown>[] ? Rest extends readonly [] ? First : MergeUnionOnCollision<First, MergeArrayOfMaps<Rest>> : First : Record<string, never> : Record<string, never>;
|
|
510
|
+
|
|
233
511
|
type MimeType = 'application/json' | 'application/xml' | 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/html' | 'text/plain' | 'image/jpeg' | 'image/png' | 'video/mp4' | 'audio/mpeg' | 'application/pdf' | 'application/zip' | 'application/octet-stream' | string;
|
|
234
512
|
|
|
235
513
|
/**
|
|
@@ -254,9 +532,35 @@ type Prettify<T> = {
|
|
|
254
532
|
* type Route2 = RemoveTrailingSlash<'/users'>; // '/users'
|
|
255
533
|
*/
|
|
256
534
|
type RemoveTrailingSlash<T extends string> = T extends `${infer Route}/` ? Route : T;
|
|
535
|
+
/**
|
|
536
|
+
* Type that removes a double leading slash from a string type if present.
|
|
537
|
+
*
|
|
538
|
+
* @template T - The string type to process
|
|
539
|
+
* @example
|
|
540
|
+
* type Route1 = RemoveDoubleLeadingSlash<'//users'>; // '/users'
|
|
541
|
+
* type Route2 = RemoveDoubleLeadingSlash<'/users'>; // '/users'
|
|
542
|
+
*/
|
|
543
|
+
type RemoveDoubleLeadingSlash<T extends string> = T extends `//${infer Route}` ? `/${Route}` : T;
|
|
544
|
+
/**
|
|
545
|
+
* Type that sanitizes a path string by removing double leading slashes.
|
|
546
|
+
*
|
|
547
|
+
* @template T - The string type to process
|
|
548
|
+
* @example
|
|
549
|
+
* type Route1 = SanitizePathSlashes<'//users'>; // '/users'
|
|
550
|
+
* type Route2 = SanitizePathSlashes<'/users'>; // '/users'
|
|
551
|
+
*/
|
|
552
|
+
type SanitizePathSlashes<T extends string> = RemoveDoubleLeadingSlash<RemoveTrailingSlash<T>>;
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Utility type that excludes strings containing forward slashes
|
|
556
|
+
*/
|
|
557
|
+
type StringWithoutSlash<T extends string> = T extends `${string}/${string}` ? 'cannot contain forward slashes' : T;
|
|
257
558
|
|
|
258
559
|
type TypeSafeFunction = (...args: never[]) => unknown;
|
|
259
560
|
|
|
260
561
|
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
562
|
+
type UnionToIntersectionChildren<U> = {
|
|
563
|
+
[K in keyof U]: UnionToIntersection<U[K]>;
|
|
564
|
+
};
|
|
261
565
|
|
|
262
|
-
export { type ExclusiveRecord, type Flatten, type FlattenKeys, type FlattenValues, type IdDto, type IdsDto,
|
|
566
|
+
export { type CamelCaseIdentifier, type EmptyObject, type ExclusiveRecord, type Flatten, type FlattenKeys, type FlattenValues, type IdDto, type IdsDto, InMemoryBlob, type InstanceTypeRecord, type MakePropertyOptionalIfChildrenOptional, type MergeArrayOfMaps, type MergeUnionOnCollision, type MimeType, type Prettify, type PrettyCamelCase, type RecordTimingDto, type RemoveDoubleLeadingSlash, type RemoveTrailingSlash, type ReturnTypeRecord, type SanitizePathSlashes, type StringWithoutSlash, type TypeSafeFunction, type UnionToIntersection, type UnionToIntersectionChildren, type ValidIdentifier, capitalize, emptyObject, extractArgumentNames, getEnvVar, getTransformationInfo, isAsyncGenerator, isNever, isNodeJsWriteableStream, isRecord, isTrue, isValidIdentifier, noop, openApiCompliantPath, readableStreamToAsyncIterable, removeDoubleLeadingSlash, removeLeadingNumbers, removeLeadingSeparators, removeNonAlphanumeric, removeTrailingSlash, safeParse, safeStringify, sanitizePathSlashes, sortObjectKeys, splitBySeparators, stripUndefinedProperties, toCamelCaseIdentifier, toPrettyCamelCase, toRecord, toValidIdentifier, uncapitalize };
|
package/lib/index.js
CHANGED
|
@@ -20,23 +20,133 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
|
|
23
|
+
InMemoryBlob: () => InMemoryBlob,
|
|
24
|
+
capitalize: () => capitalize,
|
|
25
|
+
emptyObject: () => emptyObject,
|
|
24
26
|
extractArgumentNames: () => extractArgumentNames,
|
|
25
27
|
getEnvVar: () => getEnvVar,
|
|
28
|
+
getTransformationInfo: () => getTransformationInfo,
|
|
26
29
|
isAsyncGenerator: () => isAsyncGenerator,
|
|
27
30
|
isNever: () => isNever,
|
|
28
31
|
isNodeJsWriteableStream: () => isNodeJsWriteableStream,
|
|
29
32
|
isRecord: () => isRecord,
|
|
30
33
|
isTrue: () => isTrue,
|
|
34
|
+
isValidIdentifier: () => isValidIdentifier,
|
|
31
35
|
noop: () => noop,
|
|
36
|
+
openApiCompliantPath: () => openApiCompliantPath,
|
|
32
37
|
readableStreamToAsyncIterable: () => readableStreamToAsyncIterable,
|
|
38
|
+
removeDoubleLeadingSlash: () => removeDoubleLeadingSlash,
|
|
39
|
+
removeLeadingNumbers: () => removeLeadingNumbers,
|
|
40
|
+
removeLeadingSeparators: () => removeLeadingSeparators,
|
|
41
|
+
removeNonAlphanumeric: () => removeNonAlphanumeric,
|
|
42
|
+
removeTrailingSlash: () => removeTrailingSlash,
|
|
33
43
|
safeParse: () => safeParse,
|
|
34
44
|
safeStringify: () => safeStringify,
|
|
45
|
+
sanitizePathSlashes: () => sanitizePathSlashes,
|
|
35
46
|
sortObjectKeys: () => sortObjectKeys,
|
|
36
|
-
|
|
47
|
+
splitBySeparators: () => splitBySeparators,
|
|
48
|
+
stripUndefinedProperties: () => stripUndefinedProperties,
|
|
49
|
+
toCamelCaseIdentifier: () => toCamelCaseIdentifier,
|
|
50
|
+
toPrettyCamelCase: () => toPrettyCamelCase,
|
|
51
|
+
toRecord: () => toRecord,
|
|
52
|
+
toValidIdentifier: () => toValidIdentifier,
|
|
53
|
+
uncapitalize: () => uncapitalize
|
|
37
54
|
});
|
|
38
55
|
module.exports = __toCommonJS(index_exports);
|
|
39
56
|
|
|
57
|
+
// src/camelCase.ts
|
|
58
|
+
var SEPARATOR_REGEX = /[ \-_./:]+/g;
|
|
59
|
+
var LEADING_SEPARATOR_REGEX = /^[ \-_./:]+/;
|
|
60
|
+
var NON_ALPHANUMERIC_REGEX = /[^a-zA-Z0-9]/g;
|
|
61
|
+
var LEADING_NUMBERS_REGEX = /^[0-9]+/;
|
|
62
|
+
function removeLeadingSeparators(str) {
|
|
63
|
+
return str.replace(LEADING_SEPARATOR_REGEX, "");
|
|
64
|
+
}
|
|
65
|
+
function splitBySeparators(str) {
|
|
66
|
+
return str.split(SEPARATOR_REGEX).filter((part) => part.length > 0);
|
|
67
|
+
}
|
|
68
|
+
function removeNonAlphanumeric(str) {
|
|
69
|
+
return str.replace(NON_ALPHANUMERIC_REGEX, "");
|
|
70
|
+
}
|
|
71
|
+
function removeLeadingNumbers(str) {
|
|
72
|
+
return str.replace(LEADING_NUMBERS_REGEX, "");
|
|
73
|
+
}
|
|
74
|
+
function capitalize(str) {
|
|
75
|
+
if (!str) return str;
|
|
76
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
77
|
+
}
|
|
78
|
+
function uncapitalize(str) {
|
|
79
|
+
if (!str) return str;
|
|
80
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
81
|
+
}
|
|
82
|
+
function joinCamelCase(parts) {
|
|
83
|
+
if (parts.length === 0) return "";
|
|
84
|
+
const cleanedParts = parts.map(removeNonAlphanumeric).filter((part) => part.length > 0);
|
|
85
|
+
if (cleanedParts.length === 0) return "";
|
|
86
|
+
const [first, ...rest] = cleanedParts;
|
|
87
|
+
return uncapitalize(first) + rest.map(capitalize).join("");
|
|
88
|
+
}
|
|
89
|
+
function joinPrettyCamelCase(parts) {
|
|
90
|
+
if (parts.length === 0) return "";
|
|
91
|
+
const cleanedParts = parts.map((part) => removeNonAlphanumeric(part.toLowerCase())).filter((part) => part.length > 0);
|
|
92
|
+
if (cleanedParts.length === 0) return "";
|
|
93
|
+
const [first, ...rest] = cleanedParts;
|
|
94
|
+
return first + rest.map(capitalize).join("");
|
|
95
|
+
}
|
|
96
|
+
function toCamelCaseIdentifier(str) {
|
|
97
|
+
if (typeof str !== "string") return String(str);
|
|
98
|
+
try {
|
|
99
|
+
const withoutLeadingSeparators = removeLeadingSeparators(str);
|
|
100
|
+
const parts = splitBySeparators(withoutLeadingSeparators);
|
|
101
|
+
const camelCased = joinCamelCase(parts);
|
|
102
|
+
const withoutLeadingNumbers = removeLeadingNumbers(camelCased);
|
|
103
|
+
return withoutLeadingNumbers || str;
|
|
104
|
+
} catch {
|
|
105
|
+
return str;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function toPrettyCamelCase(str) {
|
|
109
|
+
if (typeof str !== "string") return String(str);
|
|
110
|
+
try {
|
|
111
|
+
const withoutLeadingSeparators = removeLeadingSeparators(str);
|
|
112
|
+
const parts = splitBySeparators(withoutLeadingSeparators);
|
|
113
|
+
const camelCased = joinPrettyCamelCase(parts);
|
|
114
|
+
const withoutLeadingNumbers = removeLeadingNumbers(camelCased);
|
|
115
|
+
return withoutLeadingNumbers || str;
|
|
116
|
+
} catch {
|
|
117
|
+
return str;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function toValidIdentifier(str) {
|
|
121
|
+
return toCamelCaseIdentifier(str);
|
|
122
|
+
}
|
|
123
|
+
function isValidIdentifier(str) {
|
|
124
|
+
if (typeof str !== "string" || str.length === 0) return false;
|
|
125
|
+
if (!/^[a-zA-Z_$]/.test(str)) return false;
|
|
126
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(str);
|
|
127
|
+
}
|
|
128
|
+
function getTransformationInfo(str) {
|
|
129
|
+
const withoutLeadingSeparators = removeLeadingSeparators(str);
|
|
130
|
+
const parts = splitBySeparators(withoutLeadingSeparators);
|
|
131
|
+
const camelCase = joinCamelCase(parts);
|
|
132
|
+
const prettyCamelCase = joinPrettyCamelCase(parts);
|
|
133
|
+
const withoutLeadingNumbers = removeLeadingNumbers(camelCase);
|
|
134
|
+
const prettyCamelCaseWithoutLeadingNumbers = removeLeadingNumbers(prettyCamelCase);
|
|
135
|
+
return {
|
|
136
|
+
original: str,
|
|
137
|
+
withoutLeadingSeparators,
|
|
138
|
+
parts,
|
|
139
|
+
camelCase,
|
|
140
|
+
prettyCamelCase,
|
|
141
|
+
withoutLeadingNumbers,
|
|
142
|
+
prettyCamelCaseWithoutLeadingNumbers,
|
|
143
|
+
isValid: isValidIdentifier(withoutLeadingNumbers)
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/emptyObject.ts
|
|
148
|
+
var emptyObject = {};
|
|
149
|
+
|
|
40
150
|
// src/extractArgumentNames.ts
|
|
41
151
|
function extractArgumentNames(func) {
|
|
42
152
|
const fnStr = func.toString();
|
|
@@ -96,18 +206,10 @@ function isTrue(value) {
|
|
|
96
206
|
return value;
|
|
97
207
|
}
|
|
98
208
|
|
|
99
|
-
// src/
|
|
100
|
-
var
|
|
101
|
-
constructor(content
|
|
102
|
-
|
|
103
|
-
endings,
|
|
104
|
-
lastModified
|
|
105
|
-
}) {
|
|
106
|
-
super([Buffer.from(content)], name, {
|
|
107
|
-
type,
|
|
108
|
-
endings,
|
|
109
|
-
lastModified
|
|
110
|
-
});
|
|
209
|
+
// src/InMemoryBlob.ts
|
|
210
|
+
var InMemoryBlob = class extends Blob {
|
|
211
|
+
constructor(content) {
|
|
212
|
+
super([Buffer.from(content)]);
|
|
111
213
|
this.content = content;
|
|
112
214
|
}
|
|
113
215
|
};
|
|
@@ -116,6 +218,11 @@ var InMemoryFile = class extends File {
|
|
|
116
218
|
function noop(..._args) {
|
|
117
219
|
}
|
|
118
220
|
|
|
221
|
+
// src/openApiCompliantPath.ts
|
|
222
|
+
function openApiCompliantPath(path) {
|
|
223
|
+
return path.replaceAll(/:(\w+)/g, "{$1}");
|
|
224
|
+
}
|
|
225
|
+
|
|
119
226
|
// src/readableStreamToAsyncIterable.ts
|
|
120
227
|
async function* readableStreamToAsyncIterable(stream) {
|
|
121
228
|
const reader = stream.getReader();
|
|
@@ -212,6 +319,17 @@ function safeStringify(arg) {
|
|
|
212
319
|
}
|
|
213
320
|
}
|
|
214
321
|
|
|
322
|
+
// src/slashManipulation.ts
|
|
323
|
+
function removeTrailingSlash(path) {
|
|
324
|
+
return path.replace(/\/$/, "");
|
|
325
|
+
}
|
|
326
|
+
function removeDoubleLeadingSlash(path) {
|
|
327
|
+
return path.replace(/^\/\//, "/");
|
|
328
|
+
}
|
|
329
|
+
function sanitizePathSlashes(path) {
|
|
330
|
+
return removeDoubleLeadingSlash(removeTrailingSlash(path));
|
|
331
|
+
}
|
|
332
|
+
|
|
215
333
|
// src/sortObjectKeys.ts
|
|
216
334
|
function sortObjectKeys(obj) {
|
|
217
335
|
if (typeof obj !== "object" || obj === null) {
|
|
@@ -233,20 +351,42 @@ function stripUndefinedProperties(obj) {
|
|
|
233
351
|
Object.entries(obj).filter(([, value]) => value !== void 0)
|
|
234
352
|
);
|
|
235
353
|
}
|
|
354
|
+
|
|
355
|
+
// src/toRecord.ts
|
|
356
|
+
function toRecord(obj) {
|
|
357
|
+
return obj;
|
|
358
|
+
}
|
|
236
359
|
// Annotate the CommonJS export names for ESM import in node:
|
|
237
360
|
0 && (module.exports = {
|
|
238
|
-
|
|
361
|
+
InMemoryBlob,
|
|
362
|
+
capitalize,
|
|
363
|
+
emptyObject,
|
|
239
364
|
extractArgumentNames,
|
|
240
365
|
getEnvVar,
|
|
366
|
+
getTransformationInfo,
|
|
241
367
|
isAsyncGenerator,
|
|
242
368
|
isNever,
|
|
243
369
|
isNodeJsWriteableStream,
|
|
244
370
|
isRecord,
|
|
245
371
|
isTrue,
|
|
372
|
+
isValidIdentifier,
|
|
246
373
|
noop,
|
|
374
|
+
openApiCompliantPath,
|
|
247
375
|
readableStreamToAsyncIterable,
|
|
376
|
+
removeDoubleLeadingSlash,
|
|
377
|
+
removeLeadingNumbers,
|
|
378
|
+
removeLeadingSeparators,
|
|
379
|
+
removeNonAlphanumeric,
|
|
380
|
+
removeTrailingSlash,
|
|
248
381
|
safeParse,
|
|
249
382
|
safeStringify,
|
|
383
|
+
sanitizePathSlashes,
|
|
250
384
|
sortObjectKeys,
|
|
251
|
-
|
|
385
|
+
splitBySeparators,
|
|
386
|
+
stripUndefinedProperties,
|
|
387
|
+
toCamelCaseIdentifier,
|
|
388
|
+
toPrettyCamelCase,
|
|
389
|
+
toRecord,
|
|
390
|
+
toValidIdentifier,
|
|
391
|
+
uncapitalize
|
|
252
392
|
});
|
package/lib/index.mjs
CHANGED
|
@@ -1,3 +1,96 @@
|
|
|
1
|
+
// src/camelCase.ts
|
|
2
|
+
var SEPARATOR_REGEX = /[ \-_./:]+/g;
|
|
3
|
+
var LEADING_SEPARATOR_REGEX = /^[ \-_./:]+/;
|
|
4
|
+
var NON_ALPHANUMERIC_REGEX = /[^a-zA-Z0-9]/g;
|
|
5
|
+
var LEADING_NUMBERS_REGEX = /^[0-9]+/;
|
|
6
|
+
function removeLeadingSeparators(str) {
|
|
7
|
+
return str.replace(LEADING_SEPARATOR_REGEX, "");
|
|
8
|
+
}
|
|
9
|
+
function splitBySeparators(str) {
|
|
10
|
+
return str.split(SEPARATOR_REGEX).filter((part) => part.length > 0);
|
|
11
|
+
}
|
|
12
|
+
function removeNonAlphanumeric(str) {
|
|
13
|
+
return str.replace(NON_ALPHANUMERIC_REGEX, "");
|
|
14
|
+
}
|
|
15
|
+
function removeLeadingNumbers(str) {
|
|
16
|
+
return str.replace(LEADING_NUMBERS_REGEX, "");
|
|
17
|
+
}
|
|
18
|
+
function capitalize(str) {
|
|
19
|
+
if (!str) return str;
|
|
20
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
21
|
+
}
|
|
22
|
+
function uncapitalize(str) {
|
|
23
|
+
if (!str) return str;
|
|
24
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
25
|
+
}
|
|
26
|
+
function joinCamelCase(parts) {
|
|
27
|
+
if (parts.length === 0) return "";
|
|
28
|
+
const cleanedParts = parts.map(removeNonAlphanumeric).filter((part) => part.length > 0);
|
|
29
|
+
if (cleanedParts.length === 0) return "";
|
|
30
|
+
const [first, ...rest] = cleanedParts;
|
|
31
|
+
return uncapitalize(first) + rest.map(capitalize).join("");
|
|
32
|
+
}
|
|
33
|
+
function joinPrettyCamelCase(parts) {
|
|
34
|
+
if (parts.length === 0) return "";
|
|
35
|
+
const cleanedParts = parts.map((part) => removeNonAlphanumeric(part.toLowerCase())).filter((part) => part.length > 0);
|
|
36
|
+
if (cleanedParts.length === 0) return "";
|
|
37
|
+
const [first, ...rest] = cleanedParts;
|
|
38
|
+
return first + rest.map(capitalize).join("");
|
|
39
|
+
}
|
|
40
|
+
function toCamelCaseIdentifier(str) {
|
|
41
|
+
if (typeof str !== "string") return String(str);
|
|
42
|
+
try {
|
|
43
|
+
const withoutLeadingSeparators = removeLeadingSeparators(str);
|
|
44
|
+
const parts = splitBySeparators(withoutLeadingSeparators);
|
|
45
|
+
const camelCased = joinCamelCase(parts);
|
|
46
|
+
const withoutLeadingNumbers = removeLeadingNumbers(camelCased);
|
|
47
|
+
return withoutLeadingNumbers || str;
|
|
48
|
+
} catch {
|
|
49
|
+
return str;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function toPrettyCamelCase(str) {
|
|
53
|
+
if (typeof str !== "string") return String(str);
|
|
54
|
+
try {
|
|
55
|
+
const withoutLeadingSeparators = removeLeadingSeparators(str);
|
|
56
|
+
const parts = splitBySeparators(withoutLeadingSeparators);
|
|
57
|
+
const camelCased = joinPrettyCamelCase(parts);
|
|
58
|
+
const withoutLeadingNumbers = removeLeadingNumbers(camelCased);
|
|
59
|
+
return withoutLeadingNumbers || str;
|
|
60
|
+
} catch {
|
|
61
|
+
return str;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function toValidIdentifier(str) {
|
|
65
|
+
return toCamelCaseIdentifier(str);
|
|
66
|
+
}
|
|
67
|
+
function isValidIdentifier(str) {
|
|
68
|
+
if (typeof str !== "string" || str.length === 0) return false;
|
|
69
|
+
if (!/^[a-zA-Z_$]/.test(str)) return false;
|
|
70
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(str);
|
|
71
|
+
}
|
|
72
|
+
function getTransformationInfo(str) {
|
|
73
|
+
const withoutLeadingSeparators = removeLeadingSeparators(str);
|
|
74
|
+
const parts = splitBySeparators(withoutLeadingSeparators);
|
|
75
|
+
const camelCase = joinCamelCase(parts);
|
|
76
|
+
const prettyCamelCase = joinPrettyCamelCase(parts);
|
|
77
|
+
const withoutLeadingNumbers = removeLeadingNumbers(camelCase);
|
|
78
|
+
const prettyCamelCaseWithoutLeadingNumbers = removeLeadingNumbers(prettyCamelCase);
|
|
79
|
+
return {
|
|
80
|
+
original: str,
|
|
81
|
+
withoutLeadingSeparators,
|
|
82
|
+
parts,
|
|
83
|
+
camelCase,
|
|
84
|
+
prettyCamelCase,
|
|
85
|
+
withoutLeadingNumbers,
|
|
86
|
+
prettyCamelCaseWithoutLeadingNumbers,
|
|
87
|
+
isValid: isValidIdentifier(withoutLeadingNumbers)
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/emptyObject.ts
|
|
92
|
+
var emptyObject = {};
|
|
93
|
+
|
|
1
94
|
// src/extractArgumentNames.ts
|
|
2
95
|
function extractArgumentNames(func) {
|
|
3
96
|
const fnStr = func.toString();
|
|
@@ -57,18 +150,10 @@ function isTrue(value) {
|
|
|
57
150
|
return value;
|
|
58
151
|
}
|
|
59
152
|
|
|
60
|
-
// src/
|
|
61
|
-
var
|
|
62
|
-
constructor(content
|
|
63
|
-
|
|
64
|
-
endings,
|
|
65
|
-
lastModified
|
|
66
|
-
}) {
|
|
67
|
-
super([Buffer.from(content)], name, {
|
|
68
|
-
type,
|
|
69
|
-
endings,
|
|
70
|
-
lastModified
|
|
71
|
-
});
|
|
153
|
+
// src/InMemoryBlob.ts
|
|
154
|
+
var InMemoryBlob = class extends Blob {
|
|
155
|
+
constructor(content) {
|
|
156
|
+
super([Buffer.from(content)]);
|
|
72
157
|
this.content = content;
|
|
73
158
|
}
|
|
74
159
|
};
|
|
@@ -77,6 +162,11 @@ var InMemoryFile = class extends File {
|
|
|
77
162
|
function noop(..._args) {
|
|
78
163
|
}
|
|
79
164
|
|
|
165
|
+
// src/openApiCompliantPath.ts
|
|
166
|
+
function openApiCompliantPath(path) {
|
|
167
|
+
return path.replaceAll(/:(\w+)/g, "{$1}");
|
|
168
|
+
}
|
|
169
|
+
|
|
80
170
|
// src/readableStreamToAsyncIterable.ts
|
|
81
171
|
async function* readableStreamToAsyncIterable(stream) {
|
|
82
172
|
const reader = stream.getReader();
|
|
@@ -173,6 +263,17 @@ function safeStringify(arg) {
|
|
|
173
263
|
}
|
|
174
264
|
}
|
|
175
265
|
|
|
266
|
+
// src/slashManipulation.ts
|
|
267
|
+
function removeTrailingSlash(path) {
|
|
268
|
+
return path.replace(/\/$/, "");
|
|
269
|
+
}
|
|
270
|
+
function removeDoubleLeadingSlash(path) {
|
|
271
|
+
return path.replace(/^\/\//, "/");
|
|
272
|
+
}
|
|
273
|
+
function sanitizePathSlashes(path) {
|
|
274
|
+
return removeDoubleLeadingSlash(removeTrailingSlash(path));
|
|
275
|
+
}
|
|
276
|
+
|
|
176
277
|
// src/sortObjectKeys.ts
|
|
177
278
|
function sortObjectKeys(obj) {
|
|
178
279
|
if (typeof obj !== "object" || obj === null) {
|
|
@@ -194,19 +295,41 @@ function stripUndefinedProperties(obj) {
|
|
|
194
295
|
Object.entries(obj).filter(([, value]) => value !== void 0)
|
|
195
296
|
);
|
|
196
297
|
}
|
|
298
|
+
|
|
299
|
+
// src/toRecord.ts
|
|
300
|
+
function toRecord(obj) {
|
|
301
|
+
return obj;
|
|
302
|
+
}
|
|
197
303
|
export {
|
|
198
|
-
|
|
304
|
+
InMemoryBlob,
|
|
305
|
+
capitalize,
|
|
306
|
+
emptyObject,
|
|
199
307
|
extractArgumentNames,
|
|
200
308
|
getEnvVar,
|
|
309
|
+
getTransformationInfo,
|
|
201
310
|
isAsyncGenerator,
|
|
202
311
|
isNever,
|
|
203
312
|
isNodeJsWriteableStream,
|
|
204
313
|
isRecord,
|
|
205
314
|
isTrue,
|
|
315
|
+
isValidIdentifier,
|
|
206
316
|
noop,
|
|
317
|
+
openApiCompliantPath,
|
|
207
318
|
readableStreamToAsyncIterable,
|
|
319
|
+
removeDoubleLeadingSlash,
|
|
320
|
+
removeLeadingNumbers,
|
|
321
|
+
removeLeadingSeparators,
|
|
322
|
+
removeNonAlphanumeric,
|
|
323
|
+
removeTrailingSlash,
|
|
208
324
|
safeParse,
|
|
209
325
|
safeStringify,
|
|
326
|
+
sanitizePathSlashes,
|
|
210
327
|
sortObjectKeys,
|
|
211
|
-
|
|
328
|
+
splitBySeparators,
|
|
329
|
+
stripUndefinedProperties,
|
|
330
|
+
toCamelCaseIdentifier,
|
|
331
|
+
toPrettyCamelCase,
|
|
332
|
+
toRecord,
|
|
333
|
+
toValidIdentifier,
|
|
334
|
+
uncapitalize
|
|
212
335
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forklaunch/common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Common package for base types, interfaces, implementations.",
|
|
5
5
|
"homepage": "https://github.com/forklaunch/forklaunch-js#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -28,16 +28,16 @@
|
|
|
28
28
|
"lib/**"
|
|
29
29
|
],
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@eslint/js": "^9.
|
|
32
|
-
"@types/node": "^24.0.
|
|
33
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
31
|
+
"@eslint/js": "^9.30.0",
|
|
32
|
+
"@types/node": "^24.0.7",
|
|
33
|
+
"@typescript/native-preview": "7.0.0-dev.20250630.1",
|
|
34
34
|
"depcheck": "^1.4.7",
|
|
35
|
-
"eslint": "^9.
|
|
35
|
+
"eslint": "^9.30.0",
|
|
36
36
|
"globals": "^16.2.0",
|
|
37
37
|
"tsup": "^8.5.0",
|
|
38
|
-
"typedoc": "^0.28.
|
|
38
|
+
"typedoc": "^0.28.7",
|
|
39
39
|
"typescript": "^5.8.3",
|
|
40
|
-
"typescript-eslint": "^8.
|
|
40
|
+
"typescript-eslint": "^8.35.1",
|
|
41
41
|
"vitest": "^3.2.4"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|