@nestarc/feature-flag 0.3.0 → 0.5.0

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 (44) hide show
  1. package/README.md +164 -13
  2. package/dist/admin/feature-flag-admin.controller.d.ts +3 -1
  3. package/dist/admin/feature-flag-admin.controller.js +12 -0
  4. package/dist/admin/feature-flag-admin.controller.js.map +1 -1
  5. package/dist/admin/feature-flag-admin.dto.d.ts +8 -0
  6. package/dist/admin/feature-flag-admin.dto.js +24 -1
  7. package/dist/admin/feature-flag-admin.dto.js.map +1 -1
  8. package/dist/events/feature-flag.events.d.ts +35 -2
  9. package/dist/events/feature-flag.events.js +1 -0
  10. package/dist/events/feature-flag.events.js.map +1 -1
  11. package/dist/flag-registry.d.ts +24 -0
  12. package/dist/flag-registry.js +62 -0
  13. package/dist/flag-registry.js.map +1 -0
  14. package/dist/guards/feature-flag.guard.js +5 -1
  15. package/dist/guards/feature-flag.guard.js.map +1 -1
  16. package/dist/index.d.ts +5 -2
  17. package/dist/index.js +7 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/interfaces/evaluation-context.interface.d.ts +2 -0
  20. package/dist/interfaces/evaluation-details.interface.d.ts +29 -0
  21. package/dist/interfaces/evaluation-details.interface.js +3 -0
  22. package/dist/interfaces/evaluation-details.interface.js.map +1 -0
  23. package/dist/interfaces/feature-flag-options.interface.d.ts +3 -0
  24. package/dist/interfaces/feature-flag.interface.d.ts +9 -0
  25. package/dist/interfaces/flag-registry.interface.d.ts +17 -0
  26. package/dist/interfaces/flag-registry.interface.js +3 -0
  27. package/dist/interfaces/flag-registry.interface.js.map +1 -0
  28. package/dist/openfeature.d.ts +26 -0
  29. package/dist/openfeature.js +96 -0
  30. package/dist/openfeature.js.map +1 -0
  31. package/dist/services/feature-flag.service.d.ts +14 -7
  32. package/dist/services/feature-flag.service.js +103 -24
  33. package/dist/services/feature-flag.service.js.map +1 -1
  34. package/dist/services/flag-evaluator.service.d.ts +7 -8
  35. package/dist/services/flag-evaluator.service.js +62 -10
  36. package/dist/services/flag-evaluator.service.js.map +1 -1
  37. package/dist/testing/index.d.ts +1 -1
  38. package/dist/testing/index.js +2 -1
  39. package/dist/testing/index.js.map +1 -1
  40. package/dist/testing/test-feature-flag.module.d.ts +21 -0
  41. package/dist/testing/test-feature-flag.module.js +78 -19
  42. package/dist/testing/test-feature-flag.module.js.map +1 -1
  43. package/package.json +25 -6
  44. package/prisma/schema.prisma +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"flag-evaluator.service.js","sourceRoot":"","sources":["../../src/services/flag-evaluator.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flag-evaluator.service.js","sourceRoot":"","sources":["../../src/services/flag-evaluator.service.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- export { TestFeatureFlagModule } from './test-feature-flag.module';
1
+ export { TestFeatureFlagController, TestFeatureFlagModule, TestFeatureFlagRegistryOptions, } from './test-feature-flag.module';
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TestFeatureFlagModule = void 0;
3
+ exports.TestFeatureFlagModule = exports.TestFeatureFlagController = void 0;
4
4
  var test_feature_flag_module_1 = require("./test-feature-flag.module");
5
+ Object.defineProperty(exports, "TestFeatureFlagController", { enumerable: true, get: function () { return test_feature_flag_module_1.TestFeatureFlagController; } });
5
6
  Object.defineProperty(exports, "TestFeatureFlagModule", { enumerable: true, get: function () { return test_feature_flag_module_1.TestFeatureFlagModule; } });
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":";;;AAAA,uEAAmE;AAA1D,iIAAA,qBAAqB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":";;;AAAA,uEAIoC;AAHlC,qIAAA,yBAAyB,OAAA;AACzB,iIAAA,qBAAqB,OAAA"}
@@ -1,4 +1,25 @@
1
1
  import { DynamicModule } from '@nestjs/common';
2
+ import { FeatureFlagWithOverrides } from '../interfaces/feature-flag.interface';
3
+ import { BooleanEvaluationDetails, EvaluateBooleanOptions } from '../interfaces/evaluation-details.interface';
4
+ import { FlagKey, FlagRegistry } from '../interfaces/flag-registry.interface';
2
5
  export declare class TestFeatureFlagModule {
3
6
  static register(flags?: Record<string, boolean>): DynamicModule;
7
+ static registerRegistry<TFlags extends FlagRegistry>(flags: TFlags, options?: TestFeatureFlagRegistryOptions<TFlags>): DynamicModule;
8
+ private static createModule;
9
+ }
10
+ export interface TestFeatureFlagRegistryOptions<TFlags extends FlagRegistry> {
11
+ overrides?: Partial<Record<FlagKey<TFlags>, boolean>>;
12
+ }
13
+ export declare class TestFeatureFlagController<TFlags extends FlagRegistry = FlagRegistry> {
14
+ private readonly defaults;
15
+ private values;
16
+ constructor(defaults: Record<string, boolean>, overrides?: Partial<Record<FlagKey<TFlags>, boolean>>);
17
+ set<K extends FlagKey<TFlags>>(key: K, value: boolean): void;
18
+ reset(): void;
19
+ isEnabled(key: string, options?: EvaluateBooleanOptions): boolean;
20
+ evaluateAll(): Record<string, boolean>;
21
+ getDetails(key: string, options?: EvaluateBooleanOptions): BooleanEvaluationDetails;
22
+ findFlag(key: string): FeatureFlagWithOverrides;
23
+ findAll(): FeatureFlagWithOverrides[];
24
+ private getValue;
4
25
  }
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  };
8
8
  var TestFeatureFlagModule_1;
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.TestFeatureFlagModule = void 0;
10
+ exports.TestFeatureFlagController = exports.TestFeatureFlagModule = void 0;
11
11
  const common_1 = require("@nestjs/common");
12
12
  const feature_flag_service_1 = require("../services/feature-flag.service");
13
13
  function makeStubFlag(partial = {}) {
@@ -26,32 +26,29 @@ function makeStubFlag(partial = {}) {
26
26
  }
27
27
  let TestFeatureFlagModule = TestFeatureFlagModule_1 = class TestFeatureFlagModule {
28
28
  static register(flags) {
29
+ const controller = new TestFeatureFlagController(flags ?? {});
30
+ return this.createModule(controller);
31
+ }
32
+ static registerRegistry(flags, options = {}) {
33
+ const defaults = Object.fromEntries(Object.entries(flags).map(([key, definition]) => [key, definition.defaultValue]));
34
+ const controller = new TestFeatureFlagController(defaults, options.overrides);
35
+ return this.createModule(controller);
36
+ }
37
+ static createModule(controller) {
29
38
  return {
30
39
  module: TestFeatureFlagModule_1,
31
40
  global: true,
32
41
  providers: [
42
+ {
43
+ provide: TestFeatureFlagController,
44
+ useValue: controller,
45
+ },
33
46
  {
34
47
  provide: feature_flag_service_1.FeatureFlagService,
35
- useValue: {
36
- isEnabled: async (key) => flags?.[key] ?? false,
37
- evaluateAll: async () => flags ?? {},
38
- create: async (input) => makeStubFlag({ key: input.key, enabled: input.enabled ?? false }),
39
- update: async (key, input) => makeStubFlag({ key, ...input }),
40
- archive: async (key) => makeStubFlag({ key, archivedAt: new Date() }),
41
- setOverride: async () => { },
42
- removeOverride: async () => { },
43
- findAll: async () => Object.entries(flags ?? {}).map(([key, enabled]) => makeStubFlag({ key, enabled })),
44
- findByKey: async (key) => {
45
- if (flags && key in flags) {
46
- return makeStubFlag({ key, enabled: flags[key] });
47
- }
48
- throw new common_1.NotFoundException(`Feature flag "${key}" not found`);
49
- },
50
- invalidateCache: async () => { },
51
- },
48
+ useValue: createFeatureFlagServiceStub(controller),
52
49
  },
53
50
  ],
54
- exports: [feature_flag_service_1.FeatureFlagService],
51
+ exports: [feature_flag_service_1.FeatureFlagService, TestFeatureFlagController],
55
52
  };
56
53
  }
57
54
  };
@@ -59,4 +56,66 @@ exports.TestFeatureFlagModule = TestFeatureFlagModule;
59
56
  exports.TestFeatureFlagModule = TestFeatureFlagModule = TestFeatureFlagModule_1 = __decorate([
60
57
  (0, common_1.Module)({})
61
58
  ], TestFeatureFlagModule);
59
+ class TestFeatureFlagController {
60
+ constructor(defaults, overrides = {}) {
61
+ this.defaults = { ...defaults };
62
+ this.values = { ...defaults, ...overrides };
63
+ }
64
+ set(key, value) {
65
+ this.values[key] = value;
66
+ }
67
+ reset() {
68
+ this.values = { ...this.defaults };
69
+ }
70
+ isEnabled(key, options = {}) {
71
+ return this.getValue(key, options);
72
+ }
73
+ evaluateAll() {
74
+ return { ...this.values };
75
+ }
76
+ getDetails(key, options = {}) {
77
+ const hasValue = Object.prototype.hasOwnProperty.call(this.values, key);
78
+ const value = this.getValue(key, options);
79
+ return {
80
+ flagKey: key,
81
+ value,
82
+ result: value,
83
+ source: hasValue ? 'default' : 'default',
84
+ reason: hasValue ? 'GLOBAL' : 'FLAG_NOT_FOUND',
85
+ defaultUsed: !hasValue,
86
+ evaluationTimeMs: 0,
87
+ };
88
+ }
89
+ findFlag(key) {
90
+ if (!Object.prototype.hasOwnProperty.call(this.values, key)) {
91
+ throw new common_1.NotFoundException(`Feature flag "${key}" not found`);
92
+ }
93
+ return makeStubFlag({ key, enabled: this.values[key] });
94
+ }
95
+ findAll() {
96
+ return Object.entries(this.values).map(([key, enabled]) => makeStubFlag({ key, enabled }));
97
+ }
98
+ getValue(key, options) {
99
+ if (Object.prototype.hasOwnProperty.call(this.values, key)) {
100
+ return this.values[key];
101
+ }
102
+ return options.defaultValue ?? false;
103
+ }
104
+ }
105
+ exports.TestFeatureFlagController = TestFeatureFlagController;
106
+ function createFeatureFlagServiceStub(controller) {
107
+ return {
108
+ isEnabled: async (key, _context, options = {}) => controller.isEnabled(key, options),
109
+ evaluateBoolean: async (key, _context, options = {}) => controller.getDetails(key, options),
110
+ evaluateAll: async () => controller.evaluateAll(),
111
+ create: async (input) => makeStubFlag({ key: input.key, enabled: input.enabled ?? false }),
112
+ update: async (key, input) => makeStubFlag({ key, ...input }),
113
+ archive: async (key) => makeStubFlag({ key, archivedAt: new Date() }),
114
+ setOverride: async () => { },
115
+ removeOverride: async () => { },
116
+ findAll: async () => controller.findAll(),
117
+ findByKey: async (key) => controller.findFlag(key),
118
+ invalidateCache: async () => { },
119
+ };
120
+ }
62
121
  //# sourceMappingURL=test-feature-flag.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"test-feature-flag.module.js","sourceRoot":"","sources":["../../src/testing/test-feature-flag.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA0E;AAC1E,2EAAsE;AAMtE,SAAS,YAAY,CACnB,UAA6C,EAAE;IAE/C,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS;QAC3B,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,MAAM;QAC1B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;QACxC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;QACjC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC;QACnC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;QAChC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI;QACtC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC;QACtD,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC;QACtD,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;KACnC,CAAC;AACJ,CAAC;AAGM,IAAM,qBAAqB,6BAA3B,MAAM,qBAAqB;IAChC,MAAM,CAAC,QAAQ,CAAC,KAA+B;QAC7C,OAAO;YACL,MAAM,EAAE,uBAAqB;YAC7B,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,yCAAkB;oBAC3B,QAAQ,EAAE;wBACR,SAAS,EAAE,KAAK,EAAE,GAAW,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK;wBACvD,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE;wBACpC,MAAM,EAAE,KAAK,EAAE,KAA6B,EAAE,EAAE,CAC9C,YAAY,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,KAAK,EAAE,CAAC;wBACnE,MAAM,EAAE,KAAK,EAAE,GAAW,EAAE,KAAwC,EAAE,EAAE,CACtE,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;wBACjC,OAAO,EAAE,KAAK,EAAE,GAAW,EAAE,EAAE,CAC7B,YAAY,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;wBAC/C,WAAW,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;wBAC3B,cAAc,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;wBAC9B,OAAO,EAAE,KAAK,IAAI,EAAE,CAClB,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,CACjD,YAAY,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAC/B;wBACH,SAAS,EAAE,KAAK,EAAE,GAAW,EAAE,EAAE;4BAC/B,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;gCAC1B,OAAO,YAAY,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;4BACpD,CAAC;4BACD,MAAM,IAAI,0BAAiB,CAAC,iBAAiB,GAAG,aAAa,CAAC,CAAC;wBACjE,CAAC;wBACD,eAAe,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;qBAChC;iBACF;aACF;YACD,OAAO,EAAE,CAAC,yCAAkB,CAAC;SAC9B,CAAC;IACJ,CAAC;CACF,CAAA;AApCY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,qBAAqB,CAoCjC"}
1
+ {"version":3,"file":"test-feature-flag.module.js","sourceRoot":"","sources":["../../src/testing/test-feature-flag.module.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestarc/feature-flag",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "DB-backed feature flags for NestJS + Prisma + PostgreSQL with tenant-aware overrides",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -12,6 +12,10 @@
12
12
  "./testing": {
13
13
  "types": "./dist/testing/index.d.ts",
14
14
  "default": "./dist/testing/index.js"
15
+ },
16
+ "./openfeature": {
17
+ "types": "./dist/openfeature.d.ts",
18
+ "default": "./dist/openfeature.js"
15
19
  }
16
20
  },
17
21
  "files": [
@@ -22,6 +26,7 @@
22
26
  "build": "tsc -p tsconfig.build.json",
23
27
  "test": "jest",
24
28
  "test:cov": "jest --coverage",
29
+ "prebench": "npm run prisma:generate",
25
30
  "bench": "dotenv -e .env.test -- npx ts-node benchmarks/evaluation-overhead.ts",
26
31
  "lint": "eslint 'src/**/*.ts' 'test/**/*.ts'",
27
32
  "format": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",
@@ -30,7 +35,7 @@
30
35
  "docker:down": "docker compose down",
31
36
  "db:migrate": "dotenv -e .env.test -- npx prisma migrate deploy",
32
37
  "db:reset": "dotenv -e .env.test -- npx prisma migrate reset --force",
33
- "pretest:e2e": "npm run docker:up && npm run db:migrate",
38
+ "pretest:e2e": "npm run prisma:generate && npm run docker:up && npm run db:migrate",
34
39
  "test:e2e": "dotenv -e .env.test -- jest --config jest.e2e.config.ts --runInBand"
35
40
  },
36
41
  "repository": {
@@ -52,10 +57,14 @@
52
57
  ],
53
58
  "author": "nestarc",
54
59
  "license": "MIT",
60
+ "engines": {
61
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
62
+ },
55
63
  "peerDependencies": {
56
64
  "@nestjs/common": "^10.0.0 || ^11.0.0",
57
65
  "@nestjs/core": "^10.0.0 || ^11.0.0",
58
- "@prisma/client": "^5.0.0 || ^6.0.0",
66
+ "@openfeature/server-sdk": "^1.0.0",
67
+ "@prisma/client": "^7.0.0",
59
68
  "class-transformer": "^0.5.1",
60
69
  "class-validator": "^0.14.0 || ^0.15.0",
61
70
  "ioredis": "^5.0.0",
@@ -69,10 +78,17 @@
69
78
  "@nestjs/event-emitter": {
70
79
  "optional": true
71
80
  },
81
+ "@openfeature/server-sdk": {
82
+ "optional": true
83
+ },
72
84
  "ioredis": {
73
85
  "optional": true
74
86
  }
75
87
  },
88
+ "overrides": {
89
+ "js-yaml": "4.2.0",
90
+ "multer": "2.2.0"
91
+ },
76
92
  "devDependencies": {
77
93
  "@eslint/js": "^9.0.0",
78
94
  "@nestjs/common": "^11.0.0",
@@ -80,20 +96,23 @@
80
96
  "@nestjs/event-emitter": "^3.0.0",
81
97
  "@nestjs/platform-express": "^11.0.0",
82
98
  "@nestjs/testing": "^11.0.0",
83
- "@prisma/client": "^6.0.0",
99
+ "@prisma/adapter-pg": "^7.9.1",
100
+ "@prisma/client": "^7.9.1",
84
101
  "@types/express": "^5.0.0",
85
102
  "@types/ioredis-mock": "^8.2.7",
86
103
  "@types/jest": "^29.5.0",
87
104
  "@types/supertest": "^7.2.0",
88
105
  "class-transformer": "^0.5.1",
89
106
  "class-validator": "^0.15.1",
107
+ "dotenv": "^17.2.3",
90
108
  "dotenv-cli": "^11.0.0",
91
109
  "eslint": "^9.0.0",
92
- "ioredis": "^5.10.1",
110
+ "ioredis": "^5.11.1",
93
111
  "ioredis-mock": "^8.13.1",
94
112
  "jest": "^29.7.0",
113
+ "pg": "^8.22.0",
95
114
  "prettier": "^3.0.0",
96
- "prisma": "^6.0.0",
115
+ "prisma": "^7.9.1",
97
116
  "reflect-metadata": "^0.2.0",
98
117
  "rxjs": "^7.8.0",
99
118
  "supertest": "^7.2.2",
@@ -1,10 +1,11 @@
1
1
  generator client {
2
- provider = "prisma-client-js"
2
+ provider = "prisma-client"
3
+ output = "../generated/prisma"
4
+ moduleFormat = "cjs"
3
5
  }
4
6
 
5
7
  datasource db {
6
8
  provider = "postgresql"
7
- url = env("DATABASE_URL")
8
9
  }
9
10
 
10
11
  model FeatureFlag {