@forklaunch/common 0.4.5 → 0.5.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 CHANGED
@@ -245,6 +245,26 @@ declare function isRecord(obj: unknown): obj is Record<string, unknown>;
245
245
  */
246
246
  declare function isTrue(value: true): true;
247
247
 
248
+ /**
249
+ * Computes a simple, non-cryptographic hash code for a given string.
250
+ *
251
+ * This function is synchronous and works in all JavaScript environments, including browsers and Node.js.
252
+ * It is suitable for basic hashing needs such as object uniqueness checks, but should NOT be used for
253
+ * cryptographic or security-sensitive purposes.
254
+ *
255
+ * The algorithm is based on a simple bitwise operation and may produce collisions for similar strings.
256
+ *
257
+ * @param {string} str - The input string to hash.
258
+ * @returns {number} The resulting hash code as a 32-bit signed integer.
259
+ *
260
+ * @example
261
+ * ```typescript
262
+ * const hash = hashStringSync("hello");
263
+ * console.log(hash); // e.g., 99162322
264
+ * ```
265
+ */
266
+ declare function hashString(str: string): number;
267
+
248
268
  declare class InMemoryBlob extends Blob {
249
269
  content: string;
250
270
  constructor(content: string);
@@ -504,7 +524,7 @@ type MergeUnionOnCollision<T, U> = {
504
524
  };
505
525
 
506
526
  /**
507
- * Recursively merges an array of fetchMap objects
527
+ * Recursively merges an array of _fetchMap objects
508
528
  */
509
529
  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
530
 
@@ -558,9 +578,63 @@ type StringWithoutSlash<T extends string> = T extends `${string}/${string}` ? 'c
558
578
 
559
579
  type TypeSafeFunction = (...args: never[]) => unknown;
560
580
 
581
+ /**
582
+ * Utility type that converts a union type to an intersection type.
583
+ * Uses TypeScript's conditional type inference to transform U | V into U & V.
584
+ * This is a fundamental utility type used throughout the ForkLaunch framework
585
+ * for merging multiple types into a single intersection.
586
+ *
587
+ * @template U - The union type to convert to an intersection
588
+ * @param U - Any union type (e.g., A | B | C)
589
+ *
590
+ * @returns The intersection of all types in the union (e.g., A & B & C)
591
+ *
592
+ * @example
593
+ * ```typescript
594
+ * type Union = { a: string } | { b: number } | { c: boolean };
595
+ * type Intersection = UnionToIntersection<Union>;
596
+ * // Results in: { a: string } & { b: number } & { c: boolean }
597
+ *
598
+ * // Practical usage in API merging
599
+ * type Api1 = { users: { getUser: () => Promise<User> } };
600
+ * type Api2 = { posts: { getPosts: () => Promise<Post[]> } };
601
+ * type MergedApi = UnionToIntersection<Api1 | Api2>;
602
+ * // Results in: { users: { getUser: () => Promise<User> } } & { posts: { getPosts: () => Promise<Post[]> } }
603
+ * ```
604
+ */
561
605
  type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
606
+ /**
607
+ * Applies UnionToIntersection recursively to all children of an object type.
608
+ * This is useful when you have an object where each property contains a union type,
609
+ * and you want to convert all those unions to intersections while preserving
610
+ * the object structure.
611
+ *
612
+ * @template U - The object type whose children should be converted
613
+ * @param U - An object type where each property may be a union type
614
+ *
615
+ * @returns An object type with the same keys as U, but where each value
616
+ * has been processed through UnionToIntersection
617
+ *
618
+ * @example
619
+ * ```typescript
620
+ * type ApiConfig = {
621
+ * users: { getUser: () => Promise<User> } | { getUser: (id: string) => Promise<User> };
622
+ * posts: { getPosts: () => Promise<Post[]> } | { getPosts: (limit: number) => Promise<Post[]> };
623
+ * };
624
+ *
625
+ * type NormalizedApi = UnionToIntersectionChildren<ApiConfig>;
626
+ * // Results in:
627
+ * // {
628
+ * // users: { getUser: () => Promise<User> } & { getUser: (id: string) => Promise<User> };
629
+ * // posts: { getPosts: () => Promise<Post[]> } & { getPosts: (limit: number) => Promise<Post[]> };
630
+ * // }
631
+ *
632
+ * // This is particularly useful for merging multiple API configurations
633
+ * // where each endpoint might have multiple overloads
634
+ * ```
635
+ */
562
636
  type UnionToIntersectionChildren<U> = {
563
637
  [K in keyof U]: UnionToIntersection<U[K]>;
564
638
  };
565
639
 
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 };
640
+ 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, hashString, 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
@@ -245,6 +245,26 @@ declare function isRecord(obj: unknown): obj is Record<string, unknown>;
245
245
  */
