@digitaldefiance/branded-enum 0.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/types.ts"],"sourcesContent":["/**\n * Core type definitions for branded-enum library\n *\n * These types enable runtime-identifiable enum-like objects in TypeScript\n * with zero runtime overhead for value access.\n */\n\n/**\n * Symbol key for storing the enum ID metadata.\n * Using a Symbol prevents collision with user-defined keys.\n */\nexport const ENUM_ID: unique symbol = Symbol('ENUM_ID');\n\n/**\n * Symbol key for storing the enum values Set.\n * Using a Symbol prevents collision with user-defined keys.\n */\nexport const ENUM_VALUES: unique symbol = Symbol('ENUM_VALUES');\n\n/**\n * Metadata attached to branded enums via Symbol properties.\n * These properties are non-enumerable and won't appear in\n * Object.keys(), Object.values(), or JSON serialization.\n */\nexport interface BrandedEnumMetadata {\n readonly [ENUM_ID]: string;\n readonly [ENUM_VALUES]: Set<string>;\n}\n\n/**\n * A branded enum object - combines the user's values object with metadata.\n * The object is frozen (Readonly) to prevent modification after creation.\n *\n * @template T - The shape of the enum values object (Record<string, string>)\n */\nexport type BrandedEnum<T extends Record<string, string>> = Readonly<T> &\n BrandedEnumMetadata;\n\n/**\n * Base constraint type for branded enums that works with both\n * `as const` objects and regular Record<string, string> objects.\n *\n * This type is more permissive than `BrandedEnum<Record<string, string>>`\n * and allows literal types from `as const` assertions.\n */\nexport type AnyBrandedEnum = {\n readonly [ENUM_ID]: string;\n readonly [ENUM_VALUES]: Set<string>;\n};\n\n/**\n * Utility type to extract the union of all value types from a branded enum.\n * Useful for typing variables that can hold any value from the enum.\n *\n * @template E - A BrandedEnum type\n *\n * @example\n * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' } as const);\n * type StatusValue = BrandedEnumValue<typeof Status>; // 'active' | 'inactive'\n */\nexport type BrandedEnumValue<E extends AnyBrandedEnum> =\n E extends BrandedEnum<infer T> ? T[keyof T] : never;\n\n/**\n * Registry entry for tracking a single branded enum in the global registry.\n */\nexport interface RegistryEntry {\n /** The unique identifier for this enum */\n readonly enumId: string;\n /** The branded enum object itself */\n readonly enumObj: BrandedEnum<Record<string, string>>;\n /** Set of all values in this enum for O(1) lookup */\n readonly values: Set<string>;\n}\n\n/**\n * Global registry structure stored on globalThis.\n * Enables cross-bundle tracking of all branded enums.\n */\nexport interface BrandedEnumRegistry {\n /** Map from enumId to registry entry */\n readonly enums: Map<string, RegistryEntry>;\n /** Reverse index: value -> Set of enumIds containing that value */\n readonly valueIndex: Map<string, Set<string>>;\n}\n\n/**\n * The key used to store the registry on globalThis.\n * Namespaced to avoid collisions with other libraries.\n */\nexport const REGISTRY_KEY = '__brandedEnumRegistry__' as const;\n\n/**\n * The key used to store the enum consumer registry on globalThis.\n * Tracks which classes consume which branded enums.\n */\nexport const CONSUMER_REGISTRY_KEY = '__brandedEnumConsumerRegistry__' as const;\n\n/**\n * Entry tracking a class that consumes branded enums.\n */\nexport interface EnumConsumerEntry {\n /** The class constructor function */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly classRef: new (...args: any[]) => any;\n /** The class name */\n readonly className: string;\n /** Set of enum IDs that this class consumes */\n readonly enumIds: Set<string>;\n}\n\n/**\n * Global registry for tracking enum consumers (classes decorated with @EnumClass).\n * Enables debugging and introspection of enum usage across the codebase.\n */\nexport interface EnumConsumerRegistry {\n /** Map from class name to consumer entry */\n readonly consumers: Map<string, EnumConsumerEntry>;\n /** Reverse index: enumId -> Set of class names consuming that enum */\n readonly enumToConsumers: Map<string, Set<string>>;\n}\n\n// =============================================================================\n// Compile-Time Validation Types\n// =============================================================================\n\n/**\n * Extracts the union of all keys from a branded enum.\n *\n * This utility type provides compile-time access to all key names of a branded enum,\n * excluding the Symbol metadata keys (ENUM_ID and ENUM_VALUES).\n *\n * @template E - A BrandedEnum type\n *\n * @example\n * const Status = createBrandedEnum('status', {\n * Active: 'active',\n * Inactive: 'inactive',\n * Pending: 'pending',\n * } as const);\n *\n * type StatusKeys = EnumKeys<typeof Status>;\n * // StatusKeys = 'Active' | 'Inactive' | 'Pending'\n *\n * @example\n * // Use in function parameters\n * function getStatusLabel<E extends AnyBrandedEnum>(\n * enumObj: E,\n * key: EnumKeys<E>\n * ): string {\n * return enumObj[key] as string;\n * }\n */\nexport type EnumKeys<E> = E extends BrandedEnum<infer T>\n ? keyof T & string\n : E extends AnyBrandedEnum\n ? Exclude<keyof E, typeof ENUM_ID | typeof ENUM_VALUES> & string\n : never;\n\n/**\n * Extracts the union of all values from a branded enum.\n *\n * This is an alias for BrandedEnumValue that provides a more intuitive name\n * when working with compile-time type utilities.\n *\n * @template E - A BrandedEnum type\n *\n * @example\n * const Status = createBrandedEnum('status', {\n * Active: 'active',\n * Inactive: 'inactive',\n * Pending: 'pending',\n * } as const);\n *\n * type StatusValues = EnumValues<typeof Status>;\n * // StatusValues = 'active' | 'inactive' | 'pending'\n *\n * @example\n * // Use for type-safe value handling\n * function processStatus(value: EnumValues<typeof Status>) {\n * // value is 'active' | 'inactive' | 'pending'\n * }\n */\nexport type EnumValues<E> = E extends BrandedEnum<infer T>\n ? T[keyof T]\n : E extends AnyBrandedEnum\n ? Exclude<E[Exclude<keyof E, typeof ENUM_ID | typeof ENUM_VALUES>], Set<string>> & string\n : never;\n\n/**\n * Validates that a value type V is a valid value of branded enum E at compile time.\n *\n * If V is a valid value of E, this type resolves to V.\n * If V is NOT a valid value of E, this type resolves to `never`, causing a compile error\n * when used in contexts that expect a non-never type.\n *\n * This enables compile-time validation of enum values without runtime overhead.\n *\n * @template E - A BrandedEnum type\n * @template V - The value type to validate\n *\n * @example\n * const Status = createBrandedEnum('status', {\n * Active: 'active',\n * Inactive: 'inactive',\n * } as const);\n *\n * // Valid - 'active' is in Status\n * type Valid = ValidEnumValue<typeof Status, 'active'>; // 'active'\n *\n * // Invalid - 'unknown' is not in Status\n * type Invalid = ValidEnumValue<typeof Status, 'unknown'>; // never\n *\n * @example\n * // Use in function to enforce valid values at compile time\n * function setStatus<V extends string>(\n * value: ValidEnumValue<typeof Status, V>\n * ): void {\n * // Only compiles if value is 'active' | 'inactive'\n * }\n *\n * setStatus('active'); // OK\n * setStatus('inactive'); // OK\n * // setStatus('unknown'); // Compile error: Argument of type 'never' is not assignable\n *\n * @example\n * // Type-level assertion\n * type AssertActive = ValidEnumValue<typeof Status, 'active'>; // 'active' - OK\n * type AssertBad = ValidEnumValue<typeof Status, 'bad'>; // never - indicates invalid\n */\nexport type ValidEnumValue<E, V extends string> = V extends EnumValues<E>\n ? V\n : never;\n\n/**\n * Creates a strict parameter type that only accepts valid values from a branded enum.\n *\n * This utility type is designed for function parameters where you want to enforce\n * that only values from a specific branded enum are accepted at compile time.\n *\n * Unlike using `BrandedEnumValue<E>` directly, `StrictEnumParam` provides better\n * error messages and works well with generic functions.\n *\n * @template E - A BrandedEnum type\n *\n * @example\n * const Status = createBrandedEnum('status', {\n * Active: 'active',\n * Inactive: 'inactive',\n * Pending: 'pending',\n * } as const);\n *\n * // Function that only accepts Status values\n * function updateStatus(newStatus: StrictEnumParam<typeof Status>): void {\n * console.log(`Status updated to: ${newStatus}`);\n * }\n *\n * updateStatus(Status.Active); // OK\n * updateStatus('active'); // OK (literal type matches)\n * // updateStatus('unknown'); // Compile error\n *\n * @example\n * // Use with multiple enum parameters\n * const Priority = createBrandedEnum('priority', {\n * High: 'high',\n * Medium: 'medium',\n * Low: 'low',\n * } as const);\n *\n * function createTask(\n * status: StrictEnumParam<typeof Status>,\n * priority: StrictEnumParam<typeof Priority>\n * ): void {\n * // Both parameters are type-safe\n * }\n *\n * createTask(Status.Active, Priority.High); // OK\n * createTask('active', 'high'); // OK\n * // createTask('active', 'invalid'); // Compile error on second param\n *\n * @example\n * // Generic function with strict enum constraint\n * function processValue<E extends AnyBrandedEnum>(\n * enumObj: E,\n * value: StrictEnumParam<E>\n * ): void {\n * // value is guaranteed to be a valid value of enumObj\n * }\n */\nexport type StrictEnumParam<E> = EnumValues<E>;\n"],"names":["ENUM_ID","Symbol","ENUM_VALUES","REGISTRY_KEY","CONSUMER_REGISTRY_KEY"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;;;CAKC,GAED;;;CAGC,GACD,OAAO,MAAMA,UAAyBC,OAAO,WAAW;AAExD;;;CAGC,GACD,OAAO,MAAMC,cAA6BD,OAAO,eAAe;AAqEhE;;;CAGC,GACD,OAAO,MAAME,eAAe,0BAAmC;AAE/D;;;CAGC,GACD,OAAO,MAAMC,wBAAwB,kCAA2C"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Utility functions for branded enums.
3
+ *
4
+ * Provides additional functionality beyond standard enum operations,
5
+ * including reverse lookup, key validation, and iteration.
6
+ */ import { ENUM_ID, ENUM_VALUES } from './types.js';
7
+ /**
8
+ * Checks if an object is a branded enum (has Symbol metadata).
9
+ *
10
+ * @param obj - The object to check
11
+ * @returns true if obj is a branded enum
12
+ */ function isBrandedEnum(obj) {
13
+ return obj !== null && typeof obj === 'object' && ENUM_ID in obj && ENUM_VALUES in obj && typeof obj[ENUM_ID] === 'string' && obj[ENUM_VALUES] instanceof Set;
14
+ }
15
+ /**
16
+ * Checks if a value exists in a branded enum (reverse lookup).
17
+ *
18
+ * Similar to `isFromEnum`, but with arguments in a different order that
19
+ * may be more natural for some use cases. Also provides type narrowing.
20
+ *
21
+ * @template E - The branded enum type
22
+ * @param enumObj - The branded enum to search in
23
+ * @param value - The value to check. Can be any type; non-strings return false.
24
+ * @returns `true` if the value exists in the enum (with type narrowing),
25
+ * `false` otherwise. Returns `false` for non-string values or if
26
+ * enumObj is not a branded enum.
27
+ *
28
+ * @example
29
+ * // Check if value exists
30
+ * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' } as const);
31
+ * hasValue(Status, 'active'); // true
32
+ * hasValue(Status, 'unknown'); // false
33
+ *
34
+ * @example
35
+ * // Returns false for non-string values
36
+ * hasValue(Status, 123); // false
37
+ * hasValue(Status, null); // false
38
+ */ export function hasValue(enumObj, value) {
39
+ if (!isBrandedEnum(enumObj)) {
40
+ return false;
41
+ }
42
+ if (typeof value !== 'string') {
43
+ return false;
44
+ }
45
+ return enumObj[ENUM_VALUES].has(value);
46
+ }
47
+ /**
48
+ * Gets the key name for a value in a branded enum.
49
+ *
50
+ * Performs a reverse lookup to find which key maps to a given value.
51
+ * If multiple keys have the same value, returns the first one found
52
+ * (order is not guaranteed).
53
+ *
54
+ * @template E - The branded enum type
55
+ * @param enumObj - The branded enum to search in
56
+ * @param value - The string value to look up
57
+ * @returns The key name that maps to the value, or `undefined` if the
58
+ * value is not found or enumObj is not a branded enum.
59
+ *
60
+ * @example
61
+ * // Find key for value
62
+ * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' } as const);
63
+ * getKeyForValue(Status, 'active'); // 'Active'
64
+ * getKeyForValue(Status, 'inactive'); // 'Inactive'
65
+ *
66
+ * @example
67
+ * // Returns undefined for unknown values
68
+ * getKeyForValue(Status, 'unknown'); // undefined
69
+ *
70
+ * @example
71
+ * // Roundtrip: value -> key -> value
72
+ * const key = getKeyForValue(Status, 'active'); // 'Active'
73
+ * Status[key]; // 'active'
74
+ */ export function getKeyForValue(enumObj, value) {
75
+ if (!isBrandedEnum(enumObj)) {
76
+ return undefined;
77
+ }
78
+ for (const key of Object.keys(enumObj)){
79
+ if (enumObj[key] === value) {
80
+ return key;
81
+ }
82
+ }
83
+ return undefined;
84
+ }
85
+ /**
86
+ * Checks if a key exists in a branded enum.
87
+ *
88
+ * Validates whether a given key is a valid member of the enum.
89
+ * Returns false for Symbol keys (metadata) and non-string keys.
90
+ *
91
+ * @template E - The branded enum type
92
+ * @param enumObj - The branded enum to check
93
+ * @param key - The key to validate. Can be any type; non-strings return false.
94
+ * @returns `true` if the key exists in the enum (with type narrowing),
95
+ * `false` otherwise. Returns `false` for metadata Symbol keys or if
96
+ * enumObj is not a branded enum.
97
+ *
98
+ * @example
99
+ * // Check if key exists
100
+ * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' } as const);
101
+ * isValidKey(Status, 'Active'); // true
102
+ * isValidKey(Status, 'Inactive'); // true
103
+ * isValidKey(Status, 'Unknown'); // false
104
+ *
105
+ * @example
106
+ * // Returns false for non-string keys
107
+ * isValidKey(Status, 123); // false
108
+ * isValidKey(Status, Symbol('test')); // false
109
+ */ export function isValidKey(enumObj, key) {
110
+ if (!isBrandedEnum(enumObj)) {
111
+ return false;
112
+ }
113
+ if (typeof key !== 'string') {
114
+ return false;
115
+ }
116
+ return Object.prototype.hasOwnProperty.call(enumObj, key);
117
+ }
118
+ /**
119
+ * Returns an iterator of [key, value] pairs for a branded enum.
120
+ *
121
+ * Provides a way to iterate over all key-value pairs in the enum using
122
+ * a for...of loop. Only yields user-defined entries, not metadata.
123
+ * Equivalent to `Object.entries(enumObj)` but with proper typing.
124
+ *
125
+ * @template E - The branded enum type
126
+ * @param enumObj - The branded enum to iterate over
127
+ * @returns An iterator yielding [key, value] tuples. Returns an empty
128
+ * iterator if enumObj is not a branded enum.
129
+ *
130
+ * @example
131
+ * // Iterate over entries
132
+ * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' } as const);
133
+ *
134
+ * for (const [key, value] of enumEntries(Status)) {
135
+ * console.log(`${key}: ${value}`);
136
+ * }
137
+ * // Output:
138
+ * // Active: active
139
+ * // Inactive: inactive
140
+ *
141
+ * @example
142
+ * // Convert to array
143
+ * const entries = [...enumEntries(Status)];
144
+ * // [['Active', 'active'], ['Inactive', 'inactive']]
145
+ *
146
+ * @example
147
+ * // Use with Array.from
148
+ * const entriesArray = Array.from(enumEntries(Status));
149
+ */ export function* enumEntries(enumObj) {
150
+ if (!isBrandedEnum(enumObj)) {
151
+ return;
152
+ }
153
+ for (const [key, value] of Object.entries(enumObj)){
154
+ yield [
155
+ key,
156
+ value
157
+ ];
158
+ }
159
+ }
160
+
161
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/utils.ts"],"sourcesContent":["/**\n * Utility functions for branded enums.\n *\n * Provides additional functionality beyond standard enum operations,\n * including reverse lookup, key validation, and iteration.\n */\n\nimport {\n AnyBrandedEnum,\n BrandedEnum,\n BrandedEnumValue,\n ENUM_ID,\n ENUM_VALUES,\n EnumKeys,\n EnumValues,\n} from './types.js';\n\n/**\n * Checks if an object is a branded enum (has Symbol metadata).\n *\n * @param obj - The object to check\n * @returns true if obj is a branded enum\n */\nfunction isBrandedEnum(obj: unknown): obj is AnyBrandedEnum {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n ENUM_ID in obj &&\n ENUM_VALUES in obj &&\n typeof (obj as AnyBrandedEnum)[ENUM_ID] === 'string' &&\n (obj as AnyBrandedEnum)[ENUM_VALUES] instanceof Set\n );\n}\n\n/**\n * Checks if a value exists in a branded enum (reverse lookup).\n *\n * Similar to `isFromEnum`, but with arguments in a different order that\n * may be more natural for some use cases. Also provides type narrowing.\n *\n * @template E - The branded enum type\n * @param enumObj - The branded enum to search in\n * @param value - The value to check. Can be any type; non-strings return false.\n * @returns `true` if the value exists in the enum (with type narrowing),\n * `false` otherwise. Returns `false` for non-string values or if\n * enumObj is not a branded enum.\n *\n * @example\n * // Check if value exists\n * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' } as const);\n * hasValue(Status, 'active'); // true\n * hasValue(Status, 'unknown'); // false\n *\n * @example\n * // Returns false for non-string values\n * hasValue(Status, 123); // false\n * hasValue(Status, null); // false\n */\nexport function hasValue<E extends AnyBrandedEnum>(\n enumObj: E,\n value: unknown\n): value is EnumValues<E> {\n if (!isBrandedEnum(enumObj)) {\n return false;\n }\n if (typeof value !== 'string') {\n return false;\n }\n return enumObj[ENUM_VALUES].has(value);\n}\n\n/**\n * Gets the key name for a value in a branded enum.\n *\n * Performs a reverse lookup to find which key maps to a given value.\n * If multiple keys have the same value, returns the first one found\n * (order is not guaranteed).\n *\n * @template E - The branded enum type\n * @param enumObj - The branded enum to search in\n * @param value - The string value to look up\n * @returns The key name that maps to the value, or `undefined` if the\n * value is not found or enumObj is not a branded enum.\n *\n * @example\n * // Find key for value\n * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' } as const);\n * getKeyForValue(Status, 'active'); // 'Active'\n * getKeyForValue(Status, 'inactive'); // 'Inactive'\n *\n * @example\n * // Returns undefined for unknown values\n * getKeyForValue(Status, 'unknown'); // undefined\n *\n * @example\n * // Roundtrip: value -> key -> value\n * const key = getKeyForValue(Status, 'active'); // 'Active'\n * Status[key]; // 'active'\n */\nexport function getKeyForValue<E extends AnyBrandedEnum>(\n enumObj: E,\n value: string\n): EnumKeys<E> | undefined {\n if (!isBrandedEnum(enumObj)) {\n return undefined;\n }\n for (const key of Object.keys(enumObj)) {\n if ((enumObj as Record<string, unknown>)[key] === value) {\n return key as EnumKeys<E>;\n }\n }\n return undefined;\n}\n\n/**\n * Checks if a key exists in a branded enum.\n *\n * Validates whether a given key is a valid member of the enum.\n * Returns false for Symbol keys (metadata) and non-string keys.\n *\n * @template E - The branded enum type\n * @param enumObj - The branded enum to check\n * @param key - The key to validate. Can be any type; non-strings return false.\n * @returns `true` if the key exists in the enum (with type narrowing),\n * `false` otherwise. Returns `false` for metadata Symbol keys or if\n * enumObj is not a branded enum.\n *\n * @example\n * // Check if key exists\n * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' } as const);\n * isValidKey(Status, 'Active'); // true\n * isValidKey(Status, 'Inactive'); // true\n * isValidKey(Status, 'Unknown'); // false\n *\n * @example\n * // Returns false for non-string keys\n * isValidKey(Status, 123); // false\n * isValidKey(Status, Symbol('test')); // false\n */\nexport function isValidKey<E extends AnyBrandedEnum>(\n enumObj: E,\n key: unknown\n): key is EnumKeys<E> {\n if (!isBrandedEnum(enumObj)) {\n return false;\n }\n if (typeof key !== 'string') {\n return false;\n }\n return Object.prototype.hasOwnProperty.call(enumObj, key);\n}\n\n/**\n * Returns an iterator of [key, value] pairs for a branded enum.\n *\n * Provides a way to iterate over all key-value pairs in the enum using\n * a for...of loop. Only yields user-defined entries, not metadata.\n * Equivalent to `Object.entries(enumObj)` but with proper typing.\n *\n * @template E - The branded enum type\n * @param enumObj - The branded enum to iterate over\n * @returns An iterator yielding [key, value] tuples. Returns an empty\n * iterator if enumObj is not a branded enum.\n *\n * @example\n * // Iterate over entries\n * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' } as const);\n *\n * for (const [key, value] of enumEntries(Status)) {\n * console.log(`${key}: ${value}`);\n * }\n * // Output:\n * // Active: active\n * // Inactive: inactive\n *\n * @example\n * // Convert to array\n * const entries = [...enumEntries(Status)];\n * // [['Active', 'active'], ['Inactive', 'inactive']]\n *\n * @example\n * // Use with Array.from\n * const entriesArray = Array.from(enumEntries(Status));\n */\nexport function* enumEntries<E extends AnyBrandedEnum>(\n enumObj: E\n): IterableIterator<[EnumKeys<E>, EnumValues<E>]> {\n if (!isBrandedEnum(enumObj)) {\n return;\n }\n for (const [key, value] of Object.entries(enumObj)) {\n yield [key as EnumKeys<E>, value as EnumValues<E>];\n }\n}\n"],"names":["ENUM_ID","ENUM_VALUES","isBrandedEnum","obj","Set","hasValue","enumObj","value","has","getKeyForValue","undefined","key","Object","keys","isValidKey","prototype","hasOwnProperty","call","enumEntries","entries"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;;;CAKC,GAED,SAIEA,OAAO,EACPC,WAAW,QAGN,aAAa;AAEpB;;;;;CAKC,GACD,SAASC,cAAcC,GAAY;IACjC,OACEA,QAAQ,QACR,OAAOA,QAAQ,YACfH,WAAWG,OACXF,eAAeE,OACf,OAAO,AAACA,GAAsB,CAACH,QAAQ,KAAK,YAC5C,AAACG,GAAsB,CAACF,YAAY,YAAYG;AAEpD;AAEA;;;;;;;;;;;;;;;;;;;;;;;CAuBC,GACD,OAAO,SAASC,SACdC,OAAU,EACVC,KAAc;IAEd,IAAI,CAACL,cAAcI,UAAU;QAC3B,OAAO;IACT;IACA,IAAI,OAAOC,UAAU,UAAU;QAC7B,OAAO;IACT;IACA,OAAOD,OAAO,CAACL,YAAY,CAACO,GAAG,CAACD;AAClC;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GACD,OAAO,SAASE,eACdH,OAAU,EACVC,KAAa;IAEb,IAAI,CAACL,cAAcI,UAAU;QAC3B,OAAOI;IACT;IACA,KAAK,MAAMC,OAAOC,OAAOC,IAAI,CAACP,SAAU;QACtC,IAAI,AAACA,OAAmC,CAACK,IAAI,KAAKJ,OAAO;YACvD,OAAOI;QACT;IACF;IACA,OAAOD;AACT;AAEA;;;;;;;;;;;;;;;;;;;;;;;;CAwBC,GACD,OAAO,SAASI,WACdR,OAAU,EACVK,GAAY;IAEZ,IAAI,CAACT,cAAcI,UAAU;QAC3B,OAAO;IACT;IACA,IAAI,OAAOK,QAAQ,UAAU;QAC3B,OAAO;IACT;IACA,OAAOC,OAAOG,SAAS,CAACC,cAAc,CAACC,IAAI,CAACX,SAASK;AACvD;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BC,GACD,OAAO,UAAUO,YACfZ,OAAU;IAEV,IAAI,CAACJ,cAAcI,UAAU;QAC3B;IACF;IACA,KAAK,MAAM,CAACK,KAAKJ,MAAM,IAAIK,OAAOO,OAAO,CAACb,SAAU;QAClD,MAAM;YAACK;YAAoBJ;SAAuB;IACpD;AACF"}
@@ -0,0 +1,120 @@
1
+ {
2
+ "name": "@digitaldefiance/branded-enum",
3
+ "version": "0.0.1",
4
+ "description": "Runtime-identifiable enum-like types for TypeScript with zero runtime overhead",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ "./package.json": "./package.json",
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "!**/*.tsbuildinfo"
21
+ ],
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/Digital-Defiance/branded-enum.git"
25
+ },
26
+ "keywords": [
27
+ "typescript",
28
+ "enum",
29
+ "branded",
30
+ "type-safe",
31
+ "runtime"
32
+ ],
33
+ "author": "Digital Defiance, Jessica Mulein",
34
+ "bugs": {
35
+ "url": "https://github.com/Digital-Defiance/branded-enum/issues"
36
+ },
37
+ "homepage": "https://github.com/Digital-Defiance/branded-enum#readme",
38
+ "scripts": {
39
+ "build": "nx build branded-enum",
40
+ "build:examples": "nx build-examples branded-enum",
41
+ "test": "nx test branded-enum",
42
+ "lint": "nx lint branded-enum",
43
+ "publish:public": "yarn build && npm publish --access public"
44
+ },
45
+ "devDependencies": {
46
+ "@nx/jest": "22.4.2",
47
+ "@nx/js": "22.4.2",
48
+ "@swc-node/register": "~1.9.1",
49
+ "@swc/cli": "~0.6.0",
50
+ "@swc/core": "~1.5.7",
51
+ "@swc/helpers": "~0.5.11",
52
+ "@swc/jest": "~0.2.38",
53
+ "@types/jest": "^30.0.0",
54
+ "@types/node": "20.19.9",
55
+ "fast-check": "^4.5.3",
56
+ "jest": "^30.0.2",
57
+ "jest-environment-node": "^30.0.2",
58
+ "jest-util": "^30.0.2",
59
+ "nx": "22.4.2",
60
+ "prettier": "~3.6.2",
61
+ "ts-jest": "^29.4.0",
62
+ "ts-node": "10.9.1",
63
+ "tslib": "^2.3.0",
64
+ "typescript": "~5.9.2"
65
+ },
66
+ "packageManager": "yarn@4.12.0",
67
+ "nx": {
68
+ "name": "branded-enum",
69
+ "sourceRoot": "src",
70
+ "targets": {
71
+ "build": {
72
+ "executor": "@nx/js:swc",
73
+ "outputs": [
74
+ "{options.outputPath}"
75
+ ],
76
+ "options": {
77
+ "outputPath": "dist",
78
+ "main": "src/index.ts",
79
+ "tsConfig": "tsconfig.lib.json",
80
+ "skipTypeCheck": true,
81
+ "stripLeadingPaths": true
82
+ }
83
+ },
84
+ "test": {
85
+ "executor": "@nx/jest:jest",
86
+ "outputs": [
87
+ "{projectRoot}/test-output/jest/coverage"
88
+ ],
89
+ "options": {
90
+ "jestConfig": "jest.config.cts",
91
+ "passWithNoTests": true
92
+ }
93
+ },
94
+ "build-examples": {
95
+ "executor": "nx:run-commands",
96
+ "outputs": [
97
+ "{projectRoot}/examples/dist"
98
+ ],
99
+ "options": {
100
+ "command": "tsc -p examples/tsconfig.json"
101
+ },
102
+ "dependsOn": [
103
+ "build"
104
+ ]
105
+ },
106
+ "publish-public": {
107
+ "executor": "nx:run-commands",
108
+ "options": {
109
+ "command": "npm publish --access public"
110
+ },
111
+ "dependsOn": [
112
+ "build"
113
+ ]
114
+ }
115
+ }
116
+ },
117
+ "engines": {
118
+ "node": ">=18"
119
+ }
120
+ }
package/package.json ADDED
@@ -0,0 +1,110 @@
1
+ {
2
+ "name": "@digitaldefiance/branded-enum",
3
+ "version": "0.0.1",
4
+ "description": "Runtime-identifiable enum-like types for TypeScript with zero runtime overhead",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ "./package.json": "./package.json",
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "!**/*.tsbuildinfo"
21
+ ],
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/Digital-Defiance/branded-enum.git"
25
+ },
26
+ "keywords": [
27
+ "typescript",
28
+ "enum",
29
+ "branded",
30
+ "type-safe",
31
+ "runtime"
32
+ ],
33
+ "author": "Digital Defiance, Jessica Mulein",
34
+ "bugs": {
35
+ "url": "https://github.com/Digital-Defiance/branded-enum/issues"
36
+ },
37
+ "homepage": "https://github.com/Digital-Defiance/branded-enum#readme",
38
+ "scripts": {
39
+ "build": "nx build branded-enum",
40
+ "build:examples": "nx build-examples branded-enum",
41
+ "test": "nx test branded-enum",
42
+ "lint": "nx lint branded-enum",
43
+ "publish:public": "yarn build && npm publish --access public"
44
+ },
45
+ "devDependencies": {
46
+ "@nx/jest": "22.4.2",
47
+ "@nx/js": "22.4.2",
48
+ "@swc-node/register": "~1.9.1",
49
+ "@swc/cli": "~0.6.0",
50
+ "@swc/core": "~1.5.7",
51
+ "@swc/helpers": "~0.5.11",
52
+ "@swc/jest": "~0.2.38",
53
+ "@types/jest": "^30.0.0",
54
+ "@types/node": "20.19.9",
55
+ "fast-check": "^4.5.3",
56
+ "jest": "^30.0.2",
57
+ "jest-environment-node": "^30.0.2",
58
+ "jest-util": "^30.0.2",
59
+ "nx": "22.4.2",
60
+ "prettier": "~3.6.2",
61
+ "ts-jest": "^29.4.0",
62
+ "ts-node": "10.9.1",
63
+ "tslib": "^2.3.0",
64
+ "typescript": "~5.9.2"
65
+ },
66
+ "packageManager": "yarn@4.12.0",
67
+ "nx": {
68
+ "name": "branded-enum",
69
+ "sourceRoot": "src",
70
+ "targets": {
71
+ "build": {
72
+ "executor": "@nx/js:swc",
73
+ "outputs": ["{options.outputPath}"],
74
+ "options": {
75
+ "outputPath": "dist",
76
+ "main": "src/index.ts",
77
+ "tsConfig": "tsconfig.lib.json",
78
+ "skipTypeCheck": true,
79
+ "stripLeadingPaths": true
80
+ }
81
+ },
82
+ "test": {
83
+ "executor": "@nx/jest:jest",
84
+ "outputs": ["{projectRoot}/test-output/jest/coverage"],
85
+ "options": {
86
+ "jestConfig": "jest.config.cts",
87
+ "passWithNoTests": true
88
+ }
89
+ },
90
+ "build-examples": {
91
+ "executor": "nx:run-commands",
92
+ "outputs": ["{projectRoot}/examples/dist"],
93
+ "options": {
94
+ "command": "tsc -p examples/tsconfig.json"
95
+ },
96
+ "dependsOn": ["build"]
97
+ },
98
+ "publish-public": {
99
+ "executor": "nx:run-commands",
100
+ "options": {
101
+ "command": "npm publish --access public"
102
+ },
103
+ "dependsOn": ["build"]
104
+ }
105
+ }
106
+ },
107
+ "engines": {
108
+ "node": ">=18"
109
+ }
110
+ }