@nebulr-group/bridge-auth-core 0.1.2 → 0.4.0-beta.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/billing/bridge-subscription.d.ts +71 -0
- package/dist/billing/bridge-subscription.d.ts.map +1 -0
- package/dist/billing/bridge-subscription.js +209 -0
- package/dist/billing/bridge-subscription.js.map +1 -0
- package/dist/billing/entitlements-store.d.ts +61 -0
- package/dist/billing/entitlements-store.d.ts.map +1 -0
- package/dist/billing/entitlements-store.js +127 -0
- package/dist/billing/entitlements-store.js.map +1 -0
- package/dist/billing/fetch-billing-state.d.ts +9 -0
- package/dist/billing/fetch-billing-state.d.ts.map +1 -0
- package/dist/billing/fetch-billing-state.js +22 -0
- package/dist/billing/fetch-billing-state.js.map +1 -0
- package/dist/billing/lock-signal.d.ts +6 -0
- package/dist/billing/lock-signal.d.ts.map +1 -0
- package/dist/billing/lock-signal.js +8 -0
- package/dist/billing/lock-signal.js.map +1 -0
- package/dist/billing/quota-store.d.ts +86 -0
- package/dist/billing/quota-store.d.ts.map +1 -0
- package/dist/billing/quota-store.js +180 -0
- package/dist/billing/quota-store.js.map +1 -0
- package/dist/billing/types.d.ts +64 -0
- package/dist/billing/types.d.ts.map +1 -0
- package/dist/billing/types.js +49 -0
- package/dist/billing/types.js.map +1 -0
- package/dist/billing/use-bridge.d.ts +131 -0
- package/dist/billing/use-bridge.d.ts.map +1 -0
- package/dist/billing/use-bridge.js +181 -0
- package/dist/billing/use-bridge.js.map +1 -0
- package/dist/bridge-auth.d.ts +36 -1
- package/dist/bridge-auth.d.ts.map +1 -1
- package/dist/bridge-auth.js +57 -3
- package/dist/bridge-auth.js.map +1 -1
- package/dist/direct-auth.d.ts +1 -0
- package/dist/direct-auth.d.ts.map +1 -1
- package/dist/direct-auth.js +7 -0
- package/dist/direct-auth.js.map +1 -1
- package/dist/errors.d.ts +11 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +14 -0
- package/dist/errors.js.map +1 -1
- package/dist/flags/attribute-providers.d.ts +229 -0
- package/dist/flags/attribute-providers.d.ts.map +1 -0
- package/dist/flags/attribute-providers.js +375 -0
- package/dist/flags/attribute-providers.js.map +1 -0
- package/dist/flags/dev-attribute-provider.d.ts +67 -0
- package/dist/flags/dev-attribute-provider.d.ts.map +1 -0
- package/dist/flags/dev-attribute-provider.js +200 -0
- package/dist/flags/dev-attribute-provider.js.map +1 -0
- package/dist/flags/evaluator.d.ts +58 -0
- package/dist/flags/evaluator.d.ts.map +1 -0
- package/dist/flags/evaluator.js +160 -0
- package/dist/flags/evaluator.js.map +1 -0
- package/dist/flags/flag.d.ts +199 -0
- package/dist/flags/flag.d.ts.map +1 -0
- package/dist/flags/flag.js +337 -0
- package/dist/flags/flag.js.map +1 -0
- package/dist/flags/identity.d.ts +77 -0
- package/dist/flags/identity.d.ts.map +1 -0
- package/dist/flags/identity.js +134 -0
- package/dist/flags/identity.js.map +1 -0
- package/dist/flags/index.d.ts +20 -0
- package/dist/flags/index.d.ts.map +1 -0
- package/dist/flags/index.js +21 -0
- package/dist/flags/index.js.map +1 -0
- package/dist/flags/operators.d.ts +63 -0
- package/dist/flags/operators.d.ts.map +1 -0
- package/dist/flags/operators.js +299 -0
- package/dist/flags/operators.js.map +1 -0
- package/dist/flags/propagation.d.ts +16 -0
- package/dist/flags/propagation.d.ts.map +1 -0
- package/dist/flags/propagation.js +107 -0
- package/dist/flags/propagation.js.map +1 -0
- package/dist/flags/realtime.d.ts +328 -0
- package/dist/flags/realtime.d.ts.map +1 -0
- package/dist/flags/realtime.js +504 -0
- package/dist/flags/realtime.js.map +1 -0
- package/dist/flags/runtime-mode.d.ts +32 -0
- package/dist/flags/runtime-mode.d.ts.map +1 -0
- package/dist/flags/runtime-mode.js +84 -0
- package/dist/flags/runtime-mode.js.map +1 -0
- package/dist/flags/telemetry.d.ts +79 -0
- package/dist/flags/telemetry.d.ts.map +1 -0
- package/dist/flags/telemetry.js +286 -0
- package/dist/flags/telemetry.js.map +1 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +11 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +14 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/management-types.d.ts +38 -0
- package/dist/management-types.d.ts.map +1 -1
- package/dist/route-guard.d.ts.map +1 -1
- package/dist/route-guard.js +15 -5
- package/dist/route-guard.js.map +1 -1
- package/dist/token-manager.d.ts +3 -1
- package/dist/token-manager.d.ts.map +1 -1
- package/dist/token-manager.js +10 -6
- package/dist/token-manager.js.map +1 -1
- package/dist/types.d.ts +10 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/usage/index.d.ts +3 -0
- package/dist/usage/index.d.ts.map +1 -0
- package/dist/usage/index.js +4 -0
- package/dist/usage/index.js.map +1 -0
- package/dist/usage/storage/durable-storage.d.ts +47 -0
- package/dist/usage/storage/durable-storage.d.ts.map +1 -0
- package/dist/usage/storage/durable-storage.js +27 -0
- package/dist/usage/storage/durable-storage.js.map +1 -0
- package/dist/usage/storage/index.d.ts +7 -0
- package/dist/usage/storage/index.d.ts.map +1 -0
- package/dist/usage/storage/index.js +28 -0
- package/dist/usage/storage/index.js.map +1 -0
- package/dist/usage/storage/indexeddb-storage.d.ts +18 -0
- package/dist/usage/storage/indexeddb-storage.d.ts.map +1 -0
- package/dist/usage/storage/indexeddb-storage.js +159 -0
- package/dist/usage/storage/indexeddb-storage.js.map +1 -0
- package/dist/usage/storage/node-fs-storage.d.ts +29 -0
- package/dist/usage/storage/node-fs-storage.d.ts.map +1 -0
- package/dist/usage/storage/node-fs-storage.js +180 -0
- package/dist/usage/storage/node-fs-storage.js.map +1 -0
- package/dist/usage/storage/noop-storage.d.ts +17 -0
- package/dist/usage/storage/noop-storage.d.ts.map +1 -0
- package/dist/usage/storage/noop-storage.js +67 -0
- package/dist/usage/storage/noop-storage.js.map +1 -0
- package/dist/usage/usage-reporter.d.ts +64 -0
- package/dist/usage/usage-reporter.d.ts.map +1 -0
- package/dist/usage/usage-reporter.js +234 -0
- package/dist/usage/usage-reporter.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-attribute-provider.js","sourceRoot":"","sources":["../../src/flags/dev-attribute-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { AttributeType, Condition, Operator } from './operators.js';
|
|
2
|
+
/** A branch is a list of conditions (AND-ed) + the value returned on match. */
|
|
3
|
+
export interface Branch {
|
|
4
|
+
conditions: Condition[];
|
|
5
|
+
returnValue: unknown;
|
|
6
|
+
}
|
|
7
|
+
export interface Rule {
|
|
8
|
+
/** First-match-wins. */
|
|
9
|
+
branches: Branch[];
|
|
10
|
+
/** Returned when no branch matches. */
|
|
11
|
+
otherwiseValue: unknown;
|
|
12
|
+
/** 0-100. Applies to the whole rule. */
|
|
13
|
+
rolloutPct: number;
|
|
14
|
+
/** When set, the flag uses a saved group's branches; `branches` is ignored. */
|
|
15
|
+
groupRef?: string;
|
|
16
|
+
}
|
|
17
|
+
export type FlagState = 'off' | 'on' | 'on-with-rule';
|
|
18
|
+
export interface EvalContext {
|
|
19
|
+
/** Stable per-eval identity. Required when rolloutPct < 100. */
|
|
20
|
+
identity?: string;
|
|
21
|
+
/** Flat or nested attribute map. */
|
|
22
|
+
attributes: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export interface EvalResult {
|
|
25
|
+
value: unknown;
|
|
26
|
+
/** Which branch fired, 0-indexed. -1 if otherwise was returned. */
|
|
27
|
+
variantIndex: number;
|
|
28
|
+
matched: boolean;
|
|
29
|
+
excludedByRollout: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve a dotted-path attribute name against the eval context.
|
|
33
|
+
* Tries the flat key first, then walks dots.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveAttribute(ctx: EvalContext, attribute: string): unknown;
|
|
36
|
+
/**
|
|
37
|
+
* 32-bit FNV-1a hash of `${flagKey}|${identity}` mod 100. Same bucket for same
|
|
38
|
+
* inputs across server and SDK. Used for rule-level rollout and (future)
|
|
39
|
+
* variant assignment in L: Experiments.
|
|
40
|
+
*/
|
|
41
|
+
export declare function bucket(flagKey: string, identity: string): number;
|
|
42
|
+
/** Evaluate a single branch's conditions against the context. AND between conditions. */
|
|
43
|
+
export declare function evaluateBranch(branch: Branch, ctx: EvalContext): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Evaluate a Rule (branches + otherwise + rollout). First-match-wins; rollout
|
|
46
|
+
* applies to the whole rule (excluded users fall through to otherwise).
|
|
47
|
+
*/
|
|
48
|
+
export declare function evaluateRule(rule: Rule, flagKey: string, ctx: EvalContext): EvalResult;
|
|
49
|
+
export interface RuleValidationError {
|
|
50
|
+
branchIndex: number;
|
|
51
|
+
conditionIndex: number;
|
|
52
|
+
attribute?: string;
|
|
53
|
+
operator?: string;
|
|
54
|
+
message: string;
|
|
55
|
+
}
|
|
56
|
+
export declare function validateRule(rule: Rule, attributeTypes?: Readonly<Record<string, AttributeType>>): RuleValidationError[];
|
|
57
|
+
export type { Operator, AttributeType, Condition };
|
|
58
|
+
//# sourceMappingURL=evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/flags/evaluator.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AASzE,+EAA+E;AAC/E,MAAM,WAAW,MAAM;IACrB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACnB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,uCAAuC;IACvC,cAAc,EAAE,OAAO,CAAC;IACxB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,cAAc,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAY7E;AAID;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQhE;AAID,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAGxE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,UAAU,CAwBtF;AAWD,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,wBAAgB,YAAY,CAC1B,IAAI,EAAE,IAAI,EACV,cAAc,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAM,GAC3D,mBAAmB,EAAE,CAsEvB;AAGD,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Bridge Feature Flags 2.0 rule evaluator.
|
|
2
|
+
//
|
|
3
|
+
// This module is the SINGLE SOURCE OF TRUTH for both:
|
|
4
|
+
// - bridge-api server-side eval
|
|
5
|
+
// - bridge-* SDK client-side eval
|
|
6
|
+
//
|
|
7
|
+
// Imports `evaluateCondition` from the operator module in the same package
|
|
8
|
+
// (./operators.js). Server-side bridge-api imports from
|
|
9
|
+
// `@nebulr-group/bridge-auth-core` and gets identical semantics.
|
|
10
|
+
//
|
|
11
|
+
// Companion module: ./operators.ts (operator set + per-condition eval +
|
|
12
|
+
// save-time validation). This file builds the rule layer (branches + rollout)
|
|
13
|
+
// on top of those primitives.
|
|
14
|
+
import { evaluateCondition } from './operators.js';
|
|
15
|
+
import { isOperator, isOperatorValidForType, validOperatorsForType, } from './operators.js';
|
|
16
|
+
// ── Attribute resolution ────────────────────────────────────────────────────
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a dotted-path attribute name against the eval context.
|
|
19
|
+
* Tries the flat key first, then walks dots.
|
|
20
|
+
*/
|
|
21
|
+
export function resolveAttribute(ctx, attribute) {
|
|
22
|
+
if (Object.prototype.hasOwnProperty.call(ctx.attributes, attribute)) {
|
|
23
|
+
return ctx.attributes[attribute];
|
|
24
|
+
}
|
|
25
|
+
const parts = attribute.split('.');
|
|
26
|
+
let current = ctx.attributes;
|
|
27
|
+
for (const part of parts) {
|
|
28
|
+
if (current === undefined || current === null)
|
|
29
|
+
return undefined;
|
|
30
|
+
if (typeof current !== 'object')
|
|
31
|
+
return undefined;
|
|
32
|
+
current = current[part];
|
|
33
|
+
}
|
|
34
|
+
return current;
|
|
35
|
+
}
|
|
36
|
+
// ── Stable hash bucketing ───────────────────────────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* 32-bit FNV-1a hash of `${flagKey}|${identity}` mod 100. Same bucket for same
|
|
39
|
+
* inputs across server and SDK. Used for rule-level rollout and (future)
|
|
40
|
+
* variant assignment in L: Experiments.
|
|
41
|
+
*/
|
|
42
|
+
export function bucket(flagKey, identity) {
|
|
43
|
+
const input = `${flagKey}|${identity}`;
|
|
44
|
+
let hash = 0x811c9dc5;
|
|
45
|
+
for (let i = 0; i < input.length; i++) {
|
|
46
|
+
hash ^= input.charCodeAt(i);
|
|
47
|
+
hash = (hash + (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24)) >>> 0;
|
|
48
|
+
}
|
|
49
|
+
return hash % 100;
|
|
50
|
+
}
|
|
51
|
+
// ── Branch + rule evaluation ────────────────────────────────────────────────
|
|
52
|
+
/** Evaluate a single branch's conditions against the context. AND between conditions. */
|
|
53
|
+
export function evaluateBranch(branch, ctx) {
|
|
54
|
+
if (!branch.conditions || branch.conditions.length === 0)
|
|
55
|
+
return false;
|
|
56
|
+
return branch.conditions.every((c) => evaluateCondition(c, resolveAttribute(ctx, c.attribute)));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Evaluate a Rule (branches + otherwise + rollout). First-match-wins; rollout
|
|
60
|
+
* applies to the whole rule (excluded users fall through to otherwise).
|
|
61
|
+
*/
|
|
62
|
+
export function evaluateRule(rule, flagKey, ctx) {
|
|
63
|
+
const rolloutPct = clampPct(rule.rolloutPct ?? 100);
|
|
64
|
+
if (rolloutPct < 100) {
|
|
65
|
+
if (!ctx.identity) {
|
|
66
|
+
return { value: rule.otherwiseValue, variantIndex: -1, matched: false, excludedByRollout: true };
|
|
67
|
+
}
|
|
68
|
+
if (bucket(flagKey, ctx.identity) >= rolloutPct) {
|
|
69
|
+
return { value: rule.otherwiseValue, variantIndex: -1, matched: false, excludedByRollout: true };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const branches = rule.branches ?? [];
|
|
73
|
+
for (let i = 0; i < branches.length; i++) {
|
|
74
|
+
if (evaluateBranch(branches[i], ctx)) {
|
|
75
|
+
return {
|
|
76
|
+
value: branches[i].returnValue,
|
|
77
|
+
variantIndex: i,
|
|
78
|
+
matched: true,
|
|
79
|
+
excludedByRollout: false,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return { value: rule.otherwiseValue, variantIndex: -1, matched: false, excludedByRollout: false };
|
|
84
|
+
}
|
|
85
|
+
function clampPct(p) {
|
|
86
|
+
if (!Number.isFinite(p))
|
|
87
|
+
return 100;
|
|
88
|
+
if (p < 0)
|
|
89
|
+
return 0;
|
|
90
|
+
if (p > 100)
|
|
91
|
+
return 100;
|
|
92
|
+
return p;
|
|
93
|
+
}
|
|
94
|
+
const RULE_CONDITIONS_HARD_MAX = 50;
|
|
95
|
+
export function validateRule(rule, attributeTypes = {}) {
|
|
96
|
+
const errors = [];
|
|
97
|
+
if (!rule || typeof rule !== 'object') {
|
|
98
|
+
return [{ branchIndex: -1, conditionIndex: -1, message: 'Rule must be an object.' }];
|
|
99
|
+
}
|
|
100
|
+
const branches = rule.branches ?? [];
|
|
101
|
+
let totalConditions = 0;
|
|
102
|
+
branches.forEach((branch, bi) => {
|
|
103
|
+
if (!branch.conditions || branch.conditions.length === 0) {
|
|
104
|
+
errors.push({
|
|
105
|
+
branchIndex: bi,
|
|
106
|
+
conditionIndex: -1,
|
|
107
|
+
message: `Branch ${bi} has no conditions.`,
|
|
108
|
+
});
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
branch.conditions.forEach((c, ci) => {
|
|
112
|
+
totalConditions++;
|
|
113
|
+
if (!isOperator(c.operator)) {
|
|
114
|
+
errors.push({
|
|
115
|
+
branchIndex: bi,
|
|
116
|
+
conditionIndex: ci,
|
|
117
|
+
attribute: c.attribute,
|
|
118
|
+
operator: c.operator,
|
|
119
|
+
message: `Unknown operator "${c.operator}".`,
|
|
120
|
+
});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const opType = attributeTypes[c.attribute];
|
|
124
|
+
if (opType && !isOperatorValidForType(c.operator, opType)) {
|
|
125
|
+
errors.push({
|
|
126
|
+
branchIndex: bi,
|
|
127
|
+
conditionIndex: ci,
|
|
128
|
+
attribute: c.attribute,
|
|
129
|
+
operator: c.operator,
|
|
130
|
+
message: `Operator "${c.operator}" not valid for type ${opType}. Valid: ${validOperatorsForType(opType).join(', ')}.`,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
if (totalConditions > RULE_CONDITIONS_HARD_MAX) {
|
|
136
|
+
errors.push({
|
|
137
|
+
branchIndex: -1,
|
|
138
|
+
conditionIndex: -1,
|
|
139
|
+
message: `Rule has ${totalConditions} conditions; max is ${RULE_CONDITIONS_HARD_MAX}.`,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
if (rule.rolloutPct !== undefined) {
|
|
143
|
+
if (typeof rule.rolloutPct !== 'number' || rule.rolloutPct < 0 || rule.rolloutPct > 100) {
|
|
144
|
+
errors.push({
|
|
145
|
+
branchIndex: -1,
|
|
146
|
+
conditionIndex: -1,
|
|
147
|
+
message: `rolloutPct must be a number in [0, 100], got ${rule.rolloutPct}.`,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (rule.groupRef && branches.length > 0) {
|
|
152
|
+
errors.push({
|
|
153
|
+
branchIndex: -1,
|
|
154
|
+
conditionIndex: -1,
|
|
155
|
+
message: 'Rule cannot have both an inline `branches` and a `groupRef`.',
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return errors;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=evaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator.js","sourceRoot":"","sources":["../../src/flags/evaluator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { type EvalContext, type Rule, type FlagState } from './evaluator.js';
|
|
2
|
+
import { AttributeProviderRegistry, type AttributeProvider } from './attribute-providers.js';
|
|
3
|
+
/**
|
|
4
|
+
* The attribute types the SDK and admin UI both understand. `semver` is a
|
|
5
|
+
* commonly-needed string subtype that powers `app_version > 4.12` style rules;
|
|
6
|
+
* runtime evaluation treats it as a string with regex-friendly comparators.
|
|
7
|
+
*/
|
|
8
|
+
export type DeclaredAttributeType = 'string' | 'number' | 'boolean' | 'date' | 'semver' | 'json';
|
|
9
|
+
export interface AttributeDeclaration {
|
|
10
|
+
name: string;
|
|
11
|
+
type: DeclaredAttributeType;
|
|
12
|
+
/** Unix-ms when this declaration was made. */
|
|
13
|
+
timestamp: number;
|
|
14
|
+
}
|
|
15
|
+
export type FlagValueType = 'boolean' | 'string' | 'number' | 'json';
|
|
16
|
+
export interface CachedFlag {
|
|
17
|
+
key: string;
|
|
18
|
+
state: FlagState;
|
|
19
|
+
valueType: FlagValueType;
|
|
20
|
+
offValue: unknown;
|
|
21
|
+
onValue: unknown;
|
|
22
|
+
rule?: Rule;
|
|
23
|
+
}
|
|
24
|
+
export interface EvalTelemetry {
|
|
25
|
+
flag: string;
|
|
26
|
+
value: unknown;
|
|
27
|
+
variantIndex: number;
|
|
28
|
+
identity?: string;
|
|
29
|
+
/** Unix-ms when this eval happened. */
|
|
30
|
+
timestamp: number;
|
|
31
|
+
/** Optional opaque fingerprint of the call site (TBP-156). */
|
|
32
|
+
callSiteFingerprint?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface DiscoveryTelemetry {
|
|
35
|
+
flag: string;
|
|
36
|
+
defaultValue: unknown;
|
|
37
|
+
observedType: FlagValueType;
|
|
38
|
+
timestamp: number;
|
|
39
|
+
}
|
|
40
|
+
export interface AttributeObservation {
|
|
41
|
+
/** Attribute key as the dev supplied it (e.g. 'country', 'myapp:foo'). */
|
|
42
|
+
key: string;
|
|
43
|
+
/** The sample value observed for the key in this eval. */
|
|
44
|
+
sampleValue: unknown;
|
|
45
|
+
/** Inferred type — fed into discovery so the admin UI gets a sensible picker. */
|
|
46
|
+
observedType: FlagValueType;
|
|
47
|
+
timestamp: number;
|
|
48
|
+
}
|
|
49
|
+
export interface BridgeFlagsHooks {
|
|
50
|
+
/** Called on every successful eval. Should not throw. */
|
|
51
|
+
onEval?: (ev: EvalTelemetry) => void;
|
|
52
|
+
/** Called the first time the SDK sees an unknown flag key. */
|
|
53
|
+
onDiscover?: (ev: DiscoveryTelemetry) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Called once per distinct (key, sampleValue) seen in `bridge.flag()`
|
|
56
|
+
* per-call `context.attributes`. The batcher relays this to
|
|
57
|
+
* `/v1/flags/discover` with `kind: 'attribute'` so the admin UI's attribute
|
|
58
|
+
* catalog shows what dev code actually supplies.
|
|
59
|
+
*/
|
|
60
|
+
onAttributeObserved?: (ev: AttributeObservation) => void;
|
|
61
|
+
/**
|
|
62
|
+
* @deprecated Use per-call `bridge.flag(key, default, { attributes: {...} })`
|
|
63
|
+
* instead — per-call observations now feed the admin attribute catalog
|
|
64
|
+
* automatically via `onAttributeObserved`. `declareAttributes()` will be
|
|
65
|
+
* removed in a future minor release.
|
|
66
|
+
*/
|
|
67
|
+
onAttributeDeclaration?: (decl: AttributeDeclaration) => void;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The result of a flag evaluation. `passed` is true when a targeting rule (or
|
|
71
|
+
* global on) resolved this flag to its on-value; false when the flag is off,
|
|
72
|
+
* no rule matched, or the flag isn't in the cache yet. `value` is always the
|
|
73
|
+
* Bridge-decided value — the on-value when passed, the off/default value when not.
|
|
74
|
+
*/
|
|
75
|
+
export interface FlagEvalResult<T> {
|
|
76
|
+
passed: boolean;
|
|
77
|
+
value: T;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* BridgeFlags — the SDK-side flag cache + eval entry point. Most apps see
|
|
81
|
+
* exactly one instance, wired up at bootstrap time. Tests construct their
|
|
82
|
+
* own instances directly.
|
|
83
|
+
*/
|
|
84
|
+
/**
|
|
85
|
+
* Runtime mode for the SDK. Backends (Node servers) opt into `'backend'` to
|
|
86
|
+
* disable auto-anonymous identity — per locked decision #27, backend evals
|
|
87
|
+
* with no identity refuse to bucket rolled-out rules and return the safe
|
|
88
|
+
* default. Frontends use `'frontend'` (the default).
|
|
89
|
+
*/
|
|
90
|
+
export type BridgeFlagsMode = 'frontend' | 'backend';
|
|
91
|
+
/**
|
|
92
|
+
* Minimal shape of the SDK's usage reporter — kept narrow so `BridgeFlags`
|
|
93
|
+
* doesn't depend on the full `UsageReporter` class. Framework wrappers pass
|
|
94
|
+
* `bridge.usage` (which has the same `report(metric, value?)` signature).
|
|
95
|
+
*/
|
|
96
|
+
export interface FlagUsageReporterLike {
|
|
97
|
+
report(metric: string, value?: number): void;
|
|
98
|
+
}
|
|
99
|
+
export declare class BridgeFlags {
|
|
100
|
+
private cache;
|
|
101
|
+
private context;
|
|
102
|
+
private hooks;
|
|
103
|
+
private discoveredKeys;
|
|
104
|
+
/** Per-runtime dedup for attribute observations: `${key}::${canonicalValue}`. */
|
|
105
|
+
private observedAttributeKeys;
|
|
106
|
+
private attributeDeclarations;
|
|
107
|
+
private mode;
|
|
108
|
+
private serverInstanceIdValue?;
|
|
109
|
+
private missingIdentityWarned;
|
|
110
|
+
/** Billing 2.0 US-10 (TBP-262): self-report `bridge.flag_evaluations` per eval. */
|
|
111
|
+
private usageReporter?;
|
|
112
|
+
/**
|
|
113
|
+
* Phase 1 / US-13 (TBP-293, TBP-294) — AttributeProvider registry consulted
|
|
114
|
+
* on every flag eval. Bridge-managed providers (`bridge:auth`,
|
|
115
|
+
* `bridge:billing`) are auto-registered by framework SDKs; apps register
|
|
116
|
+
* their own providers via `registerAttributeProvider()`.
|
|
117
|
+
*/
|
|
118
|
+
private readonly registry;
|
|
119
|
+
constructor(options?: {
|
|
120
|
+
mode?: BridgeFlagsMode;
|
|
121
|
+
usageReporter?: FlagUsageReporterLike;
|
|
122
|
+
});
|
|
123
|
+
/**
|
|
124
|
+
* Register an `AttributeProvider`. Idempotent on `provider.name` —
|
|
125
|
+
* re-registering with the same name replaces the previous instance.
|
|
126
|
+
* Provider attributes flow into every `flag()` eval automatically.
|
|
127
|
+
* Dev-supplied attrs (via `setContext` / per-call `context`) win on
|
|
128
|
+
* collision (locked decision #20).
|
|
129
|
+
*/
|
|
130
|
+
registerAttributeProvider(provider: AttributeProvider): void;
|
|
131
|
+
/** Remove a previously-registered provider by name. No-op if not present. */
|
|
132
|
+
unregisterAttributeProvider(name: string): void;
|
|
133
|
+
/**
|
|
134
|
+
* Expose the registry for advanced callers (e.g. async `applyTo()` refreshes
|
|
135
|
+
* driven by framework auth events). Most consumers should prefer
|
|
136
|
+
* `registerAttributeProvider` / `unregisterAttributeProvider`.
|
|
137
|
+
*/
|
|
138
|
+
getAttributeProviderRegistry(): AttributeProviderRegistry;
|
|
139
|
+
/**
|
|
140
|
+
* Wire a usage reporter post-construction. The flag-eval path will call
|
|
141
|
+
* `reporter.report('bridge.flag_evaluations', 1)` on every successful eval
|
|
142
|
+
* (i.e. when a cached flag is present and evaluated). Discovery-only paths
|
|
143
|
+
* — first-sight unknown flag → default — do NOT count.
|
|
144
|
+
*/
|
|
145
|
+
setUsageReporter(reporter: FlagUsageReporterLike | undefined): void;
|
|
146
|
+
/** Read the active runtime mode. */
|
|
147
|
+
getMode(): BridgeFlagsMode;
|
|
148
|
+
/**
|
|
149
|
+
* Set a stable server-instance identity (TBP-172). When set, backend flags
|
|
150
|
+
* that explicitly opt into system-level targeting can bucket on this value
|
|
151
|
+
* (e.g. canary a feature to one specific instance). Most evals continue to
|
|
152
|
+
* use the per-call/per-context identity.
|
|
153
|
+
*/
|
|
154
|
+
setServerInstanceId(id: string): void;
|
|
155
|
+
/** Read the configured server-instance id, or undefined when not set. */
|
|
156
|
+
getServerInstanceId(): string | undefined;
|
|
157
|
+
/** Replace or merge the eval context. */
|
|
158
|
+
setContext(ctx: EvalContext, merge?: boolean): void;
|
|
159
|
+
/** Return a defensive shallow copy of the current eval context. */
|
|
160
|
+
getContext(): EvalContext;
|
|
161
|
+
/** Replace the cache from a bulk hydrate (e.g. response from bridge-api). */
|
|
162
|
+
hydrate(flags: CachedFlag[]): void;
|
|
163
|
+
/** Replace or insert a single flag (used by live updates). */
|
|
164
|
+
upsert(flag: CachedFlag): void;
|
|
165
|
+
/** Remove a flag from the cache. */
|
|
166
|
+
remove(key: string): void;
|
|
167
|
+
/** Register telemetry hooks. Replaces any previous hooks. */
|
|
168
|
+
setHooks(hooks: BridgeFlagsHooks): void;
|
|
169
|
+
/**
|
|
170
|
+
* Read a flag value. Returns `defaultValue` when the flag isn't known yet.
|
|
171
|
+
* TypeScript infers `T` from `defaultValue`, so callers don't write casts.
|
|
172
|
+
*
|
|
173
|
+
* An optional per-call `context` overrides the SDK's global context for
|
|
174
|
+
* just this eval. Attributes deep-merge — per-call wins on overlap, global
|
|
175
|
+
* keys not in the override are preserved.
|
|
176
|
+
*/
|
|
177
|
+
flag<T>(key: string, defaultValue: T, context?: Partial<EvalContext>): FlagEvalResult<T>;
|
|
178
|
+
/**
|
|
179
|
+
* Internal — evaluate the cached flag against an eval context.
|
|
180
|
+
*/
|
|
181
|
+
private evaluateCached;
|
|
182
|
+
/** Number of cached flags. Useful for debugging + tests. */
|
|
183
|
+
cacheSize(): number;
|
|
184
|
+
/** Get a snapshot of cached flag keys. */
|
|
185
|
+
cachedKeys(): string[];
|
|
186
|
+
/**
|
|
187
|
+
* @deprecated Per-call observations now power the admin attribute catalog
|
|
188
|
+
* automatically — just pass attributes when you evaluate a flag:
|
|
189
|
+
* `bridge.flag('feat', false, { attributes: { plan: 'pro' } })`.
|
|
190
|
+
* The SDK reports each `(key, sampleValue)` once via `onAttributeObserved`,
|
|
191
|
+
* which the batcher relays to `/v1/flags/discover` with `kind: 'attribute'`.
|
|
192
|
+
* `declareAttributes()` will be removed in a future minor release.
|
|
193
|
+
*/
|
|
194
|
+
declareAttributes(declarations: Record<string, DeclaredAttributeType>): void;
|
|
195
|
+
/** Read the current attribute type declarations. Useful for tests + framework wrappers. */
|
|
196
|
+
getAttributeDeclarations(): Record<string, DeclaredAttributeType>;
|
|
197
|
+
private safeHook;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=flag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flag.d.ts","sourceRoot":"","sources":["../../src/flags/flag.ts"],"names":[],"mappings":"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"}
|