@digitaldefiance/branded-enum 0.0.1 → 0.0.3

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.
Files changed (79) hide show
  1. package/dist/cjs/index.cjs +149 -0
  2. package/dist/cjs/index.cjs.map +1 -0
  3. package/dist/cjs/lib/accessors.cjs +55 -0
  4. package/dist/cjs/lib/accessors.cjs.map +1 -0
  5. package/dist/cjs/lib/advanced.cjs +558 -0
  6. package/dist/cjs/lib/advanced.cjs.map +1 -0
  7. package/dist/cjs/lib/branded-enum.cjs +15 -0
  8. package/dist/cjs/lib/branded-enum.cjs.map +1 -0
  9. package/dist/cjs/lib/decorators.cjs +202 -0
  10. package/dist/cjs/lib/decorators.cjs.map +1 -0
  11. package/dist/cjs/lib/factory.cjs +45 -0
  12. package/dist/cjs/lib/factory.cjs.map +1 -0
  13. package/dist/cjs/lib/guards.cjs +119 -0
  14. package/dist/cjs/lib/guards.cjs.map +1 -0
  15. package/dist/cjs/lib/merge.cjs +47 -0
  16. package/dist/cjs/lib/merge.cjs.map +1 -0
  17. package/dist/cjs/lib/registry.cjs +85 -0
  18. package/dist/cjs/lib/registry.cjs.map +1 -0
  19. package/dist/cjs/lib/types.cjs +38 -0
  20. package/dist/cjs/lib/types.cjs.map +1 -0
  21. package/dist/cjs/lib/utils.cjs +80 -0
  22. package/dist/cjs/lib/utils.cjs.map +1 -0
  23. package/dist/esm/index.d.ts +21 -0
  24. package/dist/esm/index.d.ts.map +1 -0
  25. package/dist/esm/index.js.map +1 -0
  26. package/dist/esm/lib/accessors.d.ts +79 -0
  27. package/dist/esm/lib/accessors.d.ts.map +1 -0
  28. package/dist/esm/lib/accessors.js.map +1 -0
  29. package/dist/esm/lib/advanced.d.ts +1422 -0
  30. package/dist/esm/lib/advanced.d.ts.map +1 -0
  31. package/dist/esm/lib/advanced.js.map +1 -0
  32. package/dist/esm/lib/branded-enum.d.ts +2 -0
  33. package/dist/esm/lib/branded-enum.d.ts.map +1 -0
  34. package/dist/esm/lib/branded-enum.js.map +1 -0
  35. package/dist/esm/lib/decorators.d.ts +147 -0
  36. package/dist/esm/lib/decorators.d.ts.map +1 -0
  37. package/dist/esm/lib/decorators.js.map +1 -0
  38. package/dist/esm/lib/factory.d.ts +52 -0
  39. package/dist/esm/lib/factory.d.ts.map +1 -0
  40. package/dist/esm/lib/factory.js.map +1 -0
  41. package/dist/esm/lib/guards.d.ts +297 -0
  42. package/dist/esm/lib/guards.d.ts.map +1 -0
  43. package/dist/esm/lib/guards.js.map +1 -0
  44. package/dist/esm/lib/merge.d.ts +64 -0
  45. package/dist/esm/lib/merge.d.ts.map +1 -0
  46. package/dist/esm/lib/merge.js.map +1 -0
  47. package/dist/esm/lib/registry.d.ts +93 -0
  48. package/dist/esm/lib/registry.d.ts.map +1 -0
  49. package/dist/esm/lib/registry.js.map +1 -0
  50. package/dist/esm/lib/types.d.ts +258 -0
  51. package/dist/esm/lib/types.d.ts.map +1 -0
  52. package/dist/esm/lib/types.js.map +1 -0
  53. package/dist/esm/lib/utils.d.ts +121 -0
  54. package/dist/esm/lib/utils.d.ts.map +1 -0
  55. package/dist/esm/lib/utils.js.map +1 -0
  56. package/package.json +31 -18
  57. package/dist/index.js.map +0 -1
  58. package/dist/lib/accessors.js.map +0 -1
  59. package/dist/lib/advanced.js.map +0 -1
  60. package/dist/lib/branded-enum.js.map +0 -1
  61. package/dist/lib/decorators.js.map +0 -1
  62. package/dist/lib/factory.js.map +0 -1
  63. package/dist/lib/guards.js.map +0 -1
  64. package/dist/lib/merge.js.map +0 -1
  65. package/dist/lib/registry.js.map +0 -1
  66. package/dist/lib/types.js.map +0 -1
  67. package/dist/lib/utils.js.map +0 -1
  68. package/dist/package.json +0 -120
  69. /package/dist/{index.js → esm/index.js} +0 -0
  70. /package/dist/{lib → esm/lib}/accessors.js +0 -0
  71. /package/dist/{lib → esm/lib}/advanced.js +0 -0
  72. /package/dist/{lib → esm/lib}/branded-enum.js +0 -0
  73. /package/dist/{lib → esm/lib}/decorators.js +0 -0
  74. /package/dist/{lib → esm/lib}/factory.js +0 -0
  75. /package/dist/{lib → esm/lib}/guards.js +0 -0
  76. /package/dist/{lib → esm/lib}/merge.js +0 -0
  77. /package/dist/{lib → esm/lib}/registry.js +0 -0
  78. /package/dist/{lib → esm/lib}/types.js +0 -0
  79. /package/dist/{lib → esm/lib}/utils.js +0 -0