246
246
  declare function isTrue(value: true): true;
247
247
 
248
+ /**
249
+ * Computes a simple, non-cryptographic hash code for a given string.
250
+ *
251
+ * This function is synchronous and works in all JavaScript environments, including browsers and Node.js.
252
+ * It is suitable for basic hashing needs such as object uniqueness checks, but should NOT be used for
253
+ * cryptographic or security-sensitive purposes.
254
+ *
255
+ * The algorithm is based on a simple bitwise operation and may produce collisions for similar strings.
256
+ *
257
+ * @param {string} str - The input string to hash.
258
+ * @returns {number} The resulting hash code as a 32-bit signed integer.
259
+ *
260
+ * @example
261
+ * ```typescript
262
+ * const hash = hashStringSync("hello");
263
+ * console.log(hash); // e.g., 99162322
264
+ * ```
265
+ */
266
+ declare function hashString(str: string): number;
267
+
248
268
  declare class InMemoryBlob extends Blob {
249
269
  content: string;
250
270
  constructor(content: string);
@@ -504,7 +524,7 @@ type MergeUnionOnCollision<T, U> = {
504
524
  };
505
525
 
506
526
  /**
507
- * Recursively merges an array of fetchMap objects
527
+ * Recursively merges an array of _fetchMap objects
508
528
  */
509
529
  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
530
 
@@ -558,9 +578,63 @@ type StringWithoutSlash<T extends string> = T extends `${string}/${string}` ? 'c
558
578
 
559
579
  type TypeSafeFunction = (...args: never[]) => unknown;
560
580
 
581
+ /**
582
+ * Utility type that converts a union type to an intersection type.
583
+ * Uses TypeScript's conditional type inference to transform U | V into U & V.
584
+ * This is a fundamental utility type used throughout the ForkLaunch framework
585
+ * for merging multiple types into a single intersection.
586
+ *
587
+ * @template U - The union type to convert to an intersection
588
+ * @param U - Any union type (e.g., A | B | C)
589
+ *
590
+ * @returns The intersection of all types in the union (e.g., A & B & C)
591
+ *
592
+ * @example
593
+ * ```typescript
594
+ * type Union = { a: string } | { b: number } | { c: boolean };
595
+ * type Intersection = UnionToIntersection<Union>;
596
+ * // Results in: { a: string } & { b: number } & { c: boolean }
597
+ *
598
+ * // Practical usage in API merging
599
+ * type Api1 = { users: { getUser: () => Promise<User> } };
600
+ * type Api2 = { posts: { getPosts: () => Promise<Post[]> } };
601
+ * type MergedApi = UnionToIntersection<Api1 | Api2>;
602
+ * // Results in: { users: { getUser: () => Promise<User> } } & { posts: { getPosts: () => Promise<Post[]> } }
603
+ * ```
604
+ */
561
605
  type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
606
+ /**
607
+ * Applies UnionToIntersection recursively to all children of an object type.
608
+ * This is useful when you have an object where each property contains a union type,
609
+ * and you want to convert all those unions to intersections while preserving
610
+ * the object structure.
611
+ *
612
+ * @template U - The object type whose children should be converted
613
+ * @param U - An object type where each property may be a union type
614
+ *
615
+ * @returns An object type with the same keys as U, but where each value
616
+ * has been processed through UnionToIntersection
617
+ *
618
+ * @example
619
+ * ```typescript
620
+ * type ApiConfig = {
621
+ * users: { getUser: () => Promise<User> } | { getUser: (id: string) => Promise<User> };
622
+ * posts: { getPosts: () => Promise<Post[]> } | { getPosts: (limit: number) => Promise<Post[]> };
623
+ * };
624
+ *
625
+ * type NormalizedApi = UnionToIntersectionChildren<ApiConfig>;
626
+ * // Results in:
627
+ * // {
628
+ * // users: { getUser: () => Promise<User> } & { getUser: (id: string) => Promise<User> };
629
+ * // posts: { getPosts: () => Promise<Post[]> } & { getPosts: (limit: number) => Promise<Post[]> };
630
+ * // }
631
+ *
632
+ * // This is particularly useful for merging multiple API configurations
633
+ * // where each endpoint might have multiple overloads
634
+ * ```
635
+ */
562
636
  type UnionToIntersectionChildren<U> = {
563
637
  [K in keyof U]: UnionToIntersection<U[K]>;
564
638
  };
565
639
 
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 };
640
+ 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, hashString, 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
@@ -26,6 +26,7 @@ __export(index_exports, {
26
26
  extractArgumentNames: () => extractArgumentNames,
27
27
  getEnvVar: () => getEnvVar,
28
28
  getTransformationInfo: () => getTransformationInfo,
29
+ hashString: () => hashString,
29
30
  isAsyncGenerator: () => isAsyncGenerator,
30
31
  isNever: () => isNever,
31
32
  isNodeJsWriteableStream: () => isNodeJsWriteableStream,
@@ -206,6 +207,18 @@ function isTrue(value) {
206
207
  return value;
207
208
  }
208
209
 
210
+ // src/hashString.ts
211
+ function hashString(str) {
212
+ let hash = 0;
213
+ if (str.length === 0) return hash;
214
+ for (let i = 0; i < str.length; i++) {
215
+ const char = str.charCodeAt(i);
216
+ hash = (hash << 5) - hash + char;
217
+ hash = hash & hash;
218
+ }
219
+ return hash;
220
+ }
221
+
209
222
  // src/InMemoryBlob.ts
210
223
  var InMemoryBlob = class extends Blob {
211
224
  constructor(content) {
@@ -364,6 +377,7 @@ function toRecord(obj) {
364
377
  extractArgumentNames,
365
378
  getEnvVar,
366
379
  getTransformationInfo,
380
+ hashString,
367
381
  isAsyncGenerator,
368
382
  isNever,
369
383
  isNodeJsWriteableStream,
package/lib/index.mjs CHANGED
@@ -150,6 +150,18 @@ function isTrue(value) {
150
150
  return value;
151
151
  }
152
152
 
153
+ // src/hashString.ts
154
+ function hashString(str) {
155
+ let hash = 0;
156
+ if (str.length === 0) return hash;
157
+ for (let i = 0; i < str.length; i++) {
158
+ const char = str.charCodeAt(i);
159
+ hash = (hash << 5) - hash + char;
160
+ hash = hash & hash;
161
+ }
162
+ return hash;
163
+ }
164
+
153
165
  // src/InMemoryBlob.ts
154
166
  var InMemoryBlob = class extends Blob {
155
167
  constructor(content) {
@@ -307,6 +319,7 @@ export {
307
319
  extractArgumentNames,
308
320
  getEnvVar,
309
321
  getTransformationInfo,
322
+ hashString,
310
323
  isAsyncGenerator,
311
324
  isNever,
312
325
  isNodeJsWriteableStream,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forklaunch/common",
3
- "version": "0.4.5",
3
+ "version": "0.5.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.31.0",
32
- "@types/node": "^24.0.13",
33
- "@typescript/native-preview": "7.0.0-dev.20250712.1",
31
+ "@eslint/js": "^9.33.0",
32
+ "@types/node": "^24.3.0",
33
+ "@typescript/native-preview": "7.0.0-dev.20250820.1",
34
34
  "depcheck": "^1.4.7",
35
- "eslint": "^9.31.0",
35
+ "eslint": "^9.33.0",
36
36
  "globals": "^16.3.0",
37
37
  "tsup": "^8.5.0",
38
- "typedoc": "^0.28.7",
39
- "typescript": "^5.8.3",
40
- "typescript-eslint": "^8.36.0",
38
+ "typedoc": "^0.28.10",
39
+ "typescript": "^5.9.2",
40
+ "typescript-eslint": "^8.40.0",
41
41
  "vitest": "^3.2.4"
42
42
  },
43
43
  "scripts": {