@quanticjs/feature-flags 2.0.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.
- package/dist/FeatureFlagBehavior.d.ts +10 -0
- package/dist/FeatureFlagBehavior.js +59 -0
- package/dist/QuanticFeatureFlagsModule.d.ts +5 -0
- package/dist/QuanticFeatureFlagsModule.js +34 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +9 -0
- package/dist/unleash.module.d.ts +9 -0
- package/dist/unleash.module.js +47 -0
- package/package.json +27 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Unleash } from 'unleash-client';
|
|
2
|
+
import { Result, PipelineBehavior, PipelineScope } from '@quanticjs/core';
|
|
3
|
+
export declare class FeatureFlagBehavior implements PipelineBehavior {
|
|
4
|
+
private readonly unleash?;
|
|
5
|
+
readonly order: 30;
|
|
6
|
+
readonly scope: PipelineScope;
|
|
7
|
+
private readonly logger;
|
|
8
|
+
constructor(unleash?: Unleash | undefined);
|
|
9
|
+
execute<T>(command: object, next: () => Promise<Result<T>>): Promise<Result<T>>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var FeatureFlagBehavior_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.FeatureFlagBehavior = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const unleash_client_1 = require("unleash-client");
|
|
19
|
+
const core_1 = require("@quanticjs/core");
|
|
20
|
+
let FeatureFlagBehavior = FeatureFlagBehavior_1 = class FeatureFlagBehavior {
|
|
21
|
+
unleash;
|
|
22
|
+
order = core_1.BehaviorOrder.FEATURE_FLAG;
|
|
23
|
+
scope = 'both';
|
|
24
|
+
logger = new common_1.Logger(FeatureFlagBehavior_1.name);
|
|
25
|
+
constructor(unleash) {
|
|
26
|
+
this.unleash = unleash;
|
|
27
|
+
}
|
|
28
|
+
async execute(command, next) {
|
|
29
|
+
const metadata = (0, core_1.getFeatureFlagMetadata)(command.constructor);
|
|
30
|
+
if (!metadata) {
|
|
31
|
+
return next();
|
|
32
|
+
}
|
|
33
|
+
if (!this.unleash) {
|
|
34
|
+
this.logger.debug('Unleash not configured, skipping feature flag check');
|
|
35
|
+
return next();
|
|
36
|
+
}
|
|
37
|
+
const { flagName, fallback, defaultValue } = metadata;
|
|
38
|
+
const isEnabled = this.unleash.isEnabled(flagName);
|
|
39
|
+
if (isEnabled) {
|
|
40
|
+
return next();
|
|
41
|
+
}
|
|
42
|
+
this.logger.warn(`Feature flag "${flagName}" is disabled, applying fallback: ${fallback}`);
|
|
43
|
+
switch (fallback) {
|
|
44
|
+
case 'skip':
|
|
45
|
+
return core_1.Result.success(undefined);
|
|
46
|
+
case 'default':
|
|
47
|
+
return core_1.Result.success(defaultValue);
|
|
48
|
+
case 'throw':
|
|
49
|
+
default:
|
|
50
|
+
return core_1.Result.failure(core_1.ErrorType.Forbidden, `Feature "${flagName}" is currently disabled`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
exports.FeatureFlagBehavior = FeatureFlagBehavior;
|
|
55
|
+
exports.FeatureFlagBehavior = FeatureFlagBehavior = FeatureFlagBehavior_1 = __decorate([
|
|
56
|
+
(0, common_1.Injectable)(),
|
|
57
|
+
__param(0, (0, common_1.Optional)()),
|
|
58
|
+
__metadata("design:paramtypes", [unleash_client_1.Unleash])
|
|
59
|
+
], FeatureFlagBehavior);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var QuanticFeatureFlagsModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.QuanticFeatureFlagsModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const core_1 = require("@quanticjs/core");
|
|
13
|
+
const unleash_module_1 = require("./unleash.module");
|
|
14
|
+
const FeatureFlagBehavior_1 = require("./FeatureFlagBehavior");
|
|
15
|
+
let QuanticFeatureFlagsModule = QuanticFeatureFlagsModule_1 = class QuanticFeatureFlagsModule {
|
|
16
|
+
static forRoot(options) {
|
|
17
|
+
return {
|
|
18
|
+
module: QuanticFeatureFlagsModule_1,
|
|
19
|
+
imports: [unleash_module_1.UnleashModule.forRoot(options)],
|
|
20
|
+
providers: [
|
|
21
|
+
{ provide: core_1.PIPELINE_BEHAVIOR, useExisting: FeatureFlagBehavior_1.FeatureFlagBehavior, multi: true },
|
|
22
|
+
],
|
|
23
|
+
exports: [
|
|
24
|
+
unleash_module_1.UnleashModule,
|
|
25
|
+
FeatureFlagBehavior_1.FeatureFlagBehavior,
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
exports.QuanticFeatureFlagsModule = QuanticFeatureFlagsModule;
|
|
31
|
+
exports.QuanticFeatureFlagsModule = QuanticFeatureFlagsModule = QuanticFeatureFlagsModule_1 = __decorate([
|
|
32
|
+
(0, common_1.Global)(),
|
|
33
|
+
(0, common_1.Module)({})
|
|
34
|
+
], QuanticFeatureFlagsModule);
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QuanticFeatureFlagsModule = exports.UnleashModule = exports.FeatureFlagBehavior = void 0;
|
|
4
|
+
var FeatureFlagBehavior_1 = require("./FeatureFlagBehavior");
|
|
5
|
+
Object.defineProperty(exports, "FeatureFlagBehavior", { enumerable: true, get: function () { return FeatureFlagBehavior_1.FeatureFlagBehavior; } });
|
|
6
|
+
var unleash_module_1 = require("./unleash.module");
|
|
7
|
+
Object.defineProperty(exports, "UnleashModule", { enumerable: true, get: function () { return unleash_module_1.UnleashModule; } });
|
|
8
|
+
var QuanticFeatureFlagsModule_1 = require("./QuanticFeatureFlagsModule");
|
|
9
|
+
Object.defineProperty(exports, "QuanticFeatureFlagsModule", { enumerable: true, get: function () { return QuanticFeatureFlagsModule_1.QuanticFeatureFlagsModule; } });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
export interface UnleashModuleOptions {
|
|
3
|
+
url?: string;
|
|
4
|
+
appName?: string;
|
|
5
|
+
customHeaders?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
export declare class UnleashModule {
|
|
8
|
+
static forRoot(options?: UnleashModuleOptions): DynamicModule;
|
|
9
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var UnleashModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.UnleashModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const unleash_client_1 = require("unleash-client");
|
|
13
|
+
const FeatureFlagBehavior_1 = require("./FeatureFlagBehavior");
|
|
14
|
+
let UnleashModule = UnleashModule_1 = class UnleashModule {
|
|
15
|
+
static forRoot(options) {
|
|
16
|
+
const unleashProvider = {
|
|
17
|
+
provide: unleash_client_1.Unleash,
|
|
18
|
+
useFactory: () => {
|
|
19
|
+
const logger = new common_1.Logger('UnleashModule');
|
|
20
|
+
const url = options?.url || process.env['UNLEASH_URL'] || 'http://localhost:4242/api';
|
|
21
|
+
const appName = options?.appName || process.env['UNLEASH_APP_NAME'] || 'arex';
|
|
22
|
+
const token = options?.customHeaders?.['Authorization'] ||
|
|
23
|
+
process.env['UNLEASH_API_TOKEN'] ||
|
|
24
|
+
'*:*.unleash-insecure-api-token';
|
|
25
|
+
logger.log(`Connecting to Unleash at ${url}`);
|
|
26
|
+
return (0, unleash_client_1.initialize)({
|
|
27
|
+
url,
|
|
28
|
+
appName,
|
|
29
|
+
customHeaders: {
|
|
30
|
+
Authorization: token,
|
|
31
|
+
},
|
|
32
|
+
refreshInterval: 10000,
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
module: UnleashModule_1,
|
|
38
|
+
providers: [unleashProvider, FeatureFlagBehavior_1.FeatureFlagBehavior],
|
|
39
|
+
exports: [unleash_client_1.Unleash, FeatureFlagBehavior_1.FeatureFlagBehavior],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
exports.UnleashModule = UnleashModule;
|
|
44
|
+
exports.UnleashModule = UnleashModule = UnleashModule_1 = __decorate([
|
|
45
|
+
(0, common_1.Global)(),
|
|
46
|
+
(0, common_1.Module)({})
|
|
47
|
+
], UnleashModule);
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@quanticjs/feature-flags",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Feature flag integration for quanticjs — Unleash-backed pipeline behavior",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"registry": "https://registry.npmjs.org",
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc -p tsconfig.json",
|
|
17
|
+
"test": "jest --passWithNoTests",
|
|
18
|
+
"clean": "rm -rf dist"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@quanticjs/core": "^2.0.0"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"@nestjs/common": "^11.0.0",
|
|
25
|
+
"unleash-client": "^6.0.0"
|
|
26
|
+
}
|
|
27
|
+
}
|