@@ -0,0 +1,558 @@
1
+ /**
2
+ * Advanced enum operations for branded enums.
3
+ *
4
+ * Provides functions for deriving new enums from existing ones,
5
+ * including subsetting, exclusion, and transformation operations.
6
+ */ "use strict";
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ function _export(target, all) {
11
+ for(var name in all)Object.defineProperty(target, name, {
12
+ enumerable: true,
13
+ get: all[name]
14
+ });
15
+ }
16
+ _export(exports, {
17
+ clearAllEnumWatchers: function() {
18
+ return clearAllEnumWatchers;
19
+ },
20
+ enumDiff: function() {
21
+ return enumDiff;
22
+ },
23
+ enumExclude: function() {
24
+ return enumExclude;
25
+ },
26
+ enumFromKeys: function() {
27
+ return enumFromKeys;
28
+ },
29
+ enumIntersect: function() {
30
+ return enumIntersect;
31
+ },
32
+ enumMap: function() {
33
+ return enumMap;
34
+ },
35
+ enumSerializer: function() {
36
+ return enumSerializer;
37
+ },
38
+ enumSubset: function() {
39
+ return enumSubset;
40
+ },
41
+ enumToRecord: function() {
42
+ return enumToRecord;
43
+ },
44
+ exhaustive: function() {
45
+ return exhaustive;
46
+ },
47
+ exhaustiveGuard: function() {
48
+ return exhaustiveGuard;
49
+ },
50
+ getEnumWatcherCount: function() {
51
+ return getEnumWatcherCount;
52
+ },
53
+ getGlobalWatcherCount: function() {
54
+ return getGlobalWatcherCount;
55
+ },
56
+ toJsonSchema: function() {
57
+ return toJsonSchema;
58
+ },
59
+ toZodSchema: function() {
60
+ return toZodSchema;
61
+ },
62
+ watchAllEnums: function() {
63
+ return watchAllEnums;
64
+ },
65
+ watchEnum: function() {
66
+ return watchEnum;
67
+ }
68
+ });
69
+ const _types = require("./types.js");
70
+ const _factory = require("./factory.js");
71
+ /**
72
+ * Checks if an object is a branded enum (has Symbol metadata).
73
+ *
74
+ * @param obj - The object to check
75
+ * @returns true if obj is a branded enum
76
+ */ function isBrandedEnum(obj) {
77
+ return obj !== null && typeof obj === 'object' && _types.ENUM_ID in obj && _types.ENUM_VALUES in obj && typeof obj[_types.ENUM_ID] === 'string' && obj[_types.ENUM_VALUES] instanceof Set;
78
+ }
79
+ function enumSubset(newId, sourceEnum, keys) {
80
+ // Validate that sourceEnum is a branded enum
81
+ if (!isBrandedEnum(sourceEnum)) {
82
+ throw new Error('enumSubset requires a branded enum as the source');
83
+ }
84
+ // Validate that keys array is not empty
85
+ if (keys.length === 0) {
86
+ throw new Error('enumSubset requires at least one key');
87
+ }
88
+ const sourceEnumId = sourceEnum[_types.ENUM_ID];
89
+ // Build the subset values object
90
+ const subsetValues = {};
91
+ for (const key of keys){
92
+ // Validate that the key exists in the source enum
93
+ if (!(key in sourceEnum)) {
94
+ throw new Error(`Key "${key}" does not exist in enum "${sourceEnumId}"`);
95
+ }
96
+ // Copy the key-value pair
97
+ subsetValues[key] = sourceEnum[key];
98
+ }
99
+ // Create and return the new branded enum (this handles registration)
100
+ return (0, _factory.createBrandedEnum)(newId, subsetValues);
101
+ }
102
+ function enumExclude(newId, sourceEnum, keysToExclude) {
103
+ // Validate that sourceEnum is a branded enum
104
+ if (!isBrandedEnum(sourceEnum)) {
105
+ throw new Error('enumExclude requires a branded enum as the source');
106
+ }
107
+ const sourceEnumId = sourceEnum[_types.ENUM_ID];
108
+ // Validate that all keys to exclude exist in the source enum
109
+ for (const key of keysToExclude){
110
+ if (!(key in sourceEnum)) {
111
+ throw new Error(`Key "${key}" does not exist in enum "${sourceEnumId}"`);
112
+ }
113
+ }
114
+ // Create a Set for O(1) lookup of excluded keys
115
+ const excludeSet = new Set(keysToExclude);
116
+ // Get all keys from the source enum (excluding Symbol metadata)
117
+ const allKeys = Object.keys(sourceEnum);
118
+ // Build the result values object with non-excluded keys
119
+ const resultValues = {};
120
+ for (const key of allKeys){
121
+ if (!excludeSet.has(key)) {
122
+ resultValues[key] = sourceEnum[key];
123
+ }
124
+ }
125
+ // Validate that we have at least one key remaining
126
+ if (Object.keys(resultValues).length === 0) {
127
+ throw new Error('enumExclude: excluding all keys would result in an empty enum');
128
+ }
129
+ // Create and return the new branded enum (this handles registration)
130
+ return (0, _factory.createBrandedEnum)(newId, resultValues);
131
+ }
132
+ function enumMap(newId, sourceEnum, mapper) {
133
+ // Validate that sourceEnum is a branded enum
134
+ if (!isBrandedEnum(sourceEnum)) {
135
+ throw new Error('enumMap requires a branded enum as the source');
136
+ }
137
+ // Get all keys from the source enum (excluding Symbol metadata)
138
+ const allKeys = Object.keys(sourceEnum);
139
+ // Build the result values object with transformed values
140
+ const resultValues = {};
141
+ for (const key of allKeys){
142
+ const originalValue = sourceEnum[key];
143
+ const transformedValue = mapper(originalValue, key);
144
+ // Validate that the mapper returned a string
145
+ if (typeof transformedValue !== 'string') {
146
+ throw new Error('enumMap mapper must return a string');
147
+ }
148
+ resultValues[key] = transformedValue;
149
+ }
150
+ // Create and return the new branded enum (this handles registration)
151
+ return (0, _factory.createBrandedEnum)(newId, resultValues);
152
+ }
153
+ function enumFromKeys(enumId, keys) {
154
+ // Validate that keys array is not empty
155
+ if (keys.length === 0) {
156
+ throw new Error('enumFromKeys requires at least one key');
157
+ }
158
+ // Track seen keys to detect duplicates
159
+ const seenKeys = new Set();
160
+ // Build the values object where each key maps to itself
161
+ const values = {};
162
+ for (const key of keys){
163
+ // Validate that each key is a non-empty string
164
+ if (typeof key !== 'string' || key.length === 0) {
165
+ throw new Error('enumFromKeys requires all keys to be non-empty strings');
166
+ }
167
+ // Check for duplicate keys
168
+ if (seenKeys.has(key)) {
169
+ throw new Error(`enumFromKeys: duplicate key "${key}" found`);
170
+ }
171
+ seenKeys.add(key);
172
+ values[key] = key;
173
+ }
174
+ // Create and return the new branded enum (this handles registration)
175
+ return (0, _factory.createBrandedEnum)(enumId, values);
176
+ }
177
+ function enumDiff(firstEnum, secondEnum) {
178
+ // Validate that both arguments are branded enums
179
+ if (!isBrandedEnum(firstEnum) || !isBrandedEnum(secondEnum)) {
180
+ throw new Error('enumDiff requires branded enums as arguments');
181
+ }
182
+ // Get all keys from both enums (excluding Symbol metadata)
183
+ const firstKeys = new Set(Object.keys(firstEnum));
184
+ const secondKeys = new Set(Object.keys(secondEnum));
185
+ const onlyInFirst = [];
186
+ const onlyInSecond = [];
187
+ const differentValues = [];
188
+ const sameValues = [];
189
+ // Find keys only in first enum and keys in both
190
+ for (const key of firstKeys){
191
+ const firstValue = firstEnum[key];
192
+ if (!secondKeys.has(key)) {
193
+ // Key only exists in first enum
194
+ onlyInFirst.push({
195
+ key,
196
+ value: firstValue
197
+ });
198
+ } else {
199
+ // Key exists in both - compare values
200
+ const secondValue = secondEnum[key];
201
+ if (firstValue === secondValue) {
202
+ sameValues.push({
203
+ key,
204
+ value: firstValue
205
+ });
206
+ } else {
207
+ differentValues.push({
208
+ key,
209
+ firstValue,
210
+ secondValue
211
+ });
212
+ }
213
+ }
214
+ }
215
+ // Find keys only in second enum
216
+ for (const key of secondKeys){
217
+ if (!firstKeys.has(key)) {
218
+ const secondValue = secondEnum[key];
219
+ onlyInSecond.push({
220
+ key,
221
+ value: secondValue
222
+ });
223
+ }
224
+ }
225
+ return {
226
+ onlyInFirst,
227
+ onlyInSecond,
228
+ differentValues,
229
+ sameValues
230
+ };
231
+ }
232
+ function enumIntersect(...enums) {
233
+ // Validate that at least two enums are provided
234
+ if (enums.length < 2) {
235
+ throw new Error('enumIntersect requires at least two branded enums');
236
+ }
237
+ // Validate that all arguments are branded enums
238
+ for (const enumObj of enums){
239
+ if (!isBrandedEnum(enumObj)) {
240
+ throw new Error('enumIntersect requires all arguments to be branded enums');
241
+ }
242
+ }
243
+ // Build a map of value -> Set of enum IDs containing that value
244
+ const valueToEnumIds = new Map();
245
+ for (const enumObj of enums){
246
+ const enumId = enumObj[_types.ENUM_ID];
247
+ const values = enumObj[_types.ENUM_VALUES];
248
+ for (const value of values){
249
+ if (!valueToEnumIds.has(value)) {
250
+ valueToEnumIds.set(value, new Set());
251
+ }
252
+ valueToEnumIds.get(value).add(enumId);
253
+ }
254
+ }
255
+ // Filter to only values that appear in multiple enums
256
+ const result = [];
257
+ for (const [value, enumIds] of valueToEnumIds){
258
+ if (enumIds.size >= 2) {
259
+ result.push({
260
+ value,
261
+ enumIds: Array.from(enumIds).sort()
262
+ });
263
+ }
264
+ }
265
+ // Sort by value for consistent ordering
266
+ result.sort((a, b)=>a.value.localeCompare(b.value));
267
+ return result;
268
+ }
269
+ function enumToRecord(enumObj) {
270
+ // Validate that enumObj is a branded enum
271
+ if (!isBrandedEnum(enumObj)) {
272
+ throw new Error('enumToRecord requires a branded enum');
273
+ }
274
+ // Create a new plain object with only the enumerable key-value pairs
275
+ const result = {};
276
+ for (const key of Object.keys(enumObj)){
277
+ result[key] = enumObj[key];
278
+ }
279
+ return result;
280
+ }
281
+ /**
282
+ * The key used to store the enum watcher registry on globalThis.
283
+ * Namespaced to avoid collisions with other libraries.
284
+ */ const WATCHER_REGISTRY_KEY = '__brandedEnumWatcherRegistry__';
285
+ /**
286
+ * Gets or initializes the watcher registry on globalThis.
287
+ */ function getWatcherRegistry() {
288
+ const global = globalThis;
289
+ if (!global[WATCHER_REGISTRY_KEY]) {
290
+ global[WATCHER_REGISTRY_KEY] = {
291
+ watchers: new Map(),
292
+ globalWatchers: new Set()
293
+ };
294
+ }
295
+ return global[WATCHER_REGISTRY_KEY];
296
+ }
297
+ function watchEnum(enumObj, callback) {
298
+ // Validate that enumObj is a branded enum
299
+ if (!isBrandedEnum(enumObj)) {
300
+ throw new Error('watchEnum requires a branded enum');
301
+ }
302
+ const enumId = enumObj[_types.ENUM_ID];
303
+ const registry = getWatcherRegistry();
304
+ // Add callback to the registry for this enum
305
+ if (!registry.watchers.has(enumId)) {
306
+ registry.watchers.set(enumId, new Set());
307
+ }
308
+ registry.watchers.get(enumId).add(callback);
309
+ // Track if this watcher is still active
310
+ let isActive = true;
311
+ // Create a Proxy to intercept access
312
+ const proxy = new Proxy(enumObj, {
313
+ get (target, prop, receiver) {
314
+ const value = Reflect.get(target, prop, receiver);
315
+ // Only trigger callback for active watchers and string keys (not symbols)
316
+ if (isActive && typeof prop === 'string') {
317
+ const event = {
318
+ enumId,
319
+ accessType: 'get',
320
+ key: prop,
321
+ value: typeof value === 'string' ? value : undefined,
322
+ timestamp: Date.now()
323
+ };
324
+ // Call the specific callback
325
+ callback(event);
326
+ // Also call any global watchers
327
+ for (const globalCallback of registry.globalWatchers){
328
+ globalCallback(event);
329
+ }
330
+ }
331
+ return value;
332
+ },
333
+ has (target, prop) {
334
+ const result = Reflect.has(target, prop);
335
+ // Only trigger callback for active watchers and string keys
336
+ if (isActive && typeof prop === 'string') {
337
+ const event = {
338
+ enumId,
339
+ accessType: 'has',
340
+ key: prop,
341
+ timestamp: Date.now()
342
+ };
343
+ callback(event);
344
+ for (const globalCallback of registry.globalWatchers){
345
+ globalCallback(event);
346
+ }
347
+ }
348
+ return result;
349
+ },
350
+ ownKeys (target) {
351
+ const keys = Reflect.ownKeys(target);
352
+ if (isActive) {
353
+ const event = {
354
+ enumId,
355
+ accessType: 'keys',
356
+ timestamp: Date.now()
357
+ };
358
+ callback(event);
359
+ for (const globalCallback of registry.globalWatchers){
360
+ globalCallback(event);
361
+ }
362
+ }
363
+ return keys;
364
+ },
365
+ getOwnPropertyDescriptor (target, prop) {
366
+ return Reflect.getOwnPropertyDescriptor(target, prop);
367
+ }
368
+ });
369
+ // Create unwatch function
370
+ const unwatch = ()=>{
371
+ isActive = false;
372
+ const callbacks = registry.watchers.get(enumId);
373
+ if (callbacks) {
374
+ callbacks.delete(callback);
375
+ if (callbacks.size === 0) {
376
+ registry.watchers.delete(enumId);
377
+ }
378
+ }
379
+ };
380
+ return {
381
+ watched: proxy,
382
+ unwatch
383
+ };
384
+ }
385
+ function watchAllEnums(callback) {
386
+ const registry = getWatcherRegistry();
387
+ registry.globalWatchers.add(callback);
388
+ return ()=>{
389
+ registry.globalWatchers.delete(callback);
390
+ };
391
+ }
392
+ function clearAllEnumWatchers() {
393
+ const registry = getWatcherRegistry();
394
+ registry.watchers.clear();
395
+ registry.globalWatchers.clear();
396
+ }
397
+ function getEnumWatcherCount(enumId) {
398
+ const registry = getWatcherRegistry();
399
+ return registry.watchers.get(enumId)?.size ?? 0;
400
+ }
401
+ function getGlobalWatcherCount() {
402
+ const registry = getWatcherRegistry();
403
+ return registry.globalWatchers.size;
404
+ }
405
+ function exhaustive(value, message) {
406
+ const errorMessage = message ?? `Exhaustive check failed: unexpected value "${String(value)}"`;
407
+ throw new Error(errorMessage);
408
+ }
409
+ function exhaustiveGuard(enumObj) {
410
+ // Validate that enumObj is a branded enum
411
+ if (!isBrandedEnum(enumObj)) {
412
+ throw new Error('exhaustiveGuard requires a branded enum');
413
+ }
414
+ const enumId = enumObj[_types.ENUM_ID];
415
+ return (value)=>{
416
+ throw new Error(`Exhaustive check failed for enum "${enumId}": unexpected value "${String(value)}"`);
417
+ };
418
+ }
419
+ /**
420
+ * Maps schema version options to their corresponding $schema URIs.
421
+ */ const SCHEMA_VERSION_URIS = {
422
+ 'draft-04': 'http://json-schema.org/draft-04/schema#',
423
+ 'draft-06': 'http://json-schema.org/draft-06/schema#',
424
+ 'draft-07': 'http://json-schema.org/draft-07/schema#',
425
+ '2019-09': 'https://json-schema.org/draft/2019-09/schema',
426
+ '2020-12': 'https://json-schema.org/draft/2020-12/schema'
427
+ };
428
+ function toJsonSchema(enumObj, options = {}) {
429
+ // Validate that enumObj is a branded enum
430
+ if (!isBrandedEnum(enumObj)) {
431
+ throw new Error('toJsonSchema requires a branded enum');
432
+ }
433
+ const enumId = enumObj[_types.ENUM_ID];
434
+ const values = enumObj[_types.ENUM_VALUES];
435
+ // Extract options with defaults
436
+ const { title = enumId, description = `Enum values for ${enumId}`, includeSchema = true, schemaVersion = 'draft-07' } = options;
437
+ // Build the schema object
438
+ const schema = {
439
+ title,
440
+ description,
441
+ type: 'string',
442
+ enum: Array.from(values).sort()
443
+ };
444
+ // Add $schema if requested
445
+ if (includeSchema) {
446
+ return {
447
+ $schema: SCHEMA_VERSION_URIS[schemaVersion],
448
+ ...schema
449
+ };
450
+ }
451
+ return schema;
452
+ }
453
+ function toZodSchema(enumObj, options = {}) {
454
+ // Validate that enumObj is a branded enum
455
+ if (!isBrandedEnum(enumObj)) {
456
+ throw new Error('toZodSchema requires a branded enum');
457
+ }
458
+ const enumId = enumObj[_types.ENUM_ID];
459
+ const values = enumObj[_types.ENUM_VALUES];
460
+ // Convert Set to sorted array
461
+ const valuesArray = Array.from(values).sort();
462
+ // Zod's z.enum() requires at least one value
463
+ if (valuesArray.length === 0) {
464
+ throw new Error('toZodSchema requires an enum with at least one value');
465
+ }
466
+ // Build the schema definition
467
+ const definition = {
468
+ typeName: 'ZodEnum',
469
+ values: valuesArray,
470
+ enumId
471
+ };
472
+ // Add description if provided
473
+ if (options.description !== undefined) {
474
+ return {
475
+ ...definition,
476
+ description: options.description
477
+ };
478
+ }
479
+ return definition;
480
+ }
481
+ function enumSerializer(enumObj, options = {}) {
482
+ // Validate that enumObj is a branded enum
483
+ if (!isBrandedEnum(enumObj)) {
484
+ throw new Error('enumSerializer requires a branded enum');
485
+ }
486
+ const enumId = enumObj[_types.ENUM_ID];
487
+ const values = enumObj[_types.ENUM_VALUES];
488
+ const validValues = Array.from(values).sort();
489
+ const { serialize: serializeTransform, deserialize: deserializeTransform } = options;
490
+ return {
491
+ enumObj,
492
+ enumId,
493
+ serialize (value) {
494
+ // Apply custom transform if provided
495
+ if (serializeTransform) {
496
+ return serializeTransform(value);
497
+ }
498
+ return value;
499
+ },
500
+ deserialize (value) {
501
+ // Check if value is a string
502
+ if (typeof value !== 'string') {
503
+ const valueType = value === null ? 'null' : typeof value;
504
+ return {
505
+ success: false,
506
+ error: {
507
+ message: `Expected a string value, received ${valueType}`,
508
+ input: value,
509
+ enumId,
510
+ validValues
511
+ }
512
+ };
513
+ }
514
+ // Apply custom deserialize transform if provided
515
+ let transformedValue = value;
516
+ if (deserializeTransform) {
517
+ try {
518
+ transformedValue = deserializeTransform(value);
519
+ } catch (e) {
520
+ return {
521
+ success: false,
522
+ error: {
523
+ message: `Deserialize transform failed: ${e instanceof Error ? e.message : String(e)}`,
524
+ input: value,
525
+ enumId,
526
+ validValues
527
+ }
528
+ };
529
+ }
530
+ }
531
+ // Validate against the enum
532
+ if (!values.has(transformedValue)) {
533
+ return {
534
+ success: false,
535
+ error: {
536
+ message: `Value "${transformedValue}" is not a member of enum "${enumId}"`,
537
+ input: value,
538
+ enumId,
539
+ validValues
540
+ }
541
+ };
542
+ }
543
+ return {
544
+ success: true,
545
+ value: transformedValue
546
+ };
547
+ },
548
+ deserializeOrThrow (value) {
549
+ const result = this.deserialize(value);
550
+ if (!result.success) {
551
+ throw new Error(result.error.message);
552
+ }
553
+ return result.value;
554
+ }
555
+ };
556
+ }
557
+
558
+ //# sourceMappingURL=advanced.cjs.map