@cqrs-ddd/pipeline-feature-flags 0.0.0-stage → 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.
- package/COMMERCIAL_LICENSE.txt +34 -0
- package/LICENSE +661 -0
- package/README.md +35 -2
- package/dist/errors/feature-disabled.error.d.ts +15 -0
- package/dist/errors/feature-disabled.error.d.ts.map +1 -0
- package/dist/errors/feature-disabled.error.js +21 -0
- package/dist/errors/feature-disabled.error.js.map +1 -0
- package/dist/errors/feature-flag-evaluation.error.d.ts +17 -0
- package/dist/errors/feature-flag-evaluation.error.d.ts.map +1 -0
- package/dist/errors/feature-flag-evaluation.error.js +24 -0
- package/dist/errors/feature-flag-evaluation.error.js.map +1 -0
- package/dist/feature-flag.behavior.d.ts +148 -0
- package/dist/feature-flag.behavior.d.ts.map +1 -0
- package/dist/feature-flag.behavior.js +261 -0
- package/dist/feature-flag.behavior.js.map +1 -0
- package/dist/helpers/build-attributes.d.ts +48 -0
- package/dist/helpers/build-attributes.d.ts.map +1 -0
- package/dist/helpers/build-attributes.js +63 -0
- package/dist/helpers/build-attributes.js.map +1 -0
- package/dist/helpers/evaluation-context.d.ts +17 -0
- package/dist/helpers/evaluation-context.d.ts.map +1 -0
- package/dist/helpers/evaluation-context.js +33 -0
- package/dist/helpers/evaluation-context.js.map +1 -0
- package/dist/helpers/feature-flag-client.d.ts +27 -0
- package/dist/helpers/feature-flag-client.d.ts.map +1 -0
- package/dist/helpers/feature-flag-client.js +57 -0
- package/dist/helpers/feature-flag-client.js.map +1 -0
- package/dist/helpers/feature-flag.intent.d.ts +22 -0
- package/dist/helpers/feature-flag.intent.d.ts.map +1 -0
- package/dist/helpers/feature-flag.intent.js +20 -0
- package/dist/helpers/feature-flag.intent.js.map +1 -0
- package/dist/http.d.ts +21 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +31 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/feature-flags-options.interface.d.ts +154 -0
- package/dist/interfaces/feature-flags-options.interface.d.ts.map +1 -0
- package/dist/interfaces/feature-flags-options.interface.js +3 -0
- package/dist/interfaces/feature-flags-options.interface.js.map +1 -0
- package/package.json +67 -3
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
import { getPipelineItem } from '@cqrs-ddd/pipeline';
|
|
3
|
+
import { FEATURE_FLAG_DECISION_ITEM_TOKEN } from '../feature-flag.behavior.js';
|
|
4
|
+
/**
|
|
5
|
+
* The feature-flag decision of one execution as flat attributes, named after
|
|
6
|
+
* the OpenTelemetry feature-flag conventions: `feature_flag.key` and
|
|
7
|
+
* `feature_flag.enabled`, plus `feature_flag.variant` and `feature_flag.reason`
|
|
8
|
+
* when the provider reported them, and `feature_flag.error_code` only when
|
|
9
|
+
* evaluation failed. `{}` when `FeatureFlagBehavior` did not run. The targeting
|
|
10
|
+
* key and the provider's error message are never included.
|
|
11
|
+
*
|
|
12
|
+
* The result is plain data and needs no telemetry package: put it on a span, a
|
|
13
|
+
* log line, an audit record or a metric label (bounded values only).
|
|
14
|
+
*
|
|
15
|
+
* @param context - The pipeline execution, read after `FeatureFlagBehavior` ran.
|
|
16
|
+
* @returns The attributes; empty when the behavior did not run.
|
|
17
|
+
*
|
|
18
|
+
* @example Span attributes
|
|
19
|
+
* With `AttributesBehavior` of `@cqrs-ddd/pipeline-opentelemetry`:
|
|
20
|
+
* ```ts
|
|
21
|
+
* createPipeline({
|
|
22
|
+
* globalBehaviors: {
|
|
23
|
+
* before: [TraceBehavior, [AttributesBehavior, { factories: [buildFeatureFlagAttributes] }]],
|
|
24
|
+
* },
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example Audit metadata
|
|
29
|
+
* `audit()` is declared outside `featureFlag()`, so the record is built after its decision:
|
|
30
|
+
* ```ts
|
|
31
|
+
* @pipeline.wrap(
|
|
32
|
+
* { kind: 'command' },
|
|
33
|
+
* audit({ action: 'order.create', metadata: buildFeatureFlagAttributes }),
|
|
34
|
+
* featureFlag({ flag: 'checkout' }),
|
|
35
|
+
* )
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @example A log line from a custom behavior, after the chain ran
|
|
39
|
+
* ```ts
|
|
40
|
+
* async handle(context: IPipelineContext, next: NextDelegate) {
|
|
41
|
+
* try {
|
|
42
|
+
* return await next();
|
|
43
|
+
* } finally {
|
|
44
|
+
* this.logger.log({ request: context.requestName, ...buildFeatureFlagAttributes(context) });
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function buildFeatureFlagAttributes(context) {
|
|
50
|
+
const decision = getPipelineItem(context, FEATURE_FLAG_DECISION_ITEM_TOKEN);
|
|
51
|
+
if (!decision)
|
|
52
|
+
return {};
|
|
53
|
+
return {
|
|
54
|
+
'feature_flag.key': decision.flagKey,
|
|
55
|
+
'feature_flag.enabled': decision.enabled,
|
|
56
|
+
...(decision.variant ? { 'feature_flag.variant': decision.variant } : {}),
|
|
57
|
+
...(decision.reason ? { 'feature_flag.reason': decision.reason } : {}),
|
|
58
|
+
...(decision.errorCode
|
|
59
|
+
? { 'feature_flag.error_code': decision.errorCode }
|
|
60
|
+
: {}),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=build-attributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-attributes.js","sourceRoot":"","sources":["../../src/helpers/build-attributes.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,eAAe,EAAyB,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAAyB;IAEzB,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,gCAAgC,CAAC,CAAC;IAC5E,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzB,OAAO;QACL,kBAAkB,EAAE,QAAQ,CAAC,OAAO;QACpC,sBAAsB,EAAE,QAAQ,CAAC,OAAO;QACxC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,sBAAsB,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,qBAAqB,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,GAAG,CAAC,QAAQ,CAAC,SAAS;YACpB,CAAC,CAAC,EAAE,yBAAyB,EAAE,QAAQ,CAAC,SAAS,EAAE;YACnD,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IPipelineContext } from '@cqrs-ddd/pipeline';
|
|
2
|
+
import type { EvaluationContext } from '@openfeature/server-sdk';
|
|
3
|
+
import type { EvaluationContextFactory, TargetingKeyFactory } from '../interfaces/feature-flags-options.interface.js';
|
|
4
|
+
/**
|
|
5
|
+
* Base OpenFeature attributes derived from the live pipeline request. It sets no
|
|
6
|
+
* `targetingKey`; that comes from `targetingKeyFactory`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function baseEvaluationContext(context: IPipelineContext): EvaluationContext;
|
|
9
|
+
/**
|
|
10
|
+
* Builds an evaluation context in this order:
|
|
11
|
+
* base pipeline attributes → module context → handler context → targeting-key factory.
|
|
12
|
+
*
|
|
13
|
+
* A targeting key already provided by module/handler context is preserved when
|
|
14
|
+
* the factory returns `undefined`. A non-empty factory result wins when present.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildEvaluationContext(context: IPipelineContext, moduleContext?: EvaluationContext, handlerContext?: EvaluationContextFactory, targetingKeyFactory?: TargetingKeyFactory): EvaluationContext;
|
|
17
|
+
//# sourceMappingURL=evaluation-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluation-context.d.ts","sourceRoot":"","sources":["../../src/helpers/evaluation-context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EACV,wBAAwB,EACxB,mBAAmB,EACpB,MAAM,kDAAkD,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,gBAAgB,GACxB,iBAAiB,CAQnB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,gBAAgB,EACzB,aAAa,CAAC,EAAE,iBAAiB,EACjC,cAAc,CAAC,EAAE,wBAAwB,EACzC,mBAAmB,CAAC,EAAE,mBAAmB,GACxC,iBAAiB,CAWnB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
/**
|
|
3
|
+
* Base OpenFeature attributes derived from the live pipeline request. It sets no
|
|
4
|
+
* `targetingKey`; that comes from `targetingKeyFactory`.
|
|
5
|
+
*/
|
|
6
|
+
export function baseEvaluationContext(context) {
|
|
7
|
+
return {
|
|
8
|
+
'pipeline.request.kind': context.requestKind,
|
|
9
|
+
'pipeline.request.name': context.requestName,
|
|
10
|
+
'pipeline.handler.name': context.handlerName,
|
|
11
|
+
'pipeline.correlation_id': context.correlationId,
|
|
12
|
+
...(context.tenantId ? { 'pipeline.tenant_id': context.tenantId } : {}),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Builds an evaluation context in this order:
|
|
17
|
+
* base pipeline attributes → module context → handler context → targeting-key factory.
|
|
18
|
+
*
|
|
19
|
+
* A targeting key already provided by module/handler context is preserved when
|
|
20
|
+
* the factory returns `undefined`. A non-empty factory result wins when present.
|
|
21
|
+
*/
|
|
22
|
+
export function buildEvaluationContext(context, moduleContext, handlerContext, targetingKeyFactory) {
|
|
23
|
+
const result = {
|
|
24
|
+
...baseEvaluationContext(context),
|
|
25
|
+
...moduleContext,
|
|
26
|
+
...handlerContext?.(context),
|
|
27
|
+
};
|
|
28
|
+
const targetingKey = targetingKeyFactory?.(context)?.trim();
|
|
29
|
+
if (targetingKey)
|
|
30
|
+
result.targetingKey = targetingKey;
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=evaluation-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluation-context.js","sourceRoot":"","sources":["../../src/helpers/evaluation-context.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAStE;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAyB;IAEzB,OAAO;QACL,uBAAuB,EAAE,OAAO,CAAC,WAAW;QAC5C,uBAAuB,EAAE,OAAO,CAAC,WAAW;QAC5C,uBAAuB,EAAE,OAAO,CAAC,WAAW;QAC5C,yBAAyB,EAAE,OAAO,CAAC,aAAa;QAChD,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxE,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAyB,EACzB,aAAiC,EACjC,cAAyC,EACzC,mBAAyC;IAEzC,MAAM,MAAM,GAAsB;QAChC,GAAG,qBAAqB,CAAC,OAAO,CAAC;QACjC,GAAG,aAAa;QAChB,GAAG,cAAc,EAAE,CAAC,OAAO,CAAC;KAC7B,CAAC;IAEF,MAAM,YAAY,GAAG,mBAAmB,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;IAC5D,IAAI,YAAY;QAAE,MAAM,CAAC,YAAY,GAAG,YAAY,CAAC;IAErD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type Client } from '@openfeature/server-sdk';
|
|
2
|
+
import type { FeatureFlagClientOptions } from '../interfaces/feature-flags-options.interface.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resolves the OpenFeature client a {@link FeatureFlagBehavior} evaluates with: the given
|
|
5
|
+
* `client`, or the client of `domain` (the default client without one) after registering
|
|
6
|
+
* `provider`, waiting for it to be ready unless `waitForReady` is `false`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const client = await createFeatureFlagClient({ provider: new UnleashProvider(config) });
|
|
11
|
+
* const behavior = new FeatureFlagBehavior(client);
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function createFeatureFlagClient(options?: FeatureFlagClientOptions): Promise<Client>;
|
|
15
|
+
/**
|
|
16
|
+
* Unregisters the provider that {@link createFeatureFlagClient} registered for the same
|
|
17
|
+
* `options`, for shutdown: the domain falls back to OpenFeature's no-op provider. Does
|
|
18
|
+
* nothing when `options` gave a `client`, gave no `provider`, or another provider has
|
|
19
|
+
* replaced it since.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* process.on('SIGTERM', () => releaseFeatureFlagProvider(options));
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function releaseFeatureFlagProvider(options?: FeatureFlagClientOptions): Promise<void>;
|
|
27
|
+
//# sourceMappingURL=feature-flag-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-flag-client.d.ts","sourceRoot":"","sources":["../../src/helpers/feature-flag-client.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,MAAM,EAGZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kDAAkD,CAAC;AAEjG;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,IAAI,CAAC,CAUf"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
import { NOOP_PROVIDER, OpenFeature, } from '@openfeature/server-sdk';
|
|
3
|
+
/**
|
|
4
|
+
* Resolves the OpenFeature client a {@link FeatureFlagBehavior} evaluates with: the given
|
|
5
|
+
* `client`, or the client of `domain` (the default client without one) after registering
|
|
6
|
+
* `provider`, waiting for it to be ready unless `waitForReady` is `false`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const client = await createFeatureFlagClient({ provider: new UnleashProvider(config) });
|
|
11
|
+
* const behavior = new FeatureFlagBehavior(client);
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export async function createFeatureFlagClient(options = {}) {
|
|
15
|
+
if (options.client)
|
|
16
|
+
return options.client;
|
|
17
|
+
if (options.provider) {
|
|
18
|
+
if (options.waitForReady === false) {
|
|
19
|
+
options.domain
|
|
20
|
+
? OpenFeature.setProvider(options.domain, options.provider)
|
|
21
|
+
: OpenFeature.setProvider(options.provider);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
await (options.domain
|
|
25
|
+
? OpenFeature.setProviderAndWait(options.domain, options.provider)
|
|
26
|
+
: OpenFeature.setProviderAndWait(options.provider));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return options.domain
|
|
30
|
+
? OpenFeature.getClient(options.domain)
|
|
31
|
+
: OpenFeature.getClient();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Unregisters the provider that {@link createFeatureFlagClient} registered for the same
|
|
35
|
+
* `options`, for shutdown: the domain falls back to OpenFeature's no-op provider. Does
|
|
36
|
+
* nothing when `options` gave a `client`, gave no `provider`, or another provider has
|
|
37
|
+
* replaced it since.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* process.on('SIGTERM', () => releaseFeatureFlagProvider(options));
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export async function releaseFeatureFlagProvider(options = {}) {
|
|
45
|
+
const { client, provider, domain } = options;
|
|
46
|
+
if (client || !provider)
|
|
47
|
+
return;
|
|
48
|
+
const current = domain
|
|
49
|
+
? OpenFeature.getProvider(domain)
|
|
50
|
+
: OpenFeature.getProvider();
|
|
51
|
+
if (current !== provider)
|
|
52
|
+
return;
|
|
53
|
+
await (domain
|
|
54
|
+
? OpenFeature.setProviderAndWait(domain, NOOP_PROVIDER)
|
|
55
|
+
: OpenFeature.setProviderAndWait(NOOP_PROVIDER));
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=feature-flag-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-flag-client.js","sourceRoot":"","sources":["../../src/helpers/feature-flag-client.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAEL,aAAa,EACb,WAAW,GACZ,MAAM,yBAAyB,CAAC;AAGjC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAO,GAA6B,EAAE;IAEtC,IAAI,OAAO,CAAC,MAAM;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC;IAC1C,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,IAAI,OAAO,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;YACnC,OAAO,CAAC,MAAM;gBACZ,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC;gBAC3D,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,OAAO,CAAC,MAAM;gBACnB,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC;gBAClE,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC,MAAM;QACnB,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;QACvC,CAAC,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,OAAO,GAA6B,EAAE;IAEtC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC7C,IAAI,MAAM,IAAI,CAAC,QAAQ;QAAE,OAAO;IAChC,MAAM,OAAO,GAAG,MAAM;QACpB,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC;QACjC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;IAC9B,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO;IACjC,MAAM,CAAC,MAAM;QACX,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,MAAM,EAAE,aAAa,CAAC;QACvD,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PipelineBehaviorTuple } from '@cqrs-ddd/pipeline';
|
|
2
|
+
import { FeatureFlagBehavior } from '../feature-flag.behavior.js';
|
|
3
|
+
import type { FeatureFlagBehaviorOptions } from '../interfaces/feature-flags-options.interface.js';
|
|
4
|
+
export type FeatureFlagIntentOptions = FeatureFlagBehaviorOptions & {
|
|
5
|
+
flag: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Returns a feature-flag behavior entry for `pipeline.wrap()` or `createPipeline({ globalBehaviors })`.
|
|
9
|
+
* @param options Required flag key plus evaluation and fallback options.
|
|
10
|
+
* @returns The behavior class and options tuple. A disabled flag prevents handler
|
|
11
|
+
* execution; the behavior returns the configured fallback or throws FeatureDisabledError.
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* @pipeline.wrap({ kind: 'command' }, featureFlag({
|
|
15
|
+
* flag: 'user-registration',
|
|
16
|
+
* defaultValue: false,
|
|
17
|
+
* fallback: () => ({ disabled: true }),
|
|
18
|
+
* }))
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function featureFlag(options: FeatureFlagIntentOptions): PipelineBehaviorTuple<FeatureFlagBehavior, FeatureFlagBehaviorOptions>;
|
|
22
|
+
//# sourceMappingURL=feature-flag.intent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-flag.intent.d.ts","sourceRoot":"","sources":["../../src/helpers/feature-flag.intent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kDAAkD,CAAC;AAEnG,MAAM,MAAM,wBAAwB,GAAG,0BAA0B,GAAG;IAClE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,wBAAwB,GAChC,qBAAqB,CAAC,mBAAmB,EAAE,0BAA0B,CAAC,CAExE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
import { FeatureFlagBehavior } from '../feature-flag.behavior.js';
|
|
3
|
+
/**
|
|
4
|
+
* Returns a feature-flag behavior entry for `pipeline.wrap()` or `createPipeline({ globalBehaviors })`.
|
|
5
|
+
* @param options Required flag key plus evaluation and fallback options.
|
|
6
|
+
* @returns The behavior class and options tuple. A disabled flag prevents handler
|
|
7
|
+
* execution; the behavior returns the configured fallback or throws FeatureDisabledError.
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* @pipeline.wrap({ kind: 'command' }, featureFlag({
|
|
11
|
+
* flag: 'user-registration',
|
|
12
|
+
* defaultValue: false,
|
|
13
|
+
* fallback: () => ({ disabled: true }),
|
|
14
|
+
* }))
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export function featureFlag(options) {
|
|
18
|
+
return [FeatureFlagBehavior, options];
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=feature-flag.intent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-flag.intent.js","sourceRoot":"","sources":["../../src/helpers/feature-flag.intent.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAGtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAOlE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CACzB,OAAiC;IAEjC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { FeatureDisabledError } from './errors/feature-disabled.error.js';
|
|
2
|
+
/** An HTTP answer for an error: status, JSON body and headers. */
|
|
3
|
+
export interface HttpResponse {
|
|
4
|
+
status: number;
|
|
5
|
+
body: Record<string, unknown>;
|
|
6
|
+
headers: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The HTTP answer for a {@link FeatureDisabledError}: `403 Forbidden` naming the flag, or
|
|
10
|
+
* with `hideFeature` a plain `404 Not Found` that does not reveal the feature exists.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const { status, body } = toHttpResponse(error, { hideFeature: true });
|
|
15
|
+
* res.status(status).json(body);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function toHttpResponse(error: FeatureDisabledError, options?: {
|
|
19
|
+
hideFeature?: boolean;
|
|
20
|
+
}): HttpResponse;
|
|
21
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE/E,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,oBAAoB,EAC3B,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,YAAY,CAkBd"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
/**
|
|
3
|
+
* The HTTP answer for a {@link FeatureDisabledError}: `403 Forbidden` naming the flag, or
|
|
4
|
+
* with `hideFeature` a plain `404 Not Found` that does not reveal the feature exists.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const { status, body } = toHttpResponse(error, { hideFeature: true });
|
|
9
|
+
* res.status(status).json(body);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export function toHttpResponse(error, options = {}) {
|
|
13
|
+
if (options.hideFeature) {
|
|
14
|
+
return {
|
|
15
|
+
status: 404,
|
|
16
|
+
body: { statusCode: 404, error: 'Not Found', message: 'Not Found' },
|
|
17
|
+
headers: {},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
status: 403,
|
|
22
|
+
body: {
|
|
23
|
+
statusCode: 403,
|
|
24
|
+
error: 'Forbidden',
|
|
25
|
+
message: error.message,
|
|
26
|
+
flag: error.flag,
|
|
27
|
+
},
|
|
28
|
+
headers: {},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAWtE;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAC5B,KAA2B,EAC3B,OAAO,GAA8B,EAAE;IAEvC,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,OAAO;YACL,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE;YACnE,OAAO,EAAE,EAAE;SACZ,CAAC;IACJ,CAAC;IACD,OAAO;QACL,MAAM,EAAE,GAAG;QACX,IAAI,EAAE;YACJ,UAAU,EAAE,GAAG;YACf,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB;QACD,OAAO,EAAE,EAAE;KACZ,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenFeature gates for wrapped functions and methods: the behavior, the client factory and `featureFlag()`. The HTTP mapping of its errors is the `@cqrs-ddd/pipeline-feature-flags/http` entry point.
|
|
3
|
+
*
|
|
4
|
+
* @module main
|
|
5
|
+
*/
|
|
6
|
+
export { FeatureDisabledError } from './errors/feature-disabled.error.js';
|
|
7
|
+
export { FeatureFlagEvaluationError } from './errors/feature-flag-evaluation.error.js';
|
|
8
|
+
export { FEATURE_FLAG_DECISION_ITEM, FEATURE_FLAG_DECISION_ITEM_TOKEN, FEATURE_FLAG_ITEM, FEATURE_FLAG_ITEM_TOKEN, FEATURE_FLAG_KEY_ITEM, FEATURE_FLAG_KEY_ITEM_TOKEN, FeatureFlagBehavior, } from './feature-flag.behavior.js';
|
|
9
|
+
export { buildFeatureFlagAttributes } from './helpers/build-attributes.js';
|
|
10
|
+
export { baseEvaluationContext, buildEvaluationContext, } from './helpers/evaluation-context.js';
|
|
11
|
+
export { type FeatureFlagIntentOptions, featureFlag, } from './helpers/feature-flag.intent.js';
|
|
12
|
+
export { createFeatureFlagClient, releaseFeatureFlagProvider, } from './helpers/feature-flag-client.js';
|
|
13
|
+
export type { EvaluationContextFactory, FeatureFallbackFactory, FeatureFlagBehaviorOptions, FeatureFlagClientOptions, FeatureFlagDecision, FeatureFlagErrorPolicy, TargetingKeyFactory, } from './interfaces/feature-flags-options.interface.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AACvF,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,EAChC,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,KAAK,wBAAwB,EAC7B,WAAW,GACZ,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,kCAAkC,CAAC;AAC1C,YAAY,EACV,wBAAwB,EACxB,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,iDAAiD,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
/**
|
|
3
|
+
* OpenFeature gates for wrapped functions and methods: the behavior, the client factory and `featureFlag()`. The HTTP mapping of its errors is the `@cqrs-ddd/pipeline-feature-flags/http` entry point.
|
|
4
|
+
*
|
|
5
|
+
* @module main
|
|
6
|
+
*/
|
|
7
|
+
export { FeatureDisabledError } from './errors/feature-disabled.error.js';
|
|
8
|
+
export { FeatureFlagEvaluationError } from './errors/feature-flag-evaluation.error.js';
|
|
9
|
+
export { FEATURE_FLAG_DECISION_ITEM, FEATURE_FLAG_DECISION_ITEM_TOKEN, FEATURE_FLAG_ITEM, FEATURE_FLAG_ITEM_TOKEN, FEATURE_FLAG_KEY_ITEM, FEATURE_FLAG_KEY_ITEM_TOKEN, FeatureFlagBehavior, } from './feature-flag.behavior.js';
|
|
10
|
+
export { buildFeatureFlagAttributes } from './helpers/build-attributes.js';
|
|
11
|
+
export { baseEvaluationContext, buildEvaluationContext, } from './helpers/evaluation-context.js';
|
|
12
|
+
export { featureFlag, } from './helpers/feature-flag.intent.js';
|
|
13
|
+
export { createFeatureFlagClient, releaseFeatureFlagProvider, } from './helpers/feature-flag-client.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE;;;;GAIG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AACvF,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,EAChC,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEL,WAAW,GACZ,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { IPipelineContext } from '@cqrs-ddd/pipeline';
|
|
2
|
+
import type { Client, EvaluationContext, Provider } from '@openfeature/server-sdk';
|
|
3
|
+
/**
|
|
4
|
+
* Builds an OpenFeature {@link EvaluationContext} from the current pipeline
|
|
5
|
+
* request — letting flag targeting rules key off the live request/handler.
|
|
6
|
+
*/
|
|
7
|
+
export type EvaluationContextFactory = (context: IPipelineContext) => EvaluationContext;
|
|
8
|
+
/**
|
|
9
|
+
* Resolves a stable OpenFeature targeting key from the current pipeline request.
|
|
10
|
+
*
|
|
11
|
+
* For percentage rollouts this should normally be a user, account, tenant or
|
|
12
|
+
* device identifier that stays stable across requests.
|
|
13
|
+
*/
|
|
14
|
+
export type TargetingKeyFactory = (context: IPipelineContext) => string | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Returns a fallback value to emit when the gating flag is disabled, instead of
|
|
17
|
+
* throwing {@link FeatureDisabledError}. Receives the pipeline context so the
|
|
18
|
+
* fallback can be request-aware.
|
|
19
|
+
*/
|
|
20
|
+
export type FeatureFallbackFactory = (context: IPipelineContext) => unknown | Promise<unknown>;
|
|
21
|
+
/** Controls how OpenFeature provider evaluation failures are handled. */
|
|
22
|
+
export type FeatureFlagErrorPolicy = 'use-default' | 'throw';
|
|
23
|
+
/**
|
|
24
|
+
* Detailed result of a feature-flag evaluation, recorded on the pipeline
|
|
25
|
+
* context so logging/audit/telemetry or later behaviors can inspect the exact
|
|
26
|
+
* provider decision without re-evaluating the flag.
|
|
27
|
+
*/
|
|
28
|
+
export interface FeatureFlagDecision {
|
|
29
|
+
/** Evaluated OpenFeature flag key. */
|
|
30
|
+
flagKey: string;
|
|
31
|
+
/** Raw boolean value returned by OpenFeature (or its configured default value). */
|
|
32
|
+
value: boolean;
|
|
33
|
+
/** Final gate decision after optional variant filtering. */
|
|
34
|
+
enabled: boolean;
|
|
35
|
+
/** Provider-selected variant, when the provider reports one. */
|
|
36
|
+
variant?: string;
|
|
37
|
+
/** OpenFeature resolution reason, when reported by the provider. */
|
|
38
|
+
reason?: string;
|
|
39
|
+
/** OpenFeature provider error code, if evaluation failed. */
|
|
40
|
+
errorCode?: string;
|
|
41
|
+
/** Provider error message, if evaluation failed. */
|
|
42
|
+
errorMessage?: string;
|
|
43
|
+
/** Stable targeting key used for this evaluation, if one was supplied. */
|
|
44
|
+
targetingKey?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Per-handler feature-flag options, supplied through
|
|
48
|
+
* `pipeline.wrap(options, [FeatureFlagBehavior, options])` and/or as defaults,
|
|
49
|
+
* the second argument of the {@link FeatureFlagBehavior} constructor.
|
|
50
|
+
*/
|
|
51
|
+
export interface FeatureFlagBehaviorOptions {
|
|
52
|
+
/**
|
|
53
|
+
* Boolean flag key that gates the handler. When omitted the behavior is a
|
|
54
|
+
* no-op (the handler always runs) — useful for setting only constructor defaults.
|
|
55
|
+
*/
|
|
56
|
+
flag?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Value used when the flag cannot be resolved (provider error, unknown key,
|
|
59
|
+
* not yet ready). Defaults to `false` (fail-closed).
|
|
60
|
+
*/
|
|
61
|
+
defaultValue?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* When the flag resolves to disabled, return this value instead of throwing
|
|
64
|
+
* {@link FeatureDisabledError}. Use it to degrade gracefully, for example by
|
|
65
|
+
* returning an empty read model or another explicitly supported fallback.
|
|
66
|
+
*/
|
|
67
|
+
fallback?: FeatureFallbackFactory;
|
|
68
|
+
/**
|
|
69
|
+
* Builds extra OpenFeature targeting context for this handler, merged on top
|
|
70
|
+
* of the base context (derived from the request) and the constructor's context.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* @pipeline.wrap({ kind: 'command' }, [FeatureFlagBehavior, {
|
|
75
|
+
* flag: 'new-checkout',
|
|
76
|
+
* context: (ctx) => ({
|
|
77
|
+
* plan: ctx.items.get('plan') as string,
|
|
78
|
+
* country: ctx.items.get('country') as string,
|
|
79
|
+
* }),
|
|
80
|
+
* }])
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
context?: EvaluationContextFactory;
|
|
84
|
+
/**
|
|
85
|
+
* Stable identity used for percentage rollouts / sticky targeting.
|
|
86
|
+
*
|
|
87
|
+
* Handler-level `targetingKeyFactory` overrides the constructor's resolver.
|
|
88
|
+
* Correlation IDs are intentionally **not** used automatically because they
|
|
89
|
+
* normally change on every request and can move the same user between rollout
|
|
90
|
+
* cohorts.
|
|
91
|
+
*
|
|
92
|
+
* @example User-sticky rollout
|
|
93
|
+
* ```ts
|
|
94
|
+
* @pipeline.wrap({ kind: 'command' }, [FeatureFlagBehavior, {
|
|
95
|
+
* flag: 'new-checkout',
|
|
96
|
+
* targetingKeyFactory: (ctx) =>
|
|
97
|
+
* ctx.items.get('userId') as string | undefined,
|
|
98
|
+
* }])
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
targetingKeyFactory?: TargetingKeyFactory;
|
|
102
|
+
/**
|
|
103
|
+
* Optional allow-list of provider variants. When set, a boolean `true` only
|
|
104
|
+
* enables the handler if the provider also resolved one of these variants.
|
|
105
|
+
*
|
|
106
|
+
* This is useful when one boolean flag carries named cohorts such as
|
|
107
|
+
* `control`, `treatment-a`, and `treatment-b`.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* @pipeline.wrap({ kind: 'command' }, [FeatureFlagBehavior, {
|
|
112
|
+
* flag: 'checkout-experiment',
|
|
113
|
+
* allowedVariants: ['treatment-a'],
|
|
114
|
+
* }])
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
allowedVariants?: readonly string[];
|
|
118
|
+
/**
|
|
119
|
+
* Provider evaluation-error handling.
|
|
120
|
+
*
|
|
121
|
+
* - `use-default` — follow OpenFeature's default-value semantics and continue
|
|
122
|
+
* evaluating the final gate using `defaultValue` (default).
|
|
123
|
+
* - `throw` — surface {@link FeatureFlagEvaluationError} instead of silently
|
|
124
|
+
* treating a provider failure like an ordinary disabled flag.
|
|
125
|
+
*
|
|
126
|
+
* @default 'use-default'
|
|
127
|
+
*/
|
|
128
|
+
errorPolicy?: FeatureFlagErrorPolicy;
|
|
129
|
+
}
|
|
130
|
+
/** Where {@link createFeatureFlagClient} takes the OpenFeature client from. */
|
|
131
|
+
export interface FeatureFlagClientOptions {
|
|
132
|
+
/**
|
|
133
|
+
* Escape hatch: a fully constructed OpenFeature {@link Client}. Takes
|
|
134
|
+
* precedence over {@link provider}.
|
|
135
|
+
*/
|
|
136
|
+
client?: Client;
|
|
137
|
+
/**
|
|
138
|
+
* An OpenFeature {@link Provider} to register — e.g. an Unleash or Flagsmith
|
|
139
|
+
* provider. Registered with `setProviderAndWait`, or `setProvider` when
|
|
140
|
+
* {@link waitForReady} is `false`, before the client is resolved.
|
|
141
|
+
*/
|
|
142
|
+
provider?: Provider;
|
|
143
|
+
/**
|
|
144
|
+
* OpenFeature domain (named client) to bind the provider/client to. Lets you
|
|
145
|
+
* run multiple providers side by side. Defaults to the unnamed default client.
|
|
146
|
+
*/
|
|
147
|
+
domain?: string;
|
|
148
|
+
/**
|
|
149
|
+
* Whether to await provider readiness via `setProviderAndWait`. Defaults to
|
|
150
|
+
* `true`. Ignored when {@link client} is supplied.
|
|
151
|
+
*/
|
|
152
|
+
waitForReady?: boolean;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=feature-flags-options.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-flags-options.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/feature-flags-options.interface.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EACV,MAAM,EACN,iBAAiB,EACjB,QAAQ,EACT,MAAM,yBAAyB,CAAC;AAEjC;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,CACrC,OAAO,EAAE,gBAAgB,KACtB,iBAAiB,CAAC;AAEvB;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,gBAAgB,KACtB,MAAM,GAAG,SAAS,CAAC;AAExB;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACnC,OAAO,EAAE,gBAAgB,KACtB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,yEAAyE;AACzE,MAAM,MAAM,sBAAsB,GAAG,aAAa,GAAG,OAAO,CAAC;AAE7D;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,KAAK,EAAE,OAAO,CAAC;IACf,4DAA4D;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAElC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,wBAAwB,CAAC;IAEnC;;;;;;;;;;;;;;;;OAgBG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAE1C;;;;;;;;;;;;;;OAcG;IACH,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEpC;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,sBAAsB,CAAC;CACtC;AAED,+EAA+E;AAC/E,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-flags-options.interface.js","sourceRoot":"","sources":["../../src/interfaces/feature-flags-options.interface.ts"],"names":[],"mappings":"AAAA,sEAAsE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,70 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cqrs-ddd/pipeline-feature-flags",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Feature flags for @cqrs-ddd/pipeline through OpenFeature: an operation runs only while its flag is on",
|
|
5
|
+
"author": "Aristotelis",
|
|
6
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=22.12.0"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"pipeline",
|
|
13
|
+
"cqrs",
|
|
14
|
+
"feature-flags",
|
|
15
|
+
"feature-toggles",
|
|
16
|
+
"openfeature",
|
|
17
|
+
"unleash",
|
|
18
|
+
"flagsmith",
|
|
19
|
+
"behavior"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/aristoteliss/ddd-cqrs.git",
|
|
24
|
+
"directory": "packages/pipeline-feature-flags"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://aristoteliss.github.io/ddd-cqrs/packages/pipeline-feature-flags/",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/aristoteliss/ddd-cqrs/issues"
|
|
29
|
+
},
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"default": "./dist/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./http": {
|
|
36
|
+
"types": "./dist/http.d.ts",
|
|
37
|
+
"default": "./dist/http.js"
|
|
38
|
+
},
|
|
39
|
+
"./package.json": "./package.json"
|
|
40
|
+
},
|
|
41
|
+
"main": "dist/index.js",
|
|
42
|
+
"types": "dist/index.d.ts",
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"LICENSE",
|
|
46
|
+
"COMMERCIAL_LICENSE.txt"
|
|
47
|
+
],
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"@openfeature/server-sdk": "^1.13.0",
|
|
53
|
+
"@cqrs-ddd/pipeline": "^0.5.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@openfeature/server-sdk": "^1.23.0",
|
|
57
|
+
"@vitest/coverage-v8": "^5.0.3",
|
|
58
|
+
"vitest": "^5.0.3",
|
|
59
|
+
"@cqrs-ddd/pipeline": "0.5.0"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "tsc -p tsconfig.build.json",
|
|
63
|
+
"build:watch": "tsc -p tsconfig.build.json --watch",
|
|
64
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
65
|
+
"rebuild": "pnpm run clean && pnpm run build",
|
|
66
|
+
"lint": "tsc --noEmit",
|
|
67
|
+
"test": "vitest run",
|
|
68
|
+
"test:watch": "vitest"
|
|
69
|
+
}
|
|
6
70
|
}
|