@digitaldefiance/branded-enum 0.0.5 → 0.0.6

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/factory.ts"],"sourcesContent":["/**\n * Factory function for creating branded enums.\n *\n * Creates enum-like objects with runtime metadata for identification,\n * while keeping values as raw strings for serialization compatibility.\n */\n\nimport {\n BrandedEnum,\n BrandedEnumMetadata,\n ENUM_ID,\n ENUM_VALUES,\n} from './types.js';\nimport { registerEnum } from './registry.js';\n\n/**\n * Creates a branded enum with runtime metadata.\n *\n * The returned object:\n * - Contains all provided key-value pairs as enumerable properties\n * - Has non-enumerable Symbol properties for metadata (ENUM_ID, ENUM_VALUES)\n * - Is frozen to prevent modification\n * - Is registered in the global registry\n *\n * @template T - The shape of the values object (use `as const` for literal types)\n * @param enumId - Unique identifier for this enum. Must be unique across all\n * branded enums in the application.\n * @param values - Object containing key-value pairs where keys are enum member\n * names and values are the string values. Use `as const` for literal type inference.\n * @returns A frozen branded enum object with attached metadata\n * @throws {Error} Throws `Error` with message `Branded enum with ID \"${enumId}\" already exists`\n * if an enum with the same ID has already been registered.\n *\n * @example\n * // Basic usage\n * const Status = createBrandedEnum('status', {\n * Active: 'active',\n * Inactive: 'inactive',\n * } as const);\n *\n * Status.Active // 'active' (raw string)\n * getEnumId(Status) // 'status'\n *\n * @example\n * // Type inference with as const\n * const Colors = createBrandedEnum('colors', {\n * Red: 'red',\n * Green: 'green',\n * Blue: 'blue',\n * } as const);\n *\n * type ColorValue = typeof Colors[keyof typeof Colors]; // 'red' | 'green' | 'blue'\n *\n * @example\n * // Error handling for duplicate IDs\n * createBrandedEnum('myEnum', { A: 'a' } as const);\n * createBrandedEnum('myEnum', { B: 'b' } as const); // Throws Error\n */\nexport function createBrandedEnum<T extends Record<string, string>>(\n enumId: string,\n values: T\n): BrandedEnum<T> {\n // Create the enum object with user values\n const enumObj = { ...values } as T & BrandedEnumMetadata;\n\n // Collect all values into a Set for O(1) membership checks\n const valueSet = new Set<string>(Object.values(values));\n\n // Attach non-enumerable Symbol properties for metadata\n Object.defineProperty(enumObj, ENUM_ID, {\n value: enumId,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n Object.defineProperty(enumObj, ENUM_VALUES, {\n value: valueSet,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n // Freeze the object to prevent modification\n const frozenEnum = Object.freeze(enumObj) as BrandedEnum<T>;\n\n // Register in global registry (throws if duplicate ID)\n registerEnum(frozenEnum);\n\n return frozenEnum;\n}\n"],"names":["ENUM_ID","ENUM_VALUES","registerEnum","createBrandedEnum","enumId","values","enumObj","valueSet","Set","Object","defineProperty","value","enumerable","writable","configurable","frozenEnum","freeze"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;;;CAKC,GAED,SAGEA,OAAO,EACPC,WAAW,QACN,aAAa;AACpB,SAASC,YAAY,QAAQ,gBAAgB;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0CC,GACD,OAAO,SAASC,kBACdC,MAAc,EACdC,MAAS;IAET,0CAA0C;IAC1C,MAAMC,UAAU;QAAE,GAAGD,MAAM;IAAC;IAE5B,2DAA2D;IAC3D,MAAME,WAAW,IAAIC,IAAYC,OAAOJ,MAAM,CAACA;IAE/C,uDAAuD;IACvDI,OAAOC,cAAc,CAACJ,SAASN,SAAS;QACtCW,OAAOP;QACPQ,YAAY;QACZC,UAAU;QACVC,cAAc;IAChB;IAEAL,OAAOC,cAAc,CAACJ,SAASL,aAAa;QAC1CU,OAAOJ;QACPK,YAAY;QACZC,UAAU;QACVC,cAAc;IAChB;IAEA,4CAA4C;IAC5C,MAAMC,aAAaN,OAAOO,MAAM,CAACV;IAEjC,uDAAuD;IACvDJ,aAAaa;IAEb,OAAOA;AACT"}
1
+ {"version":3,"sources":["../../../src/lib/factory.ts"],"sourcesContent":["/**\n * Factory function for creating branded enums.\n *\n * Creates enum-like objects with runtime metadata for identification,\n * while keeping values as raw strings for serialization compatibility.\n */\n\nimport {\n BrandedEnum,\n BrandedEnumMetadata,\n ENUM_ID,\n ENUM_VALUES,\n} from './types.js';\nimport { getRegistry, registerEnum } from './registry.js';\n\n/**\n * Creates a branded enum with runtime metadata.\n *\n * The returned object:\n * - Contains all provided key-value pairs as enumerable properties\n * - Has non-enumerable Symbol properties for metadata (ENUM_ID, ENUM_VALUES)\n * - Is frozen to prevent modification\n * - Is registered in the global registry\n *\n * This function is idempotent - if an enum with the same ID already exists,\n * the existing enum is returned instead of creating a new one. This enables\n * safe usage in module-scoped code that may be re-executed in test environments\n * or hot-reload scenarios.\n *\n * @template T - The shape of the values object (use `as const` for literal types)\n * @param enumId - Unique identifier for this enum. Must be unique across all\n * branded enums in the application.\n * @param values - Object containing key-value pairs where keys are enum member\n * names and values are the string values. Use `as const` for literal type inference.\n * @returns A frozen branded enum object with attached metadata\n *\n * @example\n * // Basic usage\n * const Status = createBrandedEnum('status', {\n * Active: 'active',\n * Inactive: 'inactive',\n * } as const);\n *\n * Status.Active // 'active' (raw string)\n * getEnumId(Status) // 'status'\n *\n * @example\n * // Type inference with as const\n * const Colors = createBrandedEnum('colors', {\n * Red: 'red',\n * Green: 'green',\n * Blue: 'blue',\n * } as const);\n *\n * type ColorValue = typeof Colors[keyof typeof Colors]; // 'red' | 'green' | 'blue'\n *\n * @example\n * // Safe re-registration (idempotent)\n * const Enum1 = createBrandedEnum('myEnum', { A: 'a' } as const);\n * const Enum2 = createBrandedEnum('myEnum', { A: 'a' } as const);\n * // Enum1 === Enum2 (same reference)\n */\nexport function createBrandedEnum<T extends Record<string, string>>(\n enumId: string,\n values: T\n): BrandedEnum<T> {\n // Check if already registered - return existing enum (idempotent)\n const registry = getRegistry();\n const existing = registry.enums.get(enumId);\n if (existing) {\n return existing.enumObj as BrandedEnum<T>;\n }\n\n // Create the enum object with user values\n const enumObj = { ...values } as T & BrandedEnumMetadata;\n\n // Collect all values into a Set for O(1) membership checks\n const valueSet = new Set<string>(Object.values(values));\n\n // Attach non-enumerable Symbol properties for metadata\n Object.defineProperty(enumObj, ENUM_ID, {\n value: enumId,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n Object.defineProperty(enumObj, ENUM_VALUES, {\n value: valueSet,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n // Freeze the object to prevent modification\n const frozenEnum = Object.freeze(enumObj) as BrandedEnum<T>;\n\n // Register in global registry (throws if duplicate ID)\n registerEnum(frozenEnum);\n\n return frozenEnum;\n}\n"],"names":["ENUM_ID","ENUM_VALUES","getRegistry","registerEnum","createBrandedEnum","enumId","values","registry","existing","enums","get","enumObj","valueSet","Set","Object","defineProperty","value","enumerable","writable","configurable","frozenEnum","freeze"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;;;CAKC,GAED,SAGEA,OAAO,EACPC,WAAW,QACN,aAAa;AACpB,SAASC,WAAW,EAAEC,YAAY,QAAQ,gBAAgB;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CC,GACD,OAAO,SAASC,kBACdC,MAAc,EACdC,MAAS;IAET,kEAAkE;IAClE,MAAMC,WAAWL;IACjB,MAAMM,WAAWD,SAASE,KAAK,CAACC,GAAG,CAACL;IACpC,IAAIG,UAAU;QACZ,OAAOA,SAASG,OAAO;IACzB;IAEA,0CAA0C;IAC1C,MAAMA,UAAU;QAAE,GAAGL,MAAM;IAAC;IAE5B,2DAA2D;IAC3D,MAAMM,WAAW,IAAIC,IAAYC,OAAOR,MAAM,CAACA;IAE/C,uDAAuD;IACvDQ,OAAOC,cAAc,CAACJ,SAASX,SAAS;QACtCgB,OAAOX;QACPY,YAAY;QACZC,UAAU;QACVC,cAAc;IAChB;IAEAL,OAAOC,cAAc,CAACJ,SAASV,aAAa;QAC1Ce,OAAOJ;QACPK,YAAY;QACZC,UAAU;QACVC,cAAc;IAChB;IAEA,4CAA4C;IAC5C,MAAMC,aAAaN,OAAOO,MAAM,CAACV;IAEjC,uDAAuD;IACvDR,aAAaiB;IAEb,OAAOA;AACT"}
@@ -17,15 +17,14 @@ import { AnyBrandedEnum, BrandedEnum } from './types.js';
17
17
  * - Duplicate values (same value in multiple enums) are allowed
18
18
  *
19
19
  * @template T - Tuple of branded enum types being merged
20
- * @param newId - Unique identifier for the merged enum. Must not already
21
- * be registered.
20
+ * @param newId - Unique identifier for the merged enum. If already registered,
21
+ * returns the existing enum (idempotent behavior).
22
22
  * @param enums - One or more branded enums to merge
23
- * @returns A new branded enum containing all values from source enums
23
+ * @returns A new branded enum containing all values from source enums,
24
+ * or the existing enum if newId is already registered
24
25
  * @throws {Error} Throws `Error` with message
25
26
  * `Cannot merge enums: duplicate key "${key}" found in enums "${enumId1}" and "${enumId2}"`
26
27
  * if the same key exists in multiple source enums.
27
- * @throws {Error} Throws `Error` with message
28
- * `Branded enum with ID "${newId}" already exists` if newId is already registered.
29
28
  * @throws {Error} Throws `Error` with message `All arguments must be branded enums`
30
29
  * if any argument is not a valid branded enum.
31
30
  *
@@ -1 +1 @@
1
- {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../../src/lib/merge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,WAAW,EAAwB,MAAM,YAAY,CAAC;AA2B/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE,EAC5D,KAAK,EAAE,MAAM,EACb,GAAG,KAAK,EAAE,CAAC,GACV,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA6BrC"}
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../../src/lib/merge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,WAAW,EAAwB,MAAM,YAAY,CAAC;AA2B/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE,EAC5D,KAAK,EAAE,MAAM,EACb,GAAG,KAAK,EAAE,CAAC,GACV,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA6BrC"}
@@ -22,15 +22,14 @@ import { createBrandedEnum } from './factory.js';
22
22
  * - Duplicate values (same value in multiple enums) are allowed
23
23
  *
24
24
  * @template T - Tuple of branded enum types being merged
25
- * @param newId - Unique identifier for the merged enum. Must not already
26
- * be registered.
25
+ * @param newId - Unique identifier for the merged enum. If already registered,
26
+ * returns the existing enum (idempotent behavior).
27
27
  * @param enums - One or more branded enums to merge
28
- * @returns A new branded enum containing all values from source enums
28
+ * @returns A new branded enum containing all values from source enums,
29
+ * or the existing enum if newId is already registered
29
30
  * @throws {Error} Throws `Error` with message
30
31
  * `Cannot merge enums: duplicate key "${key}" found in enums "${enumId1}" and "${enumId2}"`
31
32
  * if the same key exists in multiple source enums.
32
- * @throws {Error} Throws `Error` with message
33
- * `Branded enum with ID "${newId}" already exists` if newId is already registered.
34
33
  * @throws {Error} Throws `Error` with message `All arguments must be branded enums`
35
34
  * if any argument is not a valid branded enum.
36
35
  *
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/merge.ts"],"sourcesContent":["/**\n * Enum composition functions for branded enums.\n *\n * Enables merging multiple branded enums into a new combined enum\n * while maintaining type safety and registry tracking.\n */\n\nimport { AnyBrandedEnum, BrandedEnum, ENUM_ID, ENUM_VALUES } from './types.js';\nimport { createBrandedEnum } from './factory.js';\n\n/**\n * Type helper to extract the values type from a branded enum.\n */\ntype ExtractValues<E> = E extends BrandedEnum<infer T> ? T : never;\n\n/**\n * Type helper to merge multiple branded enum value types into one.\n */\ntype MergedValues<T extends AnyBrandedEnum[]> = {\n [K in keyof T]: ExtractValues<T[K]>;\n}[number];\n\n/**\n * Checks if an object is a branded enum.\n */\nfunction isBrandedEnum(obj: unknown): obj is AnyBrandedEnum {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n ENUM_ID in obj &&\n ENUM_VALUES in obj\n );\n}\n\n/**\n * Merges multiple branded enums into a new branded enum.\n *\n * Creates a new branded enum that contains all key-value pairs from all\n * source enums. The merged enum is registered in the global registry\n * as a new independent enum.\n *\n * Key collision handling:\n * - Duplicate keys (same key in multiple enums) throw an error\n * - Duplicate values (same value in multiple enums) are allowed\n *\n * @template T - Tuple of branded enum types being merged\n * @param newId - Unique identifier for the merged enum. Must not already\n * be registered.\n * @param enums - One or more branded enums to merge\n * @returns A new branded enum containing all values from source enums\n * @throws {Error} Throws `Error` with message\n * `Cannot merge enums: duplicate key \"${key}\" found in enums \"${enumId1}\" and \"${enumId2}\"`\n * if the same key exists in multiple source enums.\n * @throws {Error} Throws `Error` with message\n * `Branded enum with ID \"${newId}\" already exists` if newId is already registered.\n * @throws {Error} Throws `Error` with message `All arguments must be branded enums`\n * if any argument is not a valid branded enum.\n *\n * @example\n * // Basic merge\n * const Colors = createBrandedEnum('colors', { Red: 'red', Blue: 'blue' } as const);\n * const Sizes = createBrandedEnum('sizes', { Small: 'small', Large: 'large' } as const);\n *\n * const Combined = mergeEnums('combined', Colors, Sizes);\n * // Combined has: Red, Blue, Small, Large\n *\n * Combined.Red; // 'red'\n * Combined.Small; // 'small'\n *\n * @example\n * // Duplicate values are allowed\n * const Status1 = createBrandedEnum('status1', { Active: 'active' } as const);\n * const Status2 = createBrandedEnum('status2', { Enabled: 'active' } as const);\n *\n * const Merged = mergeEnums('merged', Status1, Status2);\n * // Both Active and Enabled have value 'active' - this is allowed\n *\n * @example\n * // Duplicate keys throw an error\n * const Enum1 = createBrandedEnum('enum1', { Key: 'value1' } as const);\n * const Enum2 = createBrandedEnum('enum2', { Key: 'value2' } as const);\n *\n * try {\n * mergeEnums('merged', Enum1, Enum2);\n * } catch (e) {\n * console.log(e.message);\n * // 'Cannot merge enums: duplicate key \"Key\" found in enums \"enum1\" and \"enum2\"'\n * }\n */\nexport function mergeEnums<T extends readonly AnyBrandedEnum[]>(\n newId: string,\n ...enums: T\n): BrandedEnum<Record<string, string>> {\n // Collect all key-value pairs, checking for duplicate keys\n const mergedValues: Record<string, string> = {};\n const seenKeys = new Map<string, string>(); // key -> source enumId\n\n for (const enumObj of enums) {\n if (!isBrandedEnum(enumObj)) {\n throw new Error('All arguments must be branded enums');\n }\n\n const sourceEnumId = enumObj[ENUM_ID];\n\n // Iterate over enumerable properties (user-defined keys only)\n for (const [key, value] of Object.entries(enumObj)) {\n // Check for duplicate keys\n if (seenKeys.has(key)) {\n const originalEnumId = seenKeys.get(key);\n throw new Error(\n `Cannot merge enums: duplicate key \"${key}\" found in enums \"${originalEnumId}\" and \"${sourceEnumId}\"`\n );\n }\n\n seenKeys.set(key, sourceEnumId);\n mergedValues[key] = value as string;\n }\n }\n\n // Create and return the new branded enum (this handles registration)\n return createBrandedEnum(newId, mergedValues) as BrandedEnum<MergedValues<[...T]>>;\n}\n"],"names":["ENUM_ID","ENUM_VALUES","createBrandedEnum","isBrandedEnum","obj","mergeEnums","newId","enums","mergedValues","seenKeys","Map","enumObj","Error","sourceEnumId","key","value","Object","entries","has","originalEnumId","get","set"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;;;CAKC,GAED,SAAsCA,OAAO,EAAEC,WAAW,QAAQ,aAAa;AAC/E,SAASC,iBAAiB,QAAQ,eAAe;AAcjD;;CAEC,GACD,SAASC,cAAcC,GAAY;IACjC,OACE,OAAOA,QAAQ,YACfA,QAAQ,QACRJ,WAAWI,OACXH,eAAeG;AAEnB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsDC,GACD,OAAO,SAASC,WACdC,KAAa,EACb,GAAGC,KAAQ;IAEX,2DAA2D;IAC3D,MAAMC,eAAuC,CAAC;IAC9C,MAAMC,WAAW,IAAIC,OAAuB,uBAAuB;IAEnE,KAAK,MAAMC,WAAWJ,MAAO;QAC3B,IAAI,CAACJ,cAAcQ,UAAU;YAC3B,MAAM,IAAIC,MAAM;QAClB;QAEA,MAAMC,eAAeF,OAAO,CAACX,QAAQ;QAErC,8DAA8D;QAC9D,KAAK,MAAM,CAACc,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACN,SAAU;YAClD,2BAA2B;YAC3B,IAAIF,SAASS,GAAG,CAACJ,MAAM;gBACrB,MAAMK,iBAAiBV,SAASW,GAAG,CAACN;gBACpC,MAAM,IAAIF,MACR,CAAC,mCAAmC,EAAEE,IAAI,kBAAkB,EAAEK,eAAe,OAAO,EAAEN,aAAa,CAAC,CAAC;YAEzG;YAEAJ,SAASY,GAAG,CAACP,KAAKD;YAClBL,YAAY,CAACM,IAAI,GAAGC;QACtB;IACF;IAEA,qEAAqE;IACrE,OAAOb,kBAAkBI,OAAOE;AAClC"}
1
+ {"version":3,"sources":["../../../src/lib/merge.ts"],"sourcesContent":["/**\n * Enum composition functions for branded enums.\n *\n * Enables merging multiple branded enums into a new combined enum\n * while maintaining type safety and registry tracking.\n */\n\nimport { AnyBrandedEnum, BrandedEnum, ENUM_ID, ENUM_VALUES } from './types.js';\nimport { createBrandedEnum } from './factory.js';\n\n/**\n * Type helper to extract the values type from a branded enum.\n */\ntype ExtractValues<E> = E extends BrandedEnum<infer T> ? T : never;\n\n/**\n * Type helper to merge multiple branded enum value types into one.\n */\ntype MergedValues<T extends AnyBrandedEnum[]> = {\n [K in keyof T]: ExtractValues<T[K]>;\n}[number];\n\n/**\n * Checks if an object is a branded enum.\n */\nfunction isBrandedEnum(obj: unknown): obj is AnyBrandedEnum {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n ENUM_ID in obj &&\n ENUM_VALUES in obj\n );\n}\n\n/**\n * Merges multiple branded enums into a new branded enum.\n *\n * Creates a new branded enum that contains all key-value pairs from all\n * source enums. The merged enum is registered in the global registry\n * as a new independent enum.\n *\n * Key collision handling:\n * - Duplicate keys (same key in multiple enums) throw an error\n * - Duplicate values (same value in multiple enums) are allowed\n *\n * @template T - Tuple of branded enum types being merged\n * @param newId - Unique identifier for the merged enum. If already registered,\n * returns the existing enum (idempotent behavior).\n * @param enums - One or more branded enums to merge\n * @returns A new branded enum containing all values from source enums,\n * or the existing enum if newId is already registered\n * @throws {Error} Throws `Error` with message\n * `Cannot merge enums: duplicate key \"${key}\" found in enums \"${enumId1}\" and \"${enumId2}\"`\n * if the same key exists in multiple source enums.\n * @throws {Error} Throws `Error` with message `All arguments must be branded enums`\n * if any argument is not a valid branded enum.\n *\n * @example\n * // Basic merge\n * const Colors = createBrandedEnum('colors', { Red: 'red', Blue: 'blue' } as const);\n * const Sizes = createBrandedEnum('sizes', { Small: 'small', Large: 'large' } as const);\n *\n * const Combined = mergeEnums('combined', Colors, Sizes);\n * // Combined has: Red, Blue, Small, Large\n *\n * Combined.Red; // 'red'\n * Combined.Small; // 'small'\n *\n * @example\n * // Duplicate values are allowed\n * const Status1 = createBrandedEnum('status1', { Active: 'active' } as const);\n * const Status2 = createBrandedEnum('status2', { Enabled: 'active' } as const);\n *\n * const Merged = mergeEnums('merged', Status1, Status2);\n * // Both Active and Enabled have value 'active' - this is allowed\n *\n * @example\n * // Duplicate keys throw an error\n * const Enum1 = createBrandedEnum('enum1', { Key: 'value1' } as const);\n * const Enum2 = createBrandedEnum('enum2', { Key: 'value2' } as const);\n *\n * try {\n * mergeEnums('merged', Enum1, Enum2);\n * } catch (e) {\n * console.log(e.message);\n * // 'Cannot merge enums: duplicate key \"Key\" found in enums \"enum1\" and \"enum2\"'\n * }\n */\nexport function mergeEnums<T extends readonly AnyBrandedEnum[]>(\n newId: string,\n ...enums: T\n): BrandedEnum<Record<string, string>> {\n // Collect all key-value pairs, checking for duplicate keys\n const mergedValues: Record<string, string> = {};\n const seenKeys = new Map<string, string>(); // key -> source enumId\n\n for (const enumObj of enums) {\n if (!isBrandedEnum(enumObj)) {\n throw new Error('All arguments must be branded enums');\n }\n\n const sourceEnumId = enumObj[ENUM_ID];\n\n // Iterate over enumerable properties (user-defined keys only)\n for (const [key, value] of Object.entries(enumObj)) {\n // Check for duplicate keys\n if (seenKeys.has(key)) {\n const originalEnumId = seenKeys.get(key);\n throw new Error(\n `Cannot merge enums: duplicate key \"${key}\" found in enums \"${originalEnumId}\" and \"${sourceEnumId}\"`\n );\n }\n\n seenKeys.set(key, sourceEnumId);\n mergedValues[key] = value as string;\n }\n }\n\n // Create and return the new branded enum (this handles registration)\n return createBrandedEnum(newId, mergedValues) as BrandedEnum<MergedValues<[...T]>>;\n}\n"],"names":["ENUM_ID","ENUM_VALUES","createBrandedEnum","isBrandedEnum","obj","mergeEnums","newId","enums","mergedValues","seenKeys","Map","enumObj","Error","sourceEnumId","key","value","Object","entries","has","originalEnumId","get","set"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;;;CAKC,GAED,SAAsCA,OAAO,EAAEC,WAAW,QAAQ,aAAa;AAC/E,SAASC,iBAAiB,QAAQ,eAAe;AAcjD;;CAEC,GACD,SAASC,cAAcC,GAAY;IACjC,OACE,OAAOA,QAAQ,YACfA,QAAQ,QACRJ,WAAWI,OACXH,eAAeG;AAEnB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqDC,GACD,OAAO,SAASC,WACdC,KAAa,EACb,GAAGC,KAAQ;IAEX,2DAA2D;IAC3D,MAAMC,eAAuC,CAAC;IAC9C,MAAMC,WAAW,IAAIC,OAAuB,uBAAuB;IAEnE,KAAK,MAAMC,WAAWJ,MAAO;QAC3B,IAAI,CAACJ,cAAcQ,UAAU;YAC3B,MAAM,IAAIC,MAAM;QAClB;QAEA,MAAMC,eAAeF,OAAO,CAACX,QAAQ;QAErC,8DAA8D;QAC9D,KAAK,MAAM,CAACc,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACN,SAAU;YAClD,2BAA2B;YAC3B,IAAIF,SAASS,GAAG,CAACJ,MAAM;gBACrB,MAAMK,iBAAiBV,SAASW,GAAG,CAACN;gBACpC,MAAM,IAAIF,MACR,CAAC,mCAAmC,EAAEE,IAAI,kBAAkB,EAAEK,eAAe,OAAO,EAAEN,aAAa,CAAC,CAAC;YAEzG;YAEAJ,SAASY,GAAG,CAACP,KAAKD;YAClBL,YAAY,CAACM,IAAI,GAAGC;QACtB;IACF;IAEA,qEAAqE;IACrE,OAAOb,kBAAkBI,OAAOE;AAClC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitaldefiance/branded-enum",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "Runtime-identifiable enum-like types for TypeScript with zero runtime overhead",
5
5
  "license": "MIT",
6
6
  "type": "module",