@nexusts/feature-flag 0.9.6 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,11 @@
1
+ /**
2
+ * `@FeatureFlag('flag-name')` — gate a route behind a feature flag.
3
+ *
4
+ * Dual-mode: supports TC39 standard ES decorators + legacy.
5
+ */
1
6
  import type { FlagContext } from "../types.js";
2
7
  export interface FeatureFlagOptions {
3
- /** Extract a `FlagContext` from the Hono `Context` object (first arg of the handler). */
4
8
  contextFn?: (c: any) => FlagContext;
5
- /** Custom response when the flag is disabled. Defaults to 404 JSON. */
6
9
  onDisabled?: (c: any) => Response | Promise<Response>;
7
10
  }
8
11
  export interface FlagSpec {
@@ -12,16 +15,5 @@ export interface FlagSpec {
12
15
  onDisabled?: (c: any) => Response | Promise<Response>;
13
16
  original: (...args: any[]) => any;
14
17
  }
15
- /**
16
- * Mark a route handler so `FeatureFlagService.applyDecorators()` will gate it.
17
- *
18
- * @Get('/')
19
- * @FeatureFlag('new-dashboard')
20
- * async index(c: Context) { ... }
21
- *
22
- * When the flag is disabled the handler returns a 404 JSON response.
23
- * Pass `onDisabled` to customise the response, or `contextFn` to extract
24
- * a `FlagContext` (userId etc.) from the Hono `Context`.
25
- */
26
- export declare function FeatureFlag(flagName: string, options?: FeatureFlagOptions): MethodDecorator;
18
+ export declare function FeatureFlag(flagName: string, options?: FeatureFlagOptions): any;
27
19
  export declare function getFlagSpecs(target: any): FlagSpec[];
@@ -3,6 +3,8 @@ export declare class FeatureFlagService {
3
3
  #private;
4
4
  /** DI token. */
5
5
  static readonly TOKEN: unique symbol;
6
+ /** Feature flag config — injected by DI container. */
7
+ private _config;
6
8
  constructor(config?: FeatureFlagConfig);
7
9
  /** Returns `true` if the flag is enabled for the given context. */
8
10
  isEnabled(flagName: string, context?: FlagContext): Promise<boolean>;
package/dist/index.js CHANGED
@@ -9,7 +9,6 @@ var __legacyDecorateClassTS = function(decorators, target, key, desc) {
9
9
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
10
10
  return c > 3 && r && Object.defineProperty(target, key, r), r;
11
11
  };
12
- var __legacyDecorateParamTS = (index, decorator) => (target, key) => decorator(target, key, index);
13
12
  var __legacyMetadataTS = (k, v) => {
14
13
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
15
14
  return Reflect.metadata(k, v);
@@ -66,29 +65,60 @@ class MemoryFlagBackend {
66
65
  // packages/feature-flag/src/decorators/feature-flag.decorator.ts
67
66
  import { safeGetMeta, safeDefineMeta } from "@nexusts/core/di/safe-reflect";
68
67
  var FLAG_META = Symbol.for("nexus:FeatureFlag");
68
+ var FN_KEY = Symbol.for("nexus:ff:fn:meta");
69
69
  function FeatureFlag(flagName, options = {}) {
70
- return (target, propertyKey, descriptor) => {
70
+ return function(targetOrFn, contextOrKey) {
71
+ if (contextOrKey?.kind === "method") {
72
+ const fn = targetOrFn;
73
+ const { name, metadata } = contextOrKey;
74
+ const spec = { propertyKey: name, flagName, contextFn: options.contextFn, onDisabled: options.onDisabled, original: fn };
75
+ const existing = metadata[FLAG_META] ?? [];
76
+ existing.push(spec);
77
+ metadata[FLAG_META] = existing;
78
+ if (!fn[FN_KEY])
79
+ fn[FN_KEY] = [];
80
+ fn[FN_KEY].push(spec);
81
+ return;
82
+ }
83
+ const target = targetOrFn;
84
+ const propertyKey = contextOrKey;
85
+ const descriptor = arguments[2];
71
86
  const specs = safeGetMeta(FLAG_META, target.constructor) ?? [];
72
87
  specs.push({
73
88
  propertyKey,
74
89
  flagName,
75
90
  contextFn: options.contextFn,
76
91
  onDisabled: options.onDisabled,
77
- original: descriptor.value
92
+ original: descriptor?.value
78
93
  });
79
94
  safeDefineMeta(FLAG_META, specs, target.constructor);
80
95
  };
81
96
  }
82
97
  function getFlagSpecs(target) {
83
- return safeGetMeta(FLAG_META, target) ?? [];
98
+ const fromLegacy = safeGetMeta(FLAG_META, target);
99
+ if (fromLegacy)
100
+ return fromLegacy;
101
+ const result = [];
102
+ if (target?.prototype) {
103
+ for (const key of Object.getOwnPropertyNames(target.prototype)) {
104
+ const fn = target.prototype[key];
105
+ if (typeof fn === "function") {
106
+ const stashed = fn[FN_KEY];
107
+ if (Array.isArray(stashed))
108
+ result.push(...stashed);
109
+ }
110
+ }
111
+ }
112
+ return result;
84
113
  }
85
114
 
86
115
  // packages/feature-flag/src/feature-flag.service.ts
87
116
  class FeatureFlagService {
88
117
  static TOKEN = Symbol.for("nexus:FeatureFlagService");
89
118
  #backend;
90
- constructor(config = {}) {
91
- this.#backend = new MemoryFlagBackend(config.flags ?? {});
119
+ constructor(config) {
120
+ const cfg = config ?? this._config ?? {};
121
+ this.#backend = new MemoryFlagBackend(cfg.flags ?? {});
92
122
  }
93
123
  async isEnabled(flagName, context) {
94
124
  return this.#backend.isEnabled(flagName, context);
@@ -116,9 +146,11 @@ class FeatureFlagService {
116
146
  }
117
147
  }
118
148
  }
149
+ __legacyDecorateClassTS([
150
+ Inject("FEATURE_FLAG_CONFIG")
151
+ ], FeatureFlagService.prototype, "_config", undefined);
119
152
  FeatureFlagService = __legacyDecorateClassTS([
120
153
  Injectable(),
121
- __legacyDecorateParamTS(0, Inject("FEATURE_FLAG_CONFIG")),
122
154
  __legacyMetadataTS("design:paramtypes", [
123
155
  typeof FeatureFlagConfig === "undefined" ? Object : FeatureFlagConfig
124
156
  ])
@@ -162,5 +194,5 @@ export {
162
194
  FeatureFlag
163
195
  };
164
196
 
165
- //# debugId=D7EE62290E0C17FC64756E2164756E21
197
+ //# debugId=3379C5D85D756B0964756E2164756E21
166
198
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -2,12 +2,12 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/feature-flag.module.ts", "../src/feature-flag.service.ts", "../src/backends/memory.ts", "../src/decorators/feature-flag.decorator.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * `FeatureFlagModule` — drop-in feature flags.\n *\n * @Module({\n * imports: [\n * FeatureFlagModule.forRoot({\n * flags: {\n * 'new-dashboard': { enabled: true, rollout: 0.5 },\n * 'beta-api': false,\n * },\n * }),\n * ],\n * })\n * export class AppModule {}\n */\nimport { Module } from \"@nexusts/core\";\nimport { FeatureFlagService } from \"./feature-flag.service.js\";\nimport type { FeatureFlagConfig } from \"./types.js\";\nimport { safeGetMeta, safeDefineMeta, safeHasMeta } from \"@nexusts/core/di/safe-reflect\";\n\n@Module({\n\tproviders: [\n\t\tFeatureFlagService,\n\t\t{ provide: FeatureFlagService.TOKEN, useExisting: FeatureFlagService },\n\t],\n\texports: [FeatureFlagService, FeatureFlagService.TOKEN],\n})\nexport class FeatureFlagModule {\n\tstatic forRoot(config: FeatureFlagConfig = {}) {\n\t\t@Module({\n\t\t\tproviders: [\n\t\t\t\tFeatureFlagService,\n\t\t\t\t{ provide: FeatureFlagService.TOKEN, useExisting: FeatureFlagService },\n\t\t\t\t{ provide: \"FEATURE_FLAG_CONFIG\", useValue: config },\n\t\t\t],\n\t\t\texports: [FeatureFlagService, FeatureFlagService.TOKEN],\n\t\t})\n\t\tclass ConfiguredFeatureFlagModule {}\n\t\tObject.defineProperty(ConfiguredFeatureFlagModule, \"name\", {\n\t\t\tvalue: \"ConfiguredFeatureFlagModule\",\n\t\t});\n\t\treturn ConfiguredFeatureFlagModule;\n\t}\n}\n",
6
- "/**\n * `FeatureFlagService` — isEnabled / setFlag / getFlag + decorator wiring.\n *\n * const flags = new FeatureFlagService({\n * flags: {\n * 'new-ui': { enabled: true, rollout: 0.5 },\n * 'beta-api': { enabled: false },\n * },\n * });\n *\n * await flags.isEnabled('new-ui', { userId: 'u1' }); // true or false by hash\n */\nimport { Inject, Injectable } from \"@nexusts/core\";\nimport type { FlagContext, FlagDefinition, FeatureFlagBackend, FeatureFlagConfig } from \"./types.js\";\nimport { MemoryFlagBackend } from \"./backends/memory.js\";\nimport { getFlagSpecs } from \"./decorators/feature-flag.decorator.js\";\n\n@Injectable()\nexport class FeatureFlagService {\n\t/** DI token. */\n\tstatic readonly TOKEN = Symbol.for(\"nexus:FeatureFlagService\");\n\n\t#backend: FeatureFlagBackend;\n\n\tconstructor(@Inject(\"FEATURE_FLAG_CONFIG\") config: FeatureFlagConfig = {}) {\n\t\tthis.#backend = new MemoryFlagBackend(config.flags ?? {});\n\t}\n\n\t/** Returns `true` if the flag is enabled for the given context. */\n\tasync isEnabled(flagName: string, context?: FlagContext): Promise<boolean> {\n\t\treturn this.#backend.isEnabled(flagName, context);\n\t}\n\n\t/** Create or update a flag at runtime. */\n\tsetFlag(flagName: string, definition: FlagDefinition | boolean): void {\n\t\tthis.#backend.setFlag(flagName, definition);\n\t}\n\n\t/** Return the raw definition (or `undefined` if unknown). */\n\tgetFlag(flagName: string): FlagDefinition | undefined {\n\t\treturn this.#backend.getFlag(flagName);\n\t}\n\n\t/**\n\t * Wire `@FeatureFlag` decorators onto a controller or service instance.\n\t * Each decorated route handler is wrapped so it returns a 404 JSON\n\t * response when the flag is disabled.\n\t *\n\t * The DI container calls this automatically when FeatureFlagModule is\n\t * imported; you can also call it manually in tests.\n\t */\n\tapplyDecorators(target: any): void {\n\t\tconst specs = getFlagSpecs(target.constructor);\n\t\tfor (const spec of specs) {\n\t\t\tconst original = spec.original;\n\t\t\t(target as any)[spec.propertyKey] = async (c: any, ...rest: any[]) => {\n\t\t\t\tconst ctx = spec.contextFn ? spec.contextFn(c) : undefined;\n\t\t\t\tconst enabled = await this.isEnabled(spec.flagName, ctx);\n\t\t\t\tif (!enabled) {\n\t\t\t\t\tif (spec.onDisabled) return spec.onDisabled(c);\n\t\t\t\t\treturn c.json({ message: \"Feature not available\", code: \"FEATURE_DISABLED\" }, 404);\n\t\t\t\t}\n\t\t\t\treturn original.apply(target, [c, ...rest]);\n\t\t\t};\n\t\t}\n\t}\n}\n",
5
+ "/**\n * `FeatureFlagModule` — drop-in feature flags.\n *\n * @Module({\n * imports: [\n * FeatureFlagModule.forRoot({\n * flags: {\n * 'new-dashboard': { enabled: true, rollout: 0.5 },\n * 'beta-api': false,\n * },\n * }),\n * ],\n * })\n * export class AppModule {}\n */\nimport { Module } from \"@nexusts/core\";\nimport { FeatureFlagService } from \"./feature-flag.service.js\";\nimport type { FeatureFlagConfig } from \"./types.js\";\n\n@Module({\n\tproviders: [\n\t\tFeatureFlagService,\n\t\t{ provide: FeatureFlagService.TOKEN, useExisting: FeatureFlagService },\n\t],\n\texports: [FeatureFlagService, FeatureFlagService.TOKEN],\n})\nexport class FeatureFlagModule {\n\tstatic forRoot(config: FeatureFlagConfig = {}) {\n\t\t@Module({\n\t\t\tproviders: [\n\t\t\t\tFeatureFlagService,\n\t\t\t\t{ provide: FeatureFlagService.TOKEN, useExisting: FeatureFlagService },\n\t\t\t\t{ provide: \"FEATURE_FLAG_CONFIG\", useValue: config },\n\t\t\t],\n\t\t\texports: [FeatureFlagService, FeatureFlagService.TOKEN],\n\t\t})\n\t\tclass ConfiguredFeatureFlagModule {}\n\t\tObject.defineProperty(ConfiguredFeatureFlagModule, \"name\", {\n\t\t\tvalue: \"ConfiguredFeatureFlagModule\",\n\t\t});\n\t\treturn ConfiguredFeatureFlagModule;\n\t}\n}\n",
6
+ "/**\n * `FeatureFlagService` — isEnabled / setFlag / getFlag + decorator wiring.\n *\n * const flags = new FeatureFlagService({\n * flags: {\n * 'new-ui': { enabled: true, rollout: 0.5 },\n * 'beta-api': { enabled: false },\n * },\n * });\n *\n * await flags.isEnabled('new-ui', { userId: 'u1' }); // true or false by hash\n */\nimport { Inject, Injectable } from \"@nexusts/core\";\nimport type { FlagContext, FlagDefinition, FeatureFlagBackend, FeatureFlagConfig } from \"./types.js\";\nimport { MemoryFlagBackend } from \"./backends/memory.js\";\nimport { getFlagSpecs } from \"./decorators/feature-flag.decorator.js\";\n\n@Injectable()\nexport class FeatureFlagService {\n\t/** DI token. */\n\tstatic readonly TOKEN = Symbol.for(\"nexus:FeatureFlagService\");\n\n\t/** Feature flag config — injected by DI container. */\n\t@Inject(\"FEATURE_FLAG_CONFIG\") declare private _config: FeatureFlagConfig;\n\n\t#backend!: FeatureFlagBackend;\n\n\tconstructor(config?: FeatureFlagConfig) {\n\t\tconst cfg = config ?? this._config ?? {};\n\t\tthis.#backend = new MemoryFlagBackend(cfg.flags ?? {});\n\t}\n\n\t/** Returns `true` if the flag is enabled for the given context. */\n\tasync isEnabled(flagName: string, context?: FlagContext): Promise<boolean> {\n\t\treturn this.#backend.isEnabled(flagName, context);\n\t}\n\n\t/** Create or update a flag at runtime. */\n\tsetFlag(flagName: string, definition: FlagDefinition | boolean): void {\n\t\tthis.#backend.setFlag(flagName, definition);\n\t}\n\n\t/** Return the raw definition (or `undefined` if unknown). */\n\tgetFlag(flagName: string): FlagDefinition | undefined {\n\t\treturn this.#backend.getFlag(flagName);\n\t}\n\n\t/**\n\t * Wire `@FeatureFlag` decorators onto a controller or service instance.\n\t * Each decorated route handler is wrapped so it returns a 404 JSON\n\t * response when the flag is disabled.\n\t *\n\t * The DI container calls this automatically when FeatureFlagModule is\n\t * imported; you can also call it manually in tests.\n\t */\n\tapplyDecorators(target: any): void {\n\t\tconst specs = getFlagSpecs(target.constructor);\n\t\tfor (const spec of specs) {\n\t\t\tconst original = spec.original;\n\t\t\t(target as any)[spec.propertyKey] = async (c: any, ...rest: any[]) => {\n\t\t\t\tconst ctx = spec.contextFn ? spec.contextFn(c) : undefined;\n\t\t\t\tconst enabled = await this.isEnabled(spec.flagName, ctx);\n\t\t\t\tif (!enabled) {\n\t\t\t\t\tif (spec.onDisabled) return spec.onDisabled(c);\n\t\t\t\t\treturn c.json({ message: \"Feature not available\", code: \"FEATURE_DISABLED\" }, 404);\n\t\t\t\t}\n\t\t\t\treturn original.apply(target, [c, ...rest]);\n\t\t\t};\n\t\t}\n\t}\n}\n",
7
7
  "import type { FlagContext, FlagDefinition, FeatureFlagBackend } from \"../types.js\";\n\n/** djb2 hash → deterministic 0-1 float for rollout bucketing. */\nfunction hashFloat(s: string): number {\n\tlet h = 5381;\n\tfor (let i = 0; i < s.length; i++) {\n\t\th = Math.imul(h, 33) ^ s.charCodeAt(i);\n\t}\n\treturn (h >>> 0) / 0xffffffff;\n}\n\n/** In-process feature flag backend — no external dependencies. */\nexport class MemoryFlagBackend implements FeatureFlagBackend {\n\t#flags = new Map<string, FlagDefinition>();\n\n\tconstructor(initial: Record<string, FlagDefinition | boolean> = {}) {\n\t\tfor (const [k, v] of Object.entries(initial)) {\n\t\t\tthis.#flags.set(k, typeof v === \"boolean\" ? { enabled: v } : v);\n\t\t}\n\t}\n\n\tsetFlag(flagName: string, definition: FlagDefinition | boolean): void {\n\t\tthis.#flags.set(\n\t\t\tflagName,\n\t\t\ttypeof definition === \"boolean\" ? { enabled: definition } : definition,\n\t\t);\n\t}\n\n\tgetFlag(flagName: string): FlagDefinition | undefined {\n\t\treturn this.#flags.get(flagName);\n\t}\n\n\tasync isEnabled(flagName: string, context?: FlagContext): Promise<boolean> {\n\t\tconst def = this.#flags.get(flagName);\n\t\tif (!def) return false;\n\n\t\tconst id = context?.userId ?? context?.tenantId ?? context?.key ?? \"\";\n\n\t\t// Denylist has highest priority\n\t\tif (id && def.denylist?.includes(id)) return false;\n\n\t\t// Allowlist always wins after denylist\n\t\tif (id && def.allowlist?.includes(id)) return true;\n\n\t\t// Base enabled gate\n\t\tif (def.enabled === false) return false;\n\n\t\t// Rollout: deterministic hash bucketing\n\t\tif (def.rollout !== undefined && def.rollout < 1) {\n\t\t\tif (!id) return def.rollout > 0;\n\t\t\treturn hashFloat(`${flagName}:${id}`) < def.rollout;\n\t\t}\n\n\t\treturn def.enabled ?? true;\n\t}\n}\n",
8
- "import type { FlagContext } from \"../types.js\";\nimport { safeGetMeta, safeDefineMeta, safeHasMeta } from \"@nexusts/core/di/safe-reflect\";\n\nconst FLAG_META = Symbol.for(\"nexus:FeatureFlag\");\n\nexport interface FeatureFlagOptions {\n\t/** Extract a `FlagContext` from the Hono `Context` object (first arg of the handler). */\n\tcontextFn?: (c: any) => FlagContext;\n\t/** Custom response when the flag is disabled. Defaults to 404 JSON. */\n\tonDisabled?: (c: any) => Response | Promise<Response>;\n}\n\nexport interface FlagSpec {\n\tpropertyKey: string | symbol;\n\tflagName: string;\n\tcontextFn?: (c: any) => FlagContext;\n\tonDisabled?: (c: any) => Response | Promise<Response>;\n\toriginal: (...args: any[]) => any;\n}\n\n/**\n * Mark a route handler so `FeatureFlagService.applyDecorators()` will gate it.\n *\n * @Get('/')\n * @FeatureFlag('new-dashboard')\n * async index(c: Context) { ... }\n *\n * When the flag is disabled the handler returns a 404 JSON response.\n * Pass `onDisabled` to customise the response, or `contextFn` to extract\n * a `FlagContext` (userId etc.) from the Hono `Context`.\n */\nexport function FeatureFlag(\n\tflagName: string,\n\toptions: FeatureFlagOptions = {},\n): MethodDecorator {\n\treturn (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n\t\tconst specs: FlagSpec[] = safeGetMeta(FLAG_META, target.constructor) ?? [];\n\t\tspecs.push({\n\t\t\tpropertyKey,\n\t\t\tflagName,\n\t\t\tcontextFn: options.contextFn,\n\t\t\tonDisabled: options.onDisabled,\n\t\t\toriginal: descriptor.value,\n\t\t});\n\t\tsafeDefineMeta(FLAG_META, specs, target.constructor);\n\t};\n}\n\nexport function getFlagSpecs(target: any): FlagSpec[] {\n\treturn safeGetMeta(FLAG_META, target) ?? [];\n}\n"
8
+ "/**\n * `@FeatureFlag('flag-name')` — gate a route behind a feature flag.\n *\n * Dual-mode: supports TC39 standard ES decorators + legacy.\n */\nimport type { FlagContext } from \"../types.js\";\nimport { safeGetMeta, safeDefineMeta } from \"@nexusts/core/di/safe-reflect\";\n\nconst FLAG_META = Symbol.for(\"nexus:FeatureFlag\");\nconst FN_KEY = Symbol.for(\"nexus:ff:fn:meta\");\n\nexport interface FeatureFlagOptions {\n\tcontextFn?: (c: any) => FlagContext;\n\tonDisabled?: (c: any) => Response | Promise<Response>;\n}\n\nexport interface FlagSpec {\n\tpropertyKey: string | symbol;\n\tflagName: string;\n\tcontextFn?: (c: any) => FlagContext;\n\tonDisabled?: (c: any) => Response | Promise<Response>;\n\toriginal: (...args: any[]) => any;\n}\n\nexport function FeatureFlag(flagName: string, options: FeatureFlagOptions = {}): any {\n\treturn function (this: any, targetOrFn: any, contextOrKey?: any): void {\n\t\tif (contextOrKey?.kind === \"method\") {\n\t\t\tconst fn = targetOrFn;\n\t\t\tconst { name, metadata } = contextOrKey;\n\t\t\tconst spec: FlagSpec = { propertyKey: name, flagName, contextFn: options.contextFn, onDisabled: options.onDisabled, original: fn };\n\t\t\tconst existing: FlagSpec[] = (metadata[FLAG_META] as FlagSpec[]) ?? [];\n\t\t\texisting.push(spec);\n\t\t\tmetadata[FLAG_META] = existing;\n\t\t\t// Also stash on the function for legacy reader access.\n\t\t\tif (!(fn as any)[FN_KEY]) (fn as any)[FN_KEY] = [];\n\t\t\t(fn as any)[FN_KEY].push(spec);\n\t\t\treturn;\n\t\t}\n\t\tconst target = targetOrFn;\n\t\tconst propertyKey = contextOrKey as string | symbol;\n\t\tconst descriptor = arguments[2];\n\t\tconst specs: FlagSpec[] = safeGetMeta(FLAG_META, target.constructor) ?? [];\n\t\tspecs.push({\n\t\t\tpropertyKey,\n\t\t\tflagName,\n\t\t\tcontextFn: options.contextFn,\n\t\t\tonDisabled: options.onDisabled,\n\t\t\toriginal: descriptor?.value,\n\t\t});\n\t\tsafeDefineMeta(FLAG_META, specs, target.constructor);\n\t};\n}\n\nexport function getFlagSpecs(target: any): FlagSpec[] {\n\t// Legacy path\n\tconst fromLegacy = safeGetMeta(FLAG_META, target) as FlagSpec[] | undefined;\n\tif (fromLegacy) return fromLegacy;\n\t// Standard path: collect from prototype functions\n\tconst result: FlagSpec[] = [];\n\tif (target?.prototype) {\n\t\tfor (const key of Object.getOwnPropertyNames(target.prototype)) {\n\t\t\tconst fn = target.prototype[key];\n\t\t\tif (typeof fn === \"function\") {\n\t\t\t\tconst stashed = (fn as any)[FN_KEY];\n\t\t\t\tif (Array.isArray(stashed)) result.push(...stashed);\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n"
9
9
  ],
10
- "mappings": "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",
11
- "debugId": "D7EE62290E0C17FC64756E2164756E21",
10
+ "mappings": "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",
11
+ "debugId": "3379C5D85D756B0964756E2164756E21",
12
12
  "names": []
13
13
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexusts/feature-flag",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "Feature flags, canary deployments, and A/B testing for NexusTS",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -29,7 +29,7 @@
29
29
  ],
30
30
  "license": "MIT",
31
31
  "dependencies": {
32
- "@nexusts/core": "^0.9.6"
32
+ "@nexusts/core": "^0.9.7"
33
33
  },
34
34
  "repository": {
35
35
  "type": "git",