@reharik/smart-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,179 @@
1
+ import {
2
+ isSerializedSmartEnumItem,
3
+ isSmartEnumItem
4
+ } from "./chunk-NASPJET6.js";
5
+
6
+ // src/utilities/logger.ts
7
+ var consoleLogger = {
8
+ debug(message, ...args) {
9
+ console.debug(`[ts-smart-enum:debug] ${message}`, ...args);
10
+ },
11
+ info(message, ...args) {
12
+ console.info(`[ts-smart-enum:info] ${message}`, ...args);
13
+ },
14
+ warn(message, ...args) {
15
+ console.warn(`[ts-smart-enum:warn] ${message}`, ...args);
16
+ },
17
+ error(message, ...args) {
18
+ console.error(`[ts-smart-enum:error] ${message}`, ...args);
19
+ }
20
+ };
21
+ var globalLogger = consoleLogger;
22
+ function setLogger(logger) {
23
+ globalLogger = logger;
24
+ }
25
+ function getLogger() {
26
+ return globalLogger;
27
+ }
28
+ function debug(message, ...args) {
29
+ globalLogger.debug(message, ...args);
30
+ }
31
+ function info(message, ...args) {
32
+ globalLogger.info(message, ...args);
33
+ }
34
+
35
+ // src/utilities/transformation.ts
36
+ var isPlainObject = (x) => typeof x === "object" && x !== null && Object.getPrototypeOf(x) === Object.prototype;
37
+ function serializeSmartEnums(input) {
38
+ const seen = /* @__PURE__ */ new WeakMap();
39
+ const walk = (v) => {
40
+ if (isSmartEnumItem(v)) {
41
+ return {
42
+ __smart_enum_type: v.__smart_enum_type,
43
+ value: v.value
44
+ };
45
+ }
46
+ if (typeof v === "object" && v !== null && seen.has(v)) {
47
+ return seen.get(v);
48
+ }
49
+ if (Array.isArray(v)) {
50
+ const arr = [];
51
+ seen.set(v, arr);
52
+ for (const item of v) {
53
+ arr.push(walk(item));
54
+ }
55
+ return arr;
56
+ }
57
+ if (isPlainObject(v)) {
58
+ const out = {};
59
+ seen.set(v, out);
60
+ for (const [k, val] of Object.entries(v)) {
61
+ out[k] = walk(val);
62
+ }
63
+ return out;
64
+ }
65
+ return v;
66
+ };
67
+ return walk(input);
68
+ }
69
+ function reviveSmartEnums(input, registry) {
70
+ const seen = /* @__PURE__ */ new WeakMap();
71
+ const walk = (v) => {
72
+ if (isSerializedSmartEnumItem(v)) {
73
+ debug(`Found serialized smartEnum: ${v.__smart_enum_type}`);
74
+ const enumInstance = registry[v.__smart_enum_type];
75
+ if (enumInstance) {
76
+ debug(`Found enumInstance in registry: ${v.__smart_enum_type}`);
77
+ const enumItem = enumInstance.tryFromValue(v.value);
78
+ if (enumItem) {
79
+ debug(`Revived enumItem using value: ${v.value}`);
80
+ return enumItem;
81
+ }
82
+ const key = v.value.toLowerCase();
83
+ const enumItemFromKey = enumInstance.tryFromKey(key);
84
+ if (enumItemFromKey) {
85
+ debug(`Revived enumItem using key: ${key}`);
86
+ return enumItemFromKey;
87
+ }
88
+ }
89
+ return v;
90
+ }
91
+ if (typeof v === "object" && v !== null && seen.has(v)) {
92
+ return seen.get(v);
93
+ }
94
+ if (Array.isArray(v)) {
95
+ const arr = [];
96
+ seen.set(v, arr);
97
+ for (const item of v) arr.push(walk(item));
98
+ return arr;
99
+ }
100
+ if (isPlainObject(v)) {
101
+ const out = {};
102
+ seen.set(v, out);
103
+ for (const [k, val] of Object.entries(v)) {
104
+ out[k] = walk(val);
105
+ }
106
+ return out;
107
+ }
108
+ return v;
109
+ };
110
+ return walk(input);
111
+ }
112
+
113
+ // src/utilities/transport/transportRegistry.ts
114
+ var createLevelFilteredLogger = (logger, level) => {
115
+ const levels = {
116
+ debug: 0,
117
+ info: 1,
118
+ warn: 2,
119
+ error: 3
120
+ };
121
+ const currentLevel = levels[level];
122
+ return {
123
+ debug: (message, ...args) => {
124
+ if (currentLevel <= levels.debug) {
125
+ logger.debug(message, ...args);
126
+ }
127
+ },
128
+ info: (message, ...args) => {
129
+ if (currentLevel <= levels.info) {
130
+ logger.info(message, ...args);
131
+ }
132
+ },
133
+ warn: (message, ...args) => {
134
+ if (currentLevel <= levels.warn) {
135
+ logger.warn(message, ...args);
136
+ }
137
+ },
138
+ error: (message, ...args) => {
139
+ if (currentLevel <= levels.error) {
140
+ logger.error(message, ...args);
141
+ }
142
+ }
143
+ };
144
+ };
145
+ var globalEnumRegistry;
146
+ var initializeSmartEnumMappings = (config) => {
147
+ globalEnumRegistry = config.enumRegistry;
148
+ const logLevel = config.logLevel ?? "error";
149
+ const logger = config.logger ?? getLogger();
150
+ setLogger(createLevelFilteredLogger(logger, logLevel));
151
+ info("Initialized smart enum mappings", {
152
+ enumCount: Object.keys(config.enumRegistry).length,
153
+ enumTypes: Object.keys(config.enumRegistry),
154
+ logLevel
155
+ });
156
+ };
157
+ var getGlobalEnumRegistry = () => globalEnumRegistry;
158
+
159
+ // src/utilities/transport/reviveAfterTransport.ts
160
+ var reviveAfterTransport = (payload) => {
161
+ const registry = getGlobalEnumRegistry();
162
+ if (!registry) {
163
+ return payload;
164
+ }
165
+ return reviveSmartEnums(payload, registry);
166
+ };
167
+
168
+ // src/utilities/transport/serializeForTransport.ts
169
+ var serializeForTransport = (payload) => serializeSmartEnums(payload);
170
+
171
+ export {
172
+ serializeSmartEnums,
173
+ reviveSmartEnums,
174
+ initializeSmartEnumMappings,
175
+ getGlobalEnumRegistry,
176
+ reviveAfterTransport,
177
+ serializeForTransport
178
+ };
179
+ //# sourceMappingURL=chunk-7HX2FHYM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utilities/logger.ts","../src/utilities/transformation.ts","../src/utilities/transport/transportRegistry.ts","../src/utilities/transport/reviveAfterTransport.ts","../src/utilities/transport/serializeForTransport.ts"],"sourcesContent":["/**\n * Logger interface for ts-smart-enum library\n *\n * This interface allows users to inject their own logging implementation\n * or use the default console logger.\n */\n\nexport type Logger = {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n};\n\n/**\n * Default console logger implementation\n */\nconst consoleLogger: Logger = {\n debug(message: string, ...args: unknown[]): void {\n console.debug(`[ts-smart-enum:debug] ${message}`, ...args);\n },\n\n info(message: string, ...args: unknown[]): void {\n console.info(`[ts-smart-enum:info] ${message}`, ...args);\n },\n\n warn(message: string, ...args: unknown[]): void {\n console.warn(`[ts-smart-enum:warn] ${message}`, ...args);\n },\n\n error(message: string, ...args: unknown[]): void {\n console.error(`[ts-smart-enum:error] ${message}`, ...args);\n },\n};\n\n/**\n * Global logger instance\n * Defaults to console logger\n */\nlet globalLogger: Logger = consoleLogger;\n\n/**\n * Sets the global logger instance\n *\n * @param logger - The logger implementation to use\n *\n * @example\n * ```typescript\n * import { setLogger } from 'ts-smart-enum';\n *\n * // Use custom logger\n * setLogger({\n * debug: (msg, ...args) => myLogger.debug(msg, args),\n * info: (msg, ...args) => myLogger.info(msg, args),\n * warn: (msg, ...args) => myLogger.warn(msg, args),\n * error: (msg, ...args) => myLogger.error(msg, args),\n * });\n * ```\n */\nexport function setLogger(logger: Logger): void {\n globalLogger = logger;\n}\n\n/**\n * Gets the current logger instance\n *\n * @returns The current logger instance\n */\nexport function getLogger(): Logger {\n return globalLogger;\n}\n\n// Internal convenience functions for library use\nexport function debug(message: string, ...args: unknown[]): void {\n globalLogger.debug(message, ...args);\n}\n\nexport function info(message: string, ...args: unknown[]): void {\n globalLogger.info(message, ...args);\n}\n\nexport function warn(message: string, ...args: unknown[]): void {\n globalLogger.warn(message, ...args);\n}\n\nexport function error(message: string, ...args: unknown[]): void {\n globalLogger.error(message, ...args);\n}\n","// serializeSmartEnums.ts\nexport { isSmartEnumItem, isSmartEnum } from './typeGuards.js';\nimport type { SerializedSmartEnums, AnyEnumLike } from '../types.js';\n\nimport { debug } from './logger.js';\nimport { isSerializedSmartEnumItem, isSmartEnumItem } from './typeGuards.js';\n\ntype PlainObject = Record<string, unknown>;\n\nconst isPlainObject = (x: unknown): x is PlainObject =>\n typeof x === 'object' &&\n x !== null &&\n Object.getPrototypeOf(x) === Object.prototype;\n\n/**\n * Recursively replaces Smart Enum items with self-describing objects\n * `{ __smart_enum_type, value }` for JSON transport or storage.\n *\n * @param input - Object or array that may contain enum items\n * @returns Same structure with enum items replaced by serialized shape\n *\n * @example\n * ```typescript\n * const dto = { id: '1', status: Status.active, color: Color.red };\n * const wire = serializeSmartEnums(dto);\n * // wire: { id: '1', status: { __smart_enum_type: 'Status', value: 'ACTIVE' }, color: { __smart_enum_type: 'Color', value: 'RED' } }\n * ```\n */\n// Overloads:\n// 1) Inferred\nexport function serializeSmartEnums<T>(input: T): SerializedSmartEnums<T>;\n// 2) Return-type only (constrained to objects/arrays)\nexport function serializeSmartEnums<\n S extends Readonly<PlainObject> | readonly unknown[],\n>(input: unknown): S;\n// Implementation\nexport function serializeSmartEnums(input: unknown): unknown {\n const seen = new WeakMap<object, unknown>();\n\n const walk = (v: unknown): unknown => {\n if (isSmartEnumItem(v)) {\n return {\n __smart_enum_type: v.__smart_enum_type,\n value: v.value,\n };\n }\n if (typeof v === 'object' && v !== null && seen.has(v)) {\n return seen.get(v);\n }\n\n if (Array.isArray(v)) {\n const arr: unknown[] = [];\n seen.set(v, arr);\n for (const item of v) {\n arr.push(walk(item));\n }\n return arr;\n }\n if (isPlainObject(v)) {\n const out: PlainObject = {};\n seen.set(v, out);\n for (const [k, val] of Object.entries(v)) {\n out[k] = walk(val);\n }\n return out;\n }\n return v;\n };\n\n return walk(input);\n}\n\n/**\n * Recursively revives serialized enum objects back to Smart Enum items\n * using a registry of enum types. Expects payload to contain\n * `{ __smart_enum_type, value }` where the type exists in the registry.\n *\n * @param input - Serialized payload (e.g. from JSON)\n * @param registry - Map of enum type name to enum object (e.g. `{ Status, Color }`)\n * @returns Payload with serialized enums revived to enum items\n *\n * @example\n * ```typescript\n * const wire = { status: { __smart_enum_type: 'Status', value: 'ACTIVE' } };\n * const revived = reviveSmartEnums(wire, { Status, Color });\n * // revived.status === Status.active\n * ```\n */\nexport function reviveSmartEnums<R>(\n input: unknown,\n registry: Record<string, AnyEnumLike>,\n): R {\n const seen = new WeakMap<object, unknown>();\n\n const walk = (v: unknown): unknown => {\n // Handle self-describing enum objects with __smart_enum_type and value\n if (isSerializedSmartEnumItem(v)) {\n debug(`Found serialized smartEnum: ${v.__smart_enum_type}`);\n const enumInstance = registry[v.__smart_enum_type];\n if (enumInstance) {\n debug(`Found enumInstance in registry: ${v.__smart_enum_type}`);\n // Try to find the enum item by value first\n const enumItem = enumInstance.tryFromValue(v.value);\n if (enumItem) {\n debug(`Revived enumItem using value: ${v.value}`);\n return enumItem;\n }\n // If that fails, try to find by key (convert value to key format)\n const key = v.value.toLowerCase();\n const enumItemFromKey = enumInstance.tryFromKey(key);\n if (enumItemFromKey) {\n debug(`Revived enumItem using key: ${key}`);\n return enumItemFromKey;\n }\n }\n // If no matching enum type in registry, return the original serialized object\n return v;\n }\n\n if (typeof v === 'object' && v !== null && seen.has(v)) {\n return seen.get(v);\n }\n\n if (Array.isArray(v)) {\n const arr: unknown[] = [];\n seen.set(v, arr);\n for (const item of v) arr.push(walk(item));\n return arr;\n }\n if (isPlainObject(v)) {\n const out: PlainObject = {};\n seen.set(v, out);\n for (const [k, val] of Object.entries(v)) {\n out[k] = walk(val);\n }\n return out;\n }\n return v;\n };\n return walk(input) as R;\n}\n","import type {\n AnyEnumLike,\n LogLevel,\n SmartEnumMappingsConfig,\n} from '../../types.js';\nimport { info, setLogger, getLogger, type Logger } from '../logger.js';\n\nconst createLevelFilteredLogger = (logger: Logger, level: LogLevel): Logger => {\n const levels: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n };\n\n const currentLevel = levels[level];\n\n return {\n debug: (message: string, ...args: unknown[]) => {\n if (currentLevel <= levels.debug) {\n logger.debug(message, ...args);\n }\n },\n info: (message: string, ...args: unknown[]) => {\n if (currentLevel <= levels.info) {\n logger.info(message, ...args);\n }\n },\n warn: (message: string, ...args: unknown[]) => {\n if (currentLevel <= levels.warn) {\n logger.warn(message, ...args);\n }\n },\n error: (message: string, ...args: unknown[]) => {\n if (currentLevel <= levels.error) {\n logger.error(message, ...args);\n }\n },\n };\n};\n\nlet globalEnumRegistry: Record<string, AnyEnumLike> | undefined;\n\n/**\n * Wire-format registry for `reviveAfterTransport` / `reviveSmartEnums`.\n * Not used for database string revival.\n */\nexport const initializeSmartEnumMappings = (\n config: SmartEnumMappingsConfig,\n): void => {\n globalEnumRegistry = config.enumRegistry;\n\n const logLevel = config.logLevel ?? 'error';\n const logger = config.logger ?? getLogger();\n setLogger(createLevelFilteredLogger(logger, logLevel));\n\n info('Initialized smart enum mappings', {\n enumCount: Object.keys(config.enumRegistry).length,\n enumTypes: Object.keys(config.enumRegistry),\n logLevel,\n });\n};\n\nexport const getGlobalEnumRegistry = ():\n | Record<string, AnyEnumLike>\n | undefined => globalEnumRegistry;\n","import { reviveSmartEnums } from '../transformation.js';\n\nimport { getGlobalEnumRegistry } from './transportRegistry.js';\n\n/**\n * Revives smart enums after transport. Requires `initializeSmartEnumMappings`.\n */\nexport const reviveAfterTransport = <T>(payload: unknown): T => {\n const registry = getGlobalEnumRegistry();\n if (!registry) {\n return payload as T;\n }\n return reviveSmartEnums(payload, registry);\n};\n","import { serializeSmartEnums } from '../transformation.js';\nimport type { SerializedSmartEnums } from '../../types.js';\n\n/**\n * Serializes smart enums for transport (to client or API).\n * Wire payloads include `__smart_enum_type` for `reviveAfterTransport`.\n */\nexport const serializeForTransport = <T>(payload: T): SerializedSmartEnums<T> =>\n serializeSmartEnums(payload);\n"],"mappings":"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","names":[]}
@@ -0,0 +1,145 @@
1
+ // src/enumerations.ts
2
+ import { capitalCase, constantCase } from "case-anything";
3
+
4
+ // src/extensionMethods.ts
5
+ var addExtensionMethods = (enumItems) => {
6
+ const findBy = (field, target) => enumItems.find((item) => item[field] === target);
7
+ const requireBy = (field, target, label) => {
8
+ const item = findBy(field, target);
9
+ if (!item) {
10
+ throw new Error(`No enum ${label} found for '${String(target)}'`);
11
+ }
12
+ return item;
13
+ };
14
+ return {
15
+ fromValue: (value) => requireBy("value", value, "value"),
16
+ tryFromValue: (value) => value ? findBy("value", value) : void 0,
17
+ fromKey: (key) => requireBy("key", key, "key"),
18
+ tryFromKey: (key) => key ? findBy("key", key) : void 0,
19
+ items: () => [...enumItems],
20
+ values: () => enumItems.map((item) => item.value),
21
+ keys: () => enumItems.map((item) => item.key)
22
+ };
23
+ };
24
+
25
+ // src/types.ts
26
+ var SMART_ENUM_ITEM = Symbol("smart-enum-item");
27
+ var SMART_ENUM_ID = Symbol("smart-enum-id");
28
+ var SMART_ENUM = Symbol("smart-enum");
29
+
30
+ // src/enumerations.ts
31
+ function normalizeInput(input) {
32
+ if (Array.isArray(input)) {
33
+ return Object.fromEntries(
34
+ input.map((k) => [k, {}])
35
+ );
36
+ }
37
+ return input;
38
+ }
39
+ var finalizeEnumItem = (item, enumType, enumInstanceId) => {
40
+ Object.defineProperty(item, SMART_ENUM_ITEM, {
41
+ value: true,
42
+ enumerable: false
43
+ });
44
+ Object.defineProperty(item, SMART_ENUM_ID, {
45
+ value: enumInstanceId,
46
+ enumerable: false
47
+ });
48
+ Object.defineProperty(item, "__smart_enum_brand", {
49
+ value: true,
50
+ enumerable: false
51
+ });
52
+ Object.defineProperty(item, "__smart_enum_type", {
53
+ value: enumType,
54
+ enumerable: false
55
+ });
56
+ Object.defineProperty(item, "toJSON", {
57
+ value: () => ({ __smart_enum_type: enumType, value: item.value }),
58
+ enumerable: false
59
+ });
60
+ Object.defineProperty(item, "toPostgres", {
61
+ value: () => item.value,
62
+ enumerable: false
63
+ });
64
+ return item;
65
+ };
66
+ var formatProperties = (k, formatters) => formatters.reduce(
67
+ (acc, formatter) => {
68
+ acc[formatter.key] = formatter.format(k);
69
+ return acc;
70
+ },
71
+ {
72
+ value: constantCase(k),
73
+ display: capitalCase(k)
74
+ }
75
+ );
76
+ function buildEnumFromObject(enumType, input, propertyAutoFormatters) {
77
+ const formattersWithDefaults = [
78
+ { key: "value", format: constantCase },
79
+ { key: "display", format: capitalCase },
80
+ ...propertyAutoFormatters ?? []
81
+ ];
82
+ const rawEnumItems = {};
83
+ const enumInstanceId = Symbol("smart-enum-instance");
84
+ let index = 0;
85
+ for (const key in input) {
86
+ if (Object.prototype.hasOwnProperty.call(input, key)) {
87
+ const typedKey = key;
88
+ const value = input[typedKey];
89
+ const enumItemBase = {
90
+ index,
91
+ key: typedKey,
92
+ ...formatProperties(typedKey, formattersWithDefaults),
93
+ ...value
94
+ };
95
+ const enumItem = finalizeEnumItem(
96
+ enumItemBase,
97
+ enumType,
98
+ enumInstanceId
99
+ );
100
+ Object.freeze(enumItem);
101
+ rawEnumItems[typedKey] = enumItem;
102
+ index++;
103
+ }
104
+ }
105
+ const extensionMethods = addExtensionMethods(
106
+ Object.values(rawEnumItems)
107
+ );
108
+ const enumObject = {
109
+ ...rawEnumItems,
110
+ ...extensionMethods
111
+ };
112
+ Object.defineProperty(enumObject, SMART_ENUM, {
113
+ value: true,
114
+ enumerable: false
115
+ });
116
+ Object.freeze(enumObject);
117
+ return enumObject;
118
+ }
119
+ function enumeration(enumType, props) {
120
+ const normalized = normalizeInput(props.input);
121
+ return buildEnumFromObject(
122
+ enumType,
123
+ normalized,
124
+ props.propertyAutoFormatters
125
+ );
126
+ }
127
+
128
+ // src/utilities/typeGuards.ts
129
+ var isSmartEnumItem = (x) => {
130
+ return !!x && typeof x === "object" && Reflect.get(x, SMART_ENUM_ITEM) === true;
131
+ };
132
+ var isSmartEnum = (x) => {
133
+ return !!x && typeof x === "object" && Reflect.get(x, SMART_ENUM) === true;
134
+ };
135
+ var isSerializedSmartEnumItem = (x) => {
136
+ return !!x && typeof x === "object" && Reflect.has(x, "__smart_enum_type") && Reflect.has(x, "value");
137
+ };
138
+
139
+ export {
140
+ enumeration,
141
+ isSmartEnumItem,
142
+ isSmartEnum,
143
+ isSerializedSmartEnumItem
144
+ };
145
+ //# sourceMappingURL=chunk-NASPJET6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/enumerations.ts","../src/extensionMethods.ts","../src/types.ts","../src/utilities/typeGuards.ts"],"sourcesContent":["import { capitalCase, constantCase } from 'case-anything';\n\nimport { addExtensionMethods } from './extensionMethods.js';\nimport { SMART_ENUM, SMART_ENUM_ID, SMART_ENUM_ITEM } from './types.js';\n\ntype BuiltInOverrideKeys =\n | 'key'\n | 'value'\n | 'display'\n | 'deprecated'\n | 'index'\n | '__smart_enum_brand'\n | '__smart_enum_type';\n\nexport type StandardEnumItem = {\n readonly __smart_enum_brand: true;\n readonly __smart_enum_type: string;\n readonly key: string;\n readonly value: string;\n readonly display: string;\n readonly index: number;\n readonly deprecated?: boolean;\n readonly toPostgres: () => string;\n};\n\nexport type EnumInputItem = Partial<{\n key: string;\n value: string;\n display: string;\n deprecated: boolean;\n}> &\n object;\n\nexport type ObjectEnumInput = Record<string, EnumInputItem>;\n\ntype EmptyEnumInputItem = Record<never, never>;\n\ntype Separator = '-' | '_' | ' ' | '.';\n\ntype IsUpperChar<C extends string> =\n C extends Uppercase<C> ? (C extends Lowercase<C> ? false : true) : false;\n\ntype IsLowerChar<C extends string> =\n C extends Lowercase<C> ? (C extends Uppercase<C> ? false : true) : false;\n\ntype PushUnderscore<S extends string> = S extends '' | `${string}_`\n ? S\n : `${S}_`;\n\ntype TrimUnderscore<S extends string> = S extends `_${infer R}`\n ? TrimUnderscore<R>\n : S extends `${infer R}_`\n ? TrimUnderscore<R>\n : S;\n\ntype CollapseUnderscores<S extends string> = S extends `${infer A}__${infer B}`\n ? CollapseUnderscores<`${A}_${B}`>\n : S;\n\ntype ConstantCaseInternal<\n S extends string,\n Prev extends string = '',\n Out extends string = '',\n> = S extends `${infer C}${infer Rest}`\n ? C extends Separator\n ? ConstantCaseInternal<Rest, C, PushUnderscore<Out>>\n : IsUpperChar<C> extends true\n ? IsLowerChar<Prev> extends true\n ? ConstantCaseInternal<Rest, C, `${PushUnderscore<Out>}${Uppercase<C>}`>\n : ConstantCaseInternal<Rest, C, `${Out}${Uppercase<C>}`>\n : ConstantCaseInternal<Rest, C, `${Out}${Uppercase<C>}`>\n : CollapseUnderscores<TrimUnderscore<Out>>;\n\ntype ConstantCase<S extends string> = string extends S\n ? string\n : ConstantCaseInternal<S>;\n\ntype ArrayToObjectType<T extends readonly string[]> = {\n [K in T[number]]: EmptyEnumInputItem & { readonly value?: ConstantCase<K> };\n};\n\ntype NormalizedInputType<TInput> = TInput extends readonly string[]\n ? ArrayToObjectType<TInput>\n : TInput extends ObjectEnumInput\n ? TInput\n : never;\n\ntype UnionKeys<T> = T extends T ? keyof T : never;\n\ntype MergeUnionToObject<T> = {\n [K in UnionKeys<T>]: T extends Record<K, infer V> ? V : undefined;\n};\n\ntype ExtraShapeUnion<TObj extends ObjectEnumInput> = {\n [K in keyof TObj]: Omit<TObj[K], BuiltInOverrideKeys>;\n}[keyof TObj];\n\nexport type InferredExtraFields<TObj extends ObjectEnumInput> =\n MergeUnionToObject<ExtraShapeUnion<TObj>>;\n\nexport type EnumItemFromNormalizedObject<\n TObj extends ObjectEnumInput,\n K extends keyof TObj = keyof TObj,\n> = Omit<StandardEnumItem, 'key' | 'value'> &\n InferredExtraFields<TObj> & {\n readonly key: Extract<K, string>;\n readonly value: TObj[K] extends { value?: infer V }\n ? Extract<V, string> extends never\n ? string\n : Extract<V, string>\n : string;\n };\n\nexport type EnumMemberUnionFromNormalizedObject<TObj extends ObjectEnumInput> =\n {\n [K in keyof TObj]: EnumItemFromNormalizedObject<TObj, K>;\n }[keyof TObj];\n\nexport type CoreEnumMethods<TItem extends StandardEnumItem> = {\n fromValue(value: string): TItem;\n tryFromValue(value?: string | null): TItem | undefined;\n fromKey(key: string): TItem;\n tryFromKey(key?: string | null): TItem | undefined;\n items(): readonly TItem[];\n values(): readonly string[];\n keys(): readonly string[];\n};\n\nexport type EnumFromNormalizedObject<TObj extends ObjectEnumInput> = {\n [K in keyof TObj]: EnumItemFromNormalizedObject<TObj, K>;\n} & CoreEnumMethods<EnumMemberUnionFromNormalizedObject<TObj>>;\n\nexport type EnumerationProps<TInput> = {\n input: TInput;\n propertyAutoFormatters?: PropertyAutoFormatter[];\n};\n\nexport type EnumItem<TEnum> = {\n [K in keyof TEnum]: TEnum[K] extends { __smart_enum_brand: true }\n ? TEnum[K]\n : never;\n}[keyof TEnum];\n\nexport type PropertyAutoFormatter = {\n key: string;\n format: (k: string) => string;\n};\n\ntype FinalizedEnumFields = Pick<\n StandardEnumItem,\n '__smart_enum_brand' | '__smart_enum_type'\n>;\n\ntype FinalizableEnumItem = {\n key: string;\n value: string;\n display: string;\n index: number;\n deprecated?: boolean;\n};\n\nfunction normalizeInput<TInput extends readonly string[] | ObjectEnumInput>(\n input: TInput,\n): NormalizedInputType<TInput> {\n if (Array.isArray(input)) {\n return Object.fromEntries(\n input.map(k => [k, {}]),\n ) as NormalizedInputType<TInput>;\n }\n\n return input as NormalizedInputType<TInput>;\n}\n\nconst finalizeEnumItem = <T extends { value: string }>(\n item: T,\n enumType: string,\n enumInstanceId: symbol,\n): T & FinalizedEnumFields => {\n Object.defineProperty(item, SMART_ENUM_ITEM, {\n value: true,\n enumerable: false,\n });\n\n Object.defineProperty(item, SMART_ENUM_ID, {\n value: enumInstanceId,\n enumerable: false,\n });\n\n Object.defineProperty(item, '__smart_enum_brand', {\n value: true,\n enumerable: false,\n });\n\n Object.defineProperty(item, '__smart_enum_type', {\n value: enumType,\n enumerable: false,\n });\n\n Object.defineProperty(item, 'toJSON', {\n value: () => ({ __smart_enum_type: enumType, value: item.value }),\n enumerable: false,\n });\n\n Object.defineProperty(item, 'toPostgres', {\n value: () => item.value,\n enumerable: false,\n });\n\n return item as T & FinalizedEnumFields;\n};\n\nconst formatProperties = (\n k: string,\n formatters: PropertyAutoFormatter[],\n): { value: string; display: string } & Record<string, string> =>\n formatters.reduce(\n (acc, formatter) => {\n acc[formatter.key] = formatter.format(k);\n return acc;\n },\n {\n value: constantCase(k),\n display: capitalCase(k),\n } as { value: string; display: string } & Record<string, string>,\n );\n\nfunction buildEnumFromObject<TObj extends ObjectEnumInput>(\n enumType: string,\n input: TObj,\n propertyAutoFormatters?: PropertyAutoFormatter[],\n): EnumFromNormalizedObject<TObj> {\n const formattersWithDefaults: PropertyAutoFormatter[] = [\n { key: 'value', format: constantCase },\n { key: 'display', format: capitalCase },\n ...(propertyAutoFormatters ?? []),\n ];\n\n type TItem = EnumItemFromNormalizedObject<TObj>;\n\n const rawEnumItems = {} as {\n [K in keyof TObj]: EnumItemFromNormalizedObject<TObj, K>;\n };\n\n const enumInstanceId = Symbol('smart-enum-instance');\n let index = 0;\n\n for (const key in input) {\n if (Object.prototype.hasOwnProperty.call(input, key)) {\n const typedKey = key;\n const value = input[typedKey];\n\n const enumItemBase = {\n index,\n key: typedKey,\n ...formatProperties(typedKey, formattersWithDefaults),\n ...value,\n } as FinalizableEnumItem & TObj[typeof typedKey];\n\n const enumItem = finalizeEnumItem(\n enumItemBase,\n enumType,\n enumInstanceId,\n ) as unknown as TItem;\n\n Object.freeze(enumItem);\n rawEnumItems[typedKey] = enumItem;\n index++;\n }\n }\n\n const extensionMethods = addExtensionMethods<TItem>(\n Object.values(rawEnumItems) as TItem[],\n );\n\n const enumObject = {\n ...rawEnumItems,\n ...extensionMethods,\n } as EnumFromNormalizedObject<TObj>;\n\n Object.defineProperty(enumObject, SMART_ENUM, {\n value: true,\n enumerable: false,\n });\n\n Object.freeze(enumObject);\n\n return enumObject;\n}\n\nexport function enumeration<const TArr extends readonly string[]>(\n enumType: string,\n props: EnumerationProps<TArr>,\n): EnumFromNormalizedObject<NormalizedInputType<TArr>>;\n\nexport function enumeration<const TObj extends ObjectEnumInput>(\n enumType: string,\n props: EnumerationProps<TObj>,\n): EnumFromNormalizedObject<NormalizedInputType<TObj>>;\n\nexport function enumeration(\n enumType: string,\n props: EnumerationProps<readonly string[] | ObjectEnumInput>,\n) {\n const normalized = normalizeInput(props.input);\n return buildEnumFromObject(\n enumType,\n normalized,\n props.propertyAutoFormatters,\n );\n}\n","import type { CoreEnumMethods, StandardEnumItem } from './types.js';\nexport const addExtensionMethods = <TItem extends StandardEnumItem>(\n enumItems: readonly TItem[],\n): CoreEnumMethods<TItem> => {\n const findBy = <K extends keyof TItem>(field: K, target: TItem[K]) =>\n enumItems.find(item => item[field] === target);\n\n const requireBy = <K extends keyof TItem>(\n field: K,\n target: TItem[K],\n label: string,\n ) => {\n const item = findBy(field, target);\n if (!item) {\n throw new Error(`No enum ${label} found for '${String(target)}'`);\n }\n return item;\n };\n\n return {\n fromValue: value => requireBy('value', value as TItem['value'], 'value'),\n tryFromValue: value =>\n value ? findBy('value', value as TItem['value']) : undefined,\n\n fromKey: key => requireBy('key', key as TItem['key'], 'key'),\n tryFromKey: key => (key ? findBy('key', key as TItem['key']) : undefined),\n\n items: () => [...enumItems],\n values: () => enumItems.map(item => item.value),\n keys: () => enumItems.map(item => item.key),\n };\n};\n","/**\n * Type guard to check if a value is not null or undefined\n * @param value - The value to check\n * @returns True if the value is defined and not null\n */\nexport const notEmpty = <X>(\n value: X | null | undefined,\n): value is NonNullable<X> => {\n // eslint-disable-next-line unicorn/no-null\n return value != null;\n};\n\n// Public symbols used at runtime for detection/identity (not used in type keys)\nexport const SMART_ENUM_ITEM = Symbol('smart-enum-item');\nexport const SMART_ENUM_ID = Symbol('smart-enum-id');\nexport const SMART_ENUM = Symbol('smart-enum');\n\n/**\n * Options for filtering enum items in various methods\n */\nexport type EnumFilterOptions = {\n /** Include items with null/undefined values (default: false) */\n showEmpty?: boolean;\n /** Include deprecated items (default: false) */\n showDeprecated?: boolean;\n};\n\n// export type EnumInput = readonly string[] | ObjectEnumInput;\n\n/**\n * Compile-time transformer: replaces Smart Enum items with string values,\n * recursively over arrays and objects. Structural detection checks for\n * presence of `key` and `value`.\n */\nexport type SerializedSmartEnums<T> = T extends { value: string; key: unknown }\n ? string\n : T extends ReadonlyArray<infer U>\n ? ReadonlyArray<SerializedSmartEnums<U>>\n : T extends Array<infer U>\n ? SerializedSmartEnums<U>[]\n : T extends object\n ? { [K in keyof T]: SerializedSmartEnums<T[K]> }\n : T;\n\n/**\n * Revived shape: for keys present in mapping M, the string becomes the\n * corresponding enum item type (derived from the provided enum object);\n * other fields recurse.\n */\nexport type EnumItemFromEnum<TEnum> =\n TEnum extends Record<string, infer V>\n ? V extends { __smart_enum_brand: true }\n ? V\n : never\n : never;\n\n// Structural constraint for enum objects passed to reviveSmartEnums mapping\nexport type AnyEnumLike = {\n tryFromValue: (value?: string | null) => unknown;\n tryFromKey: (key?: string | null) => unknown;\n} & Record<string, unknown>;\n\nexport type SmartEnumLike<T = unknown> = {\n tryFromValue: (value: string) => T | undefined;\n};\n\nexport type FieldEnumMapping = Record<string, SmartEnumLike>;\n\nexport type ReviveRowOptions = {\n fieldEnumMapping: FieldEnumMapping;\n strict?: boolean;\n};\n\nexport type PathEnumMapping = Record<string, SmartEnumLike>;\n\nexport type RevivePayloadOptions = {\n pathEnumMapping: PathEnumMapping;\n strict?: boolean;\n};\n\nexport type RevivedSmartEnums<T, M extends Record<string, AnyEnumLike>> =\n T extends ReadonlyArray<infer U>\n ? RevivedSmartEnums<U, M>[]\n : T extends Array<infer U>\n ? RevivedSmartEnums<U, M>[]\n : T extends object\n ? {\n [K in keyof T]: K extends Extract<keyof M, string>\n ? Enumeration<M[K]>\n : RevivedSmartEnums<T[K], M>;\n }\n : T;\n\nexport type SmartEnumItemSerialized = {\n __smart_enum_type: string;\n value: string;\n};\n\n/** Example shape for transport tests (`reviveAfterTransport` registry). */\nexport type SmartApiHelperConfig = {\n enumRegistry: Record<string, AnyEnumLike>;\n};\n\n/**\n * Compile-time transformer: replaces Smart Enum items with string values,\n * recursively over arrays and objects. Used for database storage.\n */\nexport type DatabaseFormat<T> = T extends { value: string; key: unknown }\n ? string\n : T extends ReadonlyArray<infer U>\n ? ReadonlyArray<DatabaseFormat<U>>\n : T extends Array<infer U>\n ? DatabaseFormat<U>[]\n : T extends object\n ? { [K in keyof T]: DatabaseFormat<T[K]> }\n : T;\n\n/**\n * Log levels for smart enum mappings\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * Configuration for smart enum mappings initialization\n */\nexport type SmartEnumMappingsConfig = {\n enumRegistry: Record<string, AnyEnumLike>;\n logLevel?: LogLevel;\n logger?: import('./utilities/logger.js').Logger;\n};\n\ntype BuiltInOverrideKeys =\n | 'key'\n | 'value'\n | 'display'\n | 'deprecated'\n | 'index'\n | '__smart_enum_brand'\n | '__smart_enum_type';\n\nexport type StandardEnumItem = {\n readonly __smart_enum_brand: true;\n readonly __smart_enum_type: string;\n readonly key: string;\n readonly value: string;\n readonly display: string;\n readonly index: number;\n readonly deprecated?: boolean;\n readonly toPostgres: () => string;\n};\nexport type EnumInputItem = Partial<{\n key: string;\n value: string;\n display: string;\n deprecated: boolean;\n}> &\n Record<string, unknown>;\n\nexport type ObjectEnumInput = Record<string, EnumInputItem>;\n\nexport type EmptyEnumInputItem = Record<never, never>;\n\nexport type ArrayToObjectType<T extends readonly string[]> = {\n [K in T[number]]: EmptyEnumInputItem;\n};\n\nexport type NormalizedInputType<TInput> = TInput extends readonly string[]\n ? ArrayToObjectType<TInput>\n : TInput extends ObjectEnumInput\n ? TInput\n : never;\n\nexport type EnumItemFromNormalizedObject<\n TObj extends ObjectEnumInput,\n K extends keyof TObj = keyof TObj,\n> = Omit<StandardEnumItem, 'key'> &\n InferredExtraFields<TObj> & {\n readonly key: Extract<K, string>;\n };\n\nexport type EnumMemberUnionFromNormalizedObject<TObj extends ObjectEnumInput> =\n {\n [K in keyof TObj]: EnumItemFromNormalizedObject<TObj, K>;\n }[keyof TObj];\n\nexport type EnumFromNormalizedObject<TObj extends ObjectEnumInput> = {\n [K in keyof TObj]: EnumItemFromNormalizedObject<TObj, K>;\n} & CoreEnumMethods<EnumMemberUnionFromNormalizedObject<TObj>>;\n\nexport type UnionKeys<T> = T extends T ? keyof T : never;\n\n/*\nTo widen the type of the OptionalObject from literals to their actual types,\ne.g.\nshape?: \"round\" | \"square\" | \"long\";\nslices?: true;\nlayers?: 2;\n--turns into:--\nshape: string | undefined;\nslices: boolean| undefined;\nlayers: number| undefined;\n\nwe can use the following code:\ntype Widen<T> = T extends string\n ? string\n : T extends number\n ? number\n : T extends boolean\n ? boolean\n : T;\n\ntype MergeUnionToObject<T> = {\n [K in UnionKeys<T>]: T extends Record<K, infer V> ? Widen<V> : undefined;\n};\n*/\n\ntype MergeUnionToObject<T> = {\n [K in UnionKeys<T>]: T extends Record<K, infer V> ? V : undefined;\n};\n\ntype ExtraShapeUnion<TObj extends ObjectEnumInput> = {\n [K in keyof TObj]: Omit<TObj[K], BuiltInOverrideKeys>;\n}[keyof TObj];\n\nexport type InferredExtraFields<TObj extends ObjectEnumInput> =\n MergeUnionToObject<ExtraShapeUnion<TObj>>;\n\nexport type PropertyAutoFormatter = {\n /** The property name to generate */\n key: string;\n /** Function to transform the key into the property value */\n format: (k: string) => string;\n};\n\nexport type CoreEnumMethods<TItem extends StandardEnumItem> = {\n fromValue(value: string): TItem;\n tryFromValue(value?: string | null): TItem | undefined;\n fromKey(key: string): TItem;\n tryFromKey(key?: string | null): TItem | undefined;\n items(): readonly TItem[];\n values(): readonly string[];\n keys(): readonly string[];\n};\n\nexport type EnumerationProps<TInput> = {\n input: TInput;\n propertyAutoFormatters?: PropertyAutoFormatter[];\n};\n\nexport type Enumeration<TEnum> =\n TEnum extends Record<string, infer V>\n ? V extends { __smart_enum_brand: true }\n ? V\n : never\n : never;\n\nexport type FinalizedEnumFields = Pick<\n StandardEnumItem,\n '__smart_enum_brand' | '__smart_enum_type'\n>;\nexport type FinalizableEnumItem = {\n key: string;\n value: string;\n display: string;\n index: number;\n deprecated?: boolean;\n};\n","import {\n SMART_ENUM_ITEM,\n SMART_ENUM,\n SmartEnumItemSerialized,\n} from '../types.js';\n\n/**\n * Runtime type guard to detect Smart Enum items created by this library.\n * Returns true if the value has the SMART_ENUM_ITEM symbol.\n *\n * @example\n * ```typescript\n * import { Status } from './status';\n * const item = Status.active;\n * isSmartEnumItem(item); // true\n * isSmartEnumItem({ key: 'active', value: 'ACTIVE' }); // false (plain object)\n * if (isSmartEnumItem(x)) {\n * console.log(x.value, x.__smart_enum_type); // narrowed to enum item\n * }\n * ```\n */\nexport const isSmartEnumItem = (\n x: unknown,\n): x is {\n key: string;\n value: string;\n index?: number;\n __smart_enum_type?: string;\n} => {\n return (\n !!x && typeof x === 'object' && Reflect.get(x, SMART_ENUM_ITEM) === true\n );\n};\n\n/**\n * Runtime type guard to detect a full Smart Enum object created by this library.\n * Returns true if the object has the SMART_ENUM property.\n *\n * @example\n * ```typescript\n * import { MyEnum } from './blah';\n * isSmartEnum(MyEnum) === true; // true\n * isSmartEnum(MyEnum.one) === false; // false (this is an item, not the enum)\n * ```\n */\nexport const isSmartEnum = (x: unknown): boolean => {\n return !!x && typeof x === 'object' && Reflect.get(x, SMART_ENUM) === true;\n};\n\n/**\n * Runtime type guard to detect a serialized Smart Enum item created by this library.\n * Returns true if the value has `__smart_enum_type` and `value` (wire/database shape).\n *\n * @example\n * ```typescript\n * const wire = { __smart_enum_type: 'Status', value: 'ACTIVE' };\n * isSerializedSmartEnumItem(wire); // true\n * isSerializedSmartEnumItem(Status.active); // false (live enum item)\n * if (isSerializedSmartEnumItem(x)) {\n * reviveItem(x.__smart_enum_type, x.value); // narrowed to SmartEnumItemSerialized\n * }\n * ```\n */\nexport const isSerializedSmartEnumItem = (\n x: unknown,\n): x is SmartEnumItemSerialized => {\n return (\n !!x &&\n typeof x === 'object' &&\n Reflect.has(x, '__smart_enum_type') &&\n Reflect.has(x, 'value')\n );\n};\n"],"mappings":";AAAA,SAAS,aAAa,oBAAoB;;;ACCnC,IAAM,sBAAsB,CACjC,cAC2B;AAC3B,QAAM,SAAS,CAAwB,OAAU,WAC/C,UAAU,KAAK,UAAQ,KAAK,KAAK,MAAM,MAAM;AAE/C,QAAM,YAAY,CAChB,OACA,QACA,UACG;AACH,UAAM,OAAO,OAAO,OAAO,MAAM;AACjC,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,WAAW,KAAK,eAAe,OAAO,MAAM,CAAC,GAAG;AAAA,IAClE;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,WAAW,WAAS,UAAU,SAAS,OAAyB,OAAO;AAAA,IACvE,cAAc,WACZ,QAAQ,OAAO,SAAS,KAAuB,IAAI;AAAA,IAErD,SAAS,SAAO,UAAU,OAAO,KAAqB,KAAK;AAAA,IAC3D,YAAY,SAAQ,MAAM,OAAO,OAAO,GAAmB,IAAI;AAAA,IAE/D,OAAO,MAAM,CAAC,GAAG,SAAS;AAAA,IAC1B,QAAQ,MAAM,UAAU,IAAI,UAAQ,KAAK,KAAK;AAAA,IAC9C,MAAM,MAAM,UAAU,IAAI,UAAQ,KAAK,GAAG;AAAA,EAC5C;AACF;;;AClBO,IAAM,kBAAkB,OAAO,iBAAiB;AAChD,IAAM,gBAAgB,OAAO,eAAe;AAC5C,IAAM,aAAa,OAAO,YAAY;;;AFkJ7C,SAAS,eACP,OAC6B;AAC7B,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,OAAO;AAAA,MACZ,MAAM,IAAI,OAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,mBAAmB,CACvB,MACA,UACA,mBAC4B;AAC5B,SAAO,eAAe,MAAM,iBAAiB;AAAA,IAC3C,OAAO;AAAA,IACP,YAAY;AAAA,EACd,CAAC;AAED,SAAO,eAAe,MAAM,eAAe;AAAA,IACzC,OAAO;AAAA,IACP,YAAY;AAAA,EACd,CAAC;AAED,SAAO,eAAe,MAAM,sBAAsB;AAAA,IAChD,OAAO;AAAA,IACP,YAAY;AAAA,EACd,CAAC;AAED,SAAO,eAAe,MAAM,qBAAqB;AAAA,IAC/C,OAAO;AAAA,IACP,YAAY;AAAA,EACd,CAAC;AAED,SAAO,eAAe,MAAM,UAAU;AAAA,IACpC,OAAO,OAAO,EAAE,mBAAmB,UAAU,OAAO,KAAK,MAAM;AAAA,IAC/D,YAAY;AAAA,EACd,CAAC;AAED,SAAO,eAAe,MAAM,cAAc;AAAA,IACxC,OAAO,MAAM,KAAK;AAAA,IAClB,YAAY;AAAA,EACd,CAAC;AAED,SAAO;AACT;AAEA,IAAM,mBAAmB,CACvB,GACA,eAEA,WAAW;AAAA,EACT,CAAC,KAAK,cAAc;AAClB,QAAI,UAAU,GAAG,IAAI,UAAU,OAAO,CAAC;AACvC,WAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO,aAAa,CAAC;AAAA,IACrB,SAAS,YAAY,CAAC;AAAA,EACxB;AACF;AAEF,SAAS,oBACP,UACA,OACA,wBACgC;AAChC,QAAM,yBAAkD;AAAA,IACtD,EAAE,KAAK,SAAS,QAAQ,aAAa;AAAA,IACrC,EAAE,KAAK,WAAW,QAAQ,YAAY;AAAA,IACtC,GAAI,0BAA0B,CAAC;AAAA,EACjC;AAIA,QAAM,eAAe,CAAC;AAItB,QAAM,iBAAiB,OAAO,qBAAqB;AACnD,MAAI,QAAQ;AAEZ,aAAW,OAAO,OAAO;AACvB,QAAI,OAAO,UAAU,eAAe,KAAK,OAAO,GAAG,GAAG;AACpD,YAAM,WAAW;AACjB,YAAM,QAAQ,MAAM,QAAQ;AAE5B,YAAM,eAAe;AAAA,QACnB;AAAA,QACA,KAAK;AAAA,QACL,GAAG,iBAAiB,UAAU,sBAAsB;AAAA,QACpD,GAAG;AAAA,MACL;AAEA,YAAM,WAAW;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,aAAO,OAAO,QAAQ;AACtB,mBAAa,QAAQ,IAAI;AACzB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAAmB;AAAA,IACvB,OAAO,OAAO,YAAY;AAAA,EAC5B;AAEA,QAAM,aAAa;AAAA,IACjB,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAEA,SAAO,eAAe,YAAY,YAAY;AAAA,IAC5C,OAAO;AAAA,IACP,YAAY;AAAA,EACd,CAAC;AAED,SAAO,OAAO,UAAU;AAExB,SAAO;AACT;AAYO,SAAS,YACd,UACA,OACA;AACA,QAAM,aAAa,eAAe,MAAM,KAAK;AAC7C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR;AACF;;;AGhSO,IAAM,kBAAkB,CAC7B,MAMG;AACH,SACE,CAAC,CAAC,KAAK,OAAO,MAAM,YAAY,QAAQ,IAAI,GAAG,eAAe,MAAM;AAExE;AAaO,IAAM,cAAc,CAAC,MAAwB;AAClD,SAAO,CAAC,CAAC,KAAK,OAAO,MAAM,YAAY,QAAQ,IAAI,GAAG,UAAU,MAAM;AACxE;AAgBO,IAAM,4BAA4B,CACvC,MACiC;AACjC,SACE,CAAC,CAAC,KACF,OAAO,MAAM,YACb,QAAQ,IAAI,GAAG,mBAAmB,KAClC,QAAQ,IAAI,GAAG,OAAO;AAE1B;","names":[]}
@@ -0,0 +1,184 @@
1
+ import {
2
+ isSmartEnumItem
3
+ } from "./chunk-NASPJET6.js";
4
+
5
+ // src/db/prepareForDatabase.ts
6
+ var isPlainObject = (x) => typeof x === "object" && x !== null && Object.getPrototypeOf(x) === Object.prototype;
7
+ var prepareForDatabase = (payload) => {
8
+ const seen = /* @__PURE__ */ new WeakMap();
9
+ const walk = (v) => {
10
+ if (isSmartEnumItem(v)) {
11
+ return v.value;
12
+ }
13
+ if (typeof v === "object" && v !== null && seen.has(v)) {
14
+ return seen.get(v);
15
+ }
16
+ if (Array.isArray(v)) {
17
+ const arr = [];
18
+ seen.set(v, arr);
19
+ for (const item of v) {
20
+ arr.push(walk(item));
21
+ }
22
+ return arr;
23
+ }
24
+ if (isPlainObject(v)) {
25
+ const out = {};
26
+ seen.set(v, out);
27
+ for (const [k, val] of Object.entries(v)) {
28
+ out[k] = walk(val);
29
+ }
30
+ return out;
31
+ }
32
+ return v;
33
+ };
34
+ return walk(payload);
35
+ };
36
+
37
+ // src/db/enumRevivalError.ts
38
+ var EnumRevivalError = class extends Error {
39
+ constructor(message, path, value) {
40
+ super(message);
41
+ this.path = path;
42
+ this.value = value;
43
+ this.name = "EnumRevivalError";
44
+ }
45
+ };
46
+
47
+ // src/db/reviveRowFromDatabase.ts
48
+ var reviveRowFromDatabase = (row, options) => {
49
+ const { fieldEnumMapping, strict = false } = options;
50
+ const out = { ...row };
51
+ for (const [field, smartEnum] of Object.entries(fieldEnumMapping)) {
52
+ if (!Object.hasOwn(out, field)) {
53
+ continue;
54
+ }
55
+ const raw = out[field];
56
+ if (typeof raw !== "string") {
57
+ continue;
58
+ }
59
+ const revived = smartEnum.tryFromValue(raw);
60
+ if (revived !== void 0) {
61
+ out[field] = revived;
62
+ } else if (strict) {
63
+ throw new EnumRevivalError(
64
+ `Cannot revive field ${JSON.stringify(field)}: unknown enum value ${JSON.stringify(raw)}`,
65
+ field,
66
+ raw
67
+ );
68
+ }
69
+ }
70
+ return out;
71
+ };
72
+
73
+ // src/db/revivePayloadFromDatabase.ts
74
+ var isObjectRecord = (x) => typeof x === "object" && x !== null && !Array.isArray(x);
75
+ var parsePath = (pathStr) => {
76
+ const tokens = pathStr.split(".").filter(Boolean);
77
+ const segs = [];
78
+ for (const token of tokens) {
79
+ if (token.endsWith("[]")) {
80
+ const name = token.slice(0, -2);
81
+ if (name.length === 0) {
82
+ throw new Error(
83
+ `Invalid enum revival path "${pathStr}": empty key before []`
84
+ );
85
+ }
86
+ segs.push({ type: "prop", name }, { type: "arrayEach" });
87
+ } else {
88
+ segs.push({ type: "prop", name: token });
89
+ }
90
+ }
91
+ const last = segs.at(-1);
92
+ if (!last || last.type !== "prop") {
93
+ throw new Error(
94
+ `Invalid enum revival path "${pathStr}": must end with a property name (not [])`
95
+ );
96
+ }
97
+ return segs;
98
+ };
99
+ var reviveLeaf = (host, key, smartEnum, strict, pathLabel) => {
100
+ const raw = host[key];
101
+ if (typeof raw !== "string") {
102
+ return;
103
+ }
104
+ const revived = smartEnum.tryFromValue(raw);
105
+ if (revived !== void 0) {
106
+ host[key] = revived;
107
+ } else if (strict) {
108
+ throw new EnumRevivalError(
109
+ `Cannot revive path "${pathLabel}": unknown enum value ${JSON.stringify(raw)}`,
110
+ pathLabel,
111
+ raw
112
+ );
113
+ }
114
+ };
115
+ var walkPath = (value, segs, segIndex, smartEnum, strict, pathLabel) => {
116
+ const seg = segs[segIndex];
117
+ if (seg === void 0) {
118
+ return;
119
+ }
120
+ const isLast = segIndex === segs.length - 1;
121
+ if (isLast) {
122
+ if (seg.type !== "prop") {
123
+ return;
124
+ }
125
+ if (!isObjectRecord(value)) {
126
+ if (strict) {
127
+ throw new EnumRevivalError(
128
+ `Cannot revive path "${pathLabel}": expected object at parent of "${seg.name}"`,
129
+ pathLabel,
130
+ value
131
+ );
132
+ }
133
+ return;
134
+ }
135
+ reviveLeaf(value, seg.name, smartEnum, strict, pathLabel);
136
+ return;
137
+ }
138
+ if (seg.type === "prop") {
139
+ if (!isObjectRecord(value)) {
140
+ if (strict) {
141
+ throw new EnumRevivalError(
142
+ `Cannot revive path "${pathLabel}": expected object at "${seg.name}"`,
143
+ pathLabel,
144
+ value
145
+ );
146
+ }
147
+ return;
148
+ }
149
+ walkPath(value[seg.name], segs, segIndex + 1, smartEnum, strict, pathLabel);
150
+ return;
151
+ }
152
+ if (seg.type === "arrayEach") {
153
+ if (!Array.isArray(value)) {
154
+ if (strict) {
155
+ throw new EnumRevivalError(
156
+ `Cannot revive path "${pathLabel}": expected array before nested path`,
157
+ pathLabel,
158
+ value
159
+ );
160
+ }
161
+ return;
162
+ }
163
+ for (const el of value) {
164
+ walkPath(el, segs, segIndex + 1, smartEnum, strict, pathLabel);
165
+ }
166
+ }
167
+ };
168
+ var revivePayloadFromDatabase = (payload, options) => {
169
+ const { pathEnumMapping, strict = false } = options;
170
+ const root = structuredClone(payload);
171
+ for (const [pathStr, smartEnum] of Object.entries(pathEnumMapping)) {
172
+ const segs = parsePath(pathStr);
173
+ walkPath(root, segs, 0, smartEnum, strict, pathStr);
174
+ }
175
+ return root;
176
+ };
177
+
178
+ export {
179
+ prepareForDatabase,
180
+ EnumRevivalError,
181
+ reviveRowFromDatabase,
182
+ revivePayloadFromDatabase
183
+ };
184
+ //# sourceMappingURL=chunk-YGXDKW6W.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/db/prepareForDatabase.ts","../src/db/enumRevivalError.ts","../src/db/reviveRowFromDatabase.ts","../src/db/revivePayloadFromDatabase.ts"],"sourcesContent":["import { isSmartEnumItem } from '../utilities/typeGuards.js';\nimport type { DatabaseFormat } from '../types.js';\n\ntype PlainObject = Record<string, unknown>;\n\nconst isPlainObject = (x: unknown): x is PlainObject =>\n typeof x === 'object' &&\n x !== null &&\n Object.getPrototypeOf(x) === Object.prototype;\n\n/**\n * Recursively replaces smart enum items with their `.value` strings for persistence.\n * Inbound revival requires explicit mapping (`reviveRowFromDatabase`, etc.).\n */\nexport const prepareForDatabase = <T>(payload: T): DatabaseFormat<T> => {\n const seen = new WeakMap<object, unknown>();\n\n const walk = (v: unknown): unknown => {\n if (isSmartEnumItem(v)) {\n return v.value;\n }\n\n if (typeof v === 'object' && v !== null && seen.has(v)) {\n return seen.get(v);\n }\n\n if (Array.isArray(v)) {\n const arr: unknown[] = [];\n seen.set(v, arr);\n for (const item of v) {\n arr.push(walk(item));\n }\n return arr;\n }\n if (isPlainObject(v)) {\n const out: PlainObject = {};\n seen.set(v, out);\n for (const [k, val] of Object.entries(v)) {\n out[k] = walk(val);\n }\n return out;\n }\n return v;\n };\n\n return walk(payload) as DatabaseFormat<T>;\n};\n","export class EnumRevivalError extends Error {\n public constructor(\n message: string,\n public readonly path: string,\n public readonly value: unknown,\n ) {\n super(message);\n this.name = 'EnumRevivalError';\n }\n}\n","import type { ReviveRowOptions } from '../types.js';\n\nimport { EnumRevivalError } from './enumRevivalError.js';\n\nexport const reviveRowFromDatabase = <T extends Record<string, unknown>>(\n row: T,\n options: ReviveRowOptions,\n): T => {\n const { fieldEnumMapping, strict = false } = options;\n const out = { ...row } as Record<string, unknown>;\n\n for (const [field, smartEnum] of Object.entries(fieldEnumMapping)) {\n if (!Object.hasOwn(out, field)) {\n continue;\n }\n const raw = out[field];\n if (typeof raw !== 'string') {\n continue;\n }\n const revived = smartEnum.tryFromValue(raw);\n if (revived !== undefined) {\n out[field] = revived as unknown;\n } else if (strict) {\n throw new EnumRevivalError(\n `Cannot revive field ${JSON.stringify(field)}: unknown enum value ${JSON.stringify(raw)}`,\n field,\n raw,\n );\n }\n }\n\n return out as T;\n};\n","import type { RevivePayloadOptions, SmartEnumLike } from '../types.js';\n\nimport { EnumRevivalError } from './enumRevivalError.js';\n\ntype PlainObject = Record<string, unknown>;\n\n/** Plain data objects (including `structuredClone` output where prototype may not be Object.prototype). */\nconst isObjectRecord = (x: unknown): x is PlainObject =>\n typeof x === 'object' && x !== null && !Array.isArray(x);\n\ntype PathSeg = { type: 'prop'; name: string } | { type: 'arrayEach' };\n\nconst parsePath = (pathStr: string): PathSeg[] => {\n const tokens = pathStr.split('.').filter(Boolean);\n const segs: PathSeg[] = [];\n\n for (const token of tokens) {\n if (token.endsWith('[]')) {\n const name = token.slice(0, -2);\n if (name.length === 0) {\n throw new Error(\n `Invalid enum revival path \"${pathStr}\": empty key before []`,\n );\n }\n segs.push({ type: 'prop', name }, { type: 'arrayEach' });\n } else {\n segs.push({ type: 'prop', name: token });\n }\n }\n\n const last = segs.at(-1);\n if (!last || last.type !== 'prop') {\n throw new Error(\n `Invalid enum revival path \"${pathStr}\": must end with a property name (not [])`,\n );\n }\n\n return segs;\n};\n\nconst reviveLeaf = (\n host: PlainObject,\n key: string,\n smartEnum: SmartEnumLike,\n strict: boolean,\n pathLabel: string,\n): void => {\n const raw = host[key];\n if (typeof raw !== 'string') {\n return;\n }\n const revived = smartEnum.tryFromValue(raw);\n if (revived !== undefined) {\n host[key] = revived as unknown;\n } else if (strict) {\n throw new EnumRevivalError(\n `Cannot revive path \"${pathLabel}\": unknown enum value ${JSON.stringify(raw)}`,\n pathLabel,\n raw,\n );\n }\n};\n\nconst walkPath = (\n value: unknown,\n segs: PathSeg[],\n segIndex: number,\n smartEnum: SmartEnumLike,\n strict: boolean,\n pathLabel: string,\n): void => {\n const seg = segs[segIndex];\n if (seg === undefined) {\n return;\n }\n\n const isLast = segIndex === segs.length - 1;\n\n if (isLast) {\n if (seg.type !== 'prop') {\n return;\n }\n if (!isObjectRecord(value)) {\n if (strict) {\n throw new EnumRevivalError(\n `Cannot revive path \"${pathLabel}\": expected object at parent of \"${seg.name}\"`,\n pathLabel,\n value,\n );\n }\n return;\n }\n reviveLeaf(value, seg.name, smartEnum, strict, pathLabel);\n return;\n }\n\n if (seg.type === 'prop') {\n if (!isObjectRecord(value)) {\n if (strict) {\n throw new EnumRevivalError(\n `Cannot revive path \"${pathLabel}\": expected object at \"${seg.name}\"`,\n pathLabel,\n value,\n );\n }\n return;\n }\n walkPath(value[seg.name], segs, segIndex + 1, smartEnum, strict, pathLabel);\n return;\n }\n\n if (seg.type === 'arrayEach') {\n if (!Array.isArray(value)) {\n if (strict) {\n throw new EnumRevivalError(\n `Cannot revive path \"${pathLabel}\": expected array before nested path`,\n pathLabel,\n value,\n );\n }\n return;\n }\n for (const el of value) {\n walkPath(el, segs, segIndex + 1, smartEnum, strict, pathLabel);\n }\n }\n};\n\nexport const revivePayloadFromDatabase = <T>(\n payload: T,\n options: RevivePayloadOptions,\n): T => {\n const { pathEnumMapping, strict = false } = options;\n const root = structuredClone(payload);\n\n for (const [pathStr, smartEnum] of Object.entries(pathEnumMapping)) {\n const segs = parsePath(pathStr);\n walkPath(root as unknown, segs, 0, smartEnum, strict, pathStr);\n }\n\n return root;\n};\n"],"mappings":"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","names":[]}