@nebulr-group/bridge-auth-core 0.8.0-beta.2 → 0.8.0-beta.4

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 (51) hide show
  1. package/dist/billing/quota-store.d.ts +27 -0
  2. package/dist/billing/quota-store.d.ts.map +1 -1
  3. package/dist/billing/quota-store.js +114 -23
  4. package/dist/billing/quota-store.js.map +1 -1
  5. package/dist/billing/use-bridge.d.ts +7 -0
  6. package/dist/billing/use-bridge.d.ts.map +1 -1
  7. package/dist/billing/use-bridge.js +12 -0
  8. package/dist/billing/use-bridge.js.map +1 -1
  9. package/dist/bridge-auth.d.ts.map +1 -1
  10. package/dist/bridge-auth.js +10 -4
  11. package/dist/bridge-auth.js.map +1 -1
  12. package/dist/feature-flag-service.d.ts +16 -0
  13. package/dist/feature-flag-service.d.ts.map +1 -1
  14. package/dist/feature-flag-service.js +33 -0
  15. package/dist/feature-flag-service.js.map +1 -1
  16. package/dist/flags/attribute-providers.d.ts +52 -0
  17. package/dist/flags/attribute-providers.d.ts.map +1 -1
  18. package/dist/flags/attribute-providers.js +105 -67
  19. package/dist/flags/attribute-providers.js.map +1 -1
  20. package/dist/flags/evaluator.d.ts +36 -0
  21. package/dist/flags/evaluator.d.ts.map +1 -1
  22. package/dist/flags/evaluator.js +98 -7
  23. package/dist/flags/evaluator.js.map +1 -1
  24. package/dist/flags/flag.d.ts +11 -1
  25. package/dist/flags/flag.d.ts.map +1 -1
  26. package/dist/flags/flag.js +9 -1
  27. package/dist/flags/flag.js.map +1 -1
  28. package/dist/flags/index.d.ts +4 -4
  29. package/dist/flags/index.d.ts.map +1 -1
  30. package/dist/flags/index.js +2 -2
  31. package/dist/flags/index.js.map +1 -1
  32. package/dist/flags/operators.d.ts +3 -0
  33. package/dist/flags/operators.d.ts.map +1 -1
  34. package/dist/flags/operators.js +26 -0
  35. package/dist/flags/operators.js.map +1 -1
  36. package/dist/index.d.ts +4 -4
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +1 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/management-types.d.ts +20 -0
  41. package/dist/management-types.d.ts.map +1 -1
  42. package/dist/route-guard.d.ts.map +1 -1
  43. package/dist/route-guard.js +62 -18
  44. package/dist/route-guard.js.map +1 -1
  45. package/dist/types.d.ts +33 -0
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/usage/usage-reporter.d.ts +11 -0
  48. package/dist/usage/usage-reporter.d.ts.map +1 -1
  49. package/dist/usage/usage-reporter.js +17 -0
  50. package/dist/usage/usage-reporter.js.map +1 -1
  51. package/package.json +1 -1
@@ -1,10 +1,24 @@
1
1
  import { httpFetch } from './http.js';
2
+ const OFF_REASONS = new Set(['plan', 'permission', 'off', 'rule', 'rollout']);
3
+ /** The explanation in an evaluation, or undefined when the server sent none. */
4
+ function readExplanation(evaluation) {
5
+ if (!evaluation || typeof evaluation !== 'object')
6
+ return undefined;
7
+ const e = evaluation;
8
+ if (typeof e.reason !== 'string' || !OFF_REASONS.has(e.reason))
9
+ return undefined;
10
+ return {
11
+ reason: e.reason,
12
+ ...(typeof e.feature === 'string' && e.feature ? { feature: e.feature } : {}),
13
+ };
14
+ }
2
15
  const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
3
16
  export class FeatureFlagService {
4
17
  config;
5
18
  getTokens;
6
19
  logger;
7
20
  cachedFlags = {};
21
+ cachedReasons = {};
8
22
  lastFetchTime = 0;
9
23
  constructor(config, getTokens, logger) {
10
24
  this.config = config;
@@ -17,10 +31,15 @@ export class FeatureFlagService {
17
31
  const url = `${this.config.apiBaseUrl}/cloud-views/flags/bulkEvaluate/${this.config.appId}`;
18
32
  const body = accessToken ? { accessToken } : {};
19
33
  const data = await httpFetch(url, { method: 'POST', body }, this.logger);
34
+ const reasons = {};
20
35
  this.cachedFlags = data.flags.reduce((acc, { flag, evaluation }) => {
21
36
  acc[flag] = evaluation?.enabled ?? false;
37
+ const explanation = acc[flag] ? undefined : readExplanation(evaluation);
38
+ if (explanation)
39
+ reasons[flag] = explanation;
22
40
  return acc;
23
41
  }, {});
42
+ this.cachedReasons = reasons;
24
43
  this.lastFetchTime = Date.now();
25
44
  return { ...this.cachedFlags };
26
45
  }
@@ -38,6 +57,15 @@ export class FeatureFlagService {
38
57
  getCached() {
39
58
  return { ...this.cachedFlags };
40
59
  }
60
+ /**
61
+ * TBP-756 — why `flag` was off at its last evaluation, or undefined when it
62
+ * was on, is unknown, or the server did not say (an older bridge-api).
63
+ * Read it after `isEnabled(flag)` returned false.
64
+ */
65
+ getReason(flag) {
66
+ const e = this.cachedReasons[flag];
67
+ return e ? { ...e } : undefined;
68
+ }
41
69
  /**
42
70
  * Drop the cache so the next `isEnabled` re-evaluates against the server
43
71
  * (TBP-575).
@@ -63,6 +91,11 @@ export class FeatureFlagService {
63
91
  try {
64
92
  const data = await httpFetch(url, { method: 'POST', body }, this.logger);
65
93
  this.cachedFlags[flag] = data.enabled ?? false;
94
+ const explanation = this.cachedFlags[flag] ? undefined : readExplanation(data);
95
+ if (explanation)
96
+ this.cachedReasons[flag] = explanation;
97
+ else
98
+ delete this.cachedReasons[flag];
66
99
  return data.enabled ?? false;
67
100
  }
68
101
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"feature-flag-service.js","sourceRoot":"","sources":["../src/feature-flag-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feature-flag-service.js","sourceRoot":"","sources":["../src/feature-flag-service.ts"],"names":[],"mappings":"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"}
@@ -113,6 +113,58 @@ export declare class AuthAttributeProvider implements AttributeProvider {
113
113
  constructor(config?: AuthProviderConfig);
114
114
  provide(): Record<string, unknown>;
115
115
  }
116
+ /**
117
+ * The auth-derived targeting attributes for a set of decoded JWT claims — the
118
+ * one mapping every SDK uses, so a rule on `user.role` means the same thing in
119
+ * the browser (`AuthAttributeProvider`) and on a server (bridge-nestjs builds
120
+ * its request context with this, from claims it verified itself; TBP-757):
121
+ * - `user.id` ← `sub`
122
+ * - `user.role` ← `role`
123
+ * - `user.email` ← `email`
124
+ * - `tenant.id` ← `tid`
125
+ * - `tenant.plan` ← `plan`
126
+ * - `privileges` ← `privileges` (array or string)
127
+ *
128
+ * Pure: an attribute is emitted only when its claim is present and well-typed.
129
+ * The caller is responsible for the claims being trustworthy.
130
+ */
131
+ export declare function claimsToAttributes(claims: AuthJwtClaims | undefined | null): Record<string, unknown>;
132
+ /** Subscription fields `flattenBillingSnapshot` reads (the `/session/init` + store shape). */
133
+ export interface BillingSubscriptionInput {
134
+ plan?: {
135
+ slug?: unknown;
136
+ } | null;
137
+ status?: unknown;
138
+ }
139
+ /** Per-metric quota fields `flattenBillingSnapshot` reads. */
140
+ export interface BillingQuotaInput {
141
+ used?: unknown;
142
+ limit?: unknown;
143
+ remaining?: unknown;
144
+ percent_used?: unknown;
145
+ }
146
+ /** Input to {@link flattenBillingSnapshot}. Every part is optional. */
147
+ export interface BillingSnapshotInput {
148
+ /** The workspace's subscription: plan slug + status. */
149
+ subscription?: BillingSubscriptionInput | null;
150
+ /** Entitlement name → granted. Non-boolean values are skipped. */
151
+ entitlements?: Record<string, unknown> | null;
152
+ /** Metric → quota snapshot. A `Map` (QuotaStore.getAll()) or a plain object. */
153
+ quotas?: Map<string, BillingQuotaInput | null | undefined> | Record<string, BillingQuotaInput | null | undefined> | null;
154
+ }
155
+ /**
156
+ * The billing targeting attributes, `bridge:billing.*`, for a billing
157
+ * snapshot — the one mapping `BillingAttributeProvider` uses in the browser and
158
+ * bridge-nestjs uses on the server from `/session/init` (TBP-757):
159
+ * - `bridge:billing.plan` string (plan slug)
160
+ * - `bridge:billing.subscription.status` string
161
+ * - `bridge:billing.trial` boolean (status === 'trial')
162
+ * - `bridge:billing.quota.<metric>.used|limit|remaining|percent_used` number
163
+ * - `bridge:billing.entitlement.<name>` boolean
164
+ *
165
+ * Pure and defensive: missing or mistyped parts contribute no keys.
166
+ */
167
+ export declare function flattenBillingSnapshot(input: BillingSnapshotInput | undefined | null): Record<string, unknown>;
116
168
  /**
117
169
  * A snapshot of the current billing state. All fields optional — apps can
118
170
  * surface only what they have. `quota` exposes `{used, limit}` per resource;
@@ -1 +1 @@
1
- {"version":3,"file":"attribute-providers.d.ts","sourceRoot":"","sources":["../../src/flags/attribute-providers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attribute-providers.d.ts","sourceRoot":"","sources":["../../src/flags/attribute-providers.ts"],"names":[],"mappings":"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"}
@@ -138,34 +138,106 @@ export class AuthAttributeProvider {
138
138
  catch {
139
139
  return {};
140
140
  }
141
- if (!claims || typeof claims !== 'object')
142
- return {};
143
- const out = {};
144
- if (typeof claims.sub === 'string' && claims.sub.length > 0) {
145
- out['user.id'] = claims.sub;
146
- }
147
- if (typeof claims.role === 'string') {
148
- out['user.role'] = claims.role;
149
- }
150
- if (typeof claims.email === 'string') {
151
- out['user.email'] = claims.email;
152
- }
153
- if (typeof claims.tid === 'string') {
154
- out['tenant.id'] = claims.tid;
141
+ return claimsToAttributes(claims);
142
+ }
143
+ }
144
+ /** Namespace of the billing-derived attributes. */
145
+ const BILLING_NS_PREFIX = 'bridge:billing.';
146
+ /**
147
+ * The auth-derived targeting attributes for a set of decoded JWT claims — the
148
+ * one mapping every SDK uses, so a rule on `user.role` means the same thing in
149
+ * the browser (`AuthAttributeProvider`) and on a server (bridge-nestjs builds
150
+ * its request context with this, from claims it verified itself; TBP-757):
151
+ * - `user.id` ← `sub`
152
+ * - `user.role` ← `role`
153
+ * - `user.email` ← `email`
154
+ * - `tenant.id` ← `tid`
155
+ * - `tenant.plan` ← `plan`
156
+ * - `privileges` ← `privileges` (array or string)
157
+ *
158
+ * Pure: an attribute is emitted only when its claim is present and well-typed.
159
+ * The caller is responsible for the claims being trustworthy.
160
+ */
161
+ export function claimsToAttributes(claims) {
162
+ if (!claims || typeof claims !== 'object')
163
+ return {};
164
+ const out = {};
165
+ if (typeof claims.sub === 'string' && claims.sub.length > 0) {
166
+ out['user.id'] = claims.sub;
167
+ }
168
+ if (typeof claims.role === 'string') {
169
+ out['user.role'] = claims.role;
170
+ }
171
+ if (typeof claims.email === 'string') {
172
+ out['user.email'] = claims.email;
173
+ }
174
+ if (typeof claims.tid === 'string') {
175
+ out['tenant.id'] = claims.tid;
176
+ }
177
+ if (typeof claims.plan === 'string') {
178
+ out['tenant.plan'] = claims.plan;
179
+ }
180
+ if (Array.isArray(claims.privileges)) {
181
+ out['privileges'] = claims.privileges;
182
+ }
183
+ else if (typeof claims.privileges === 'string') {
184
+ out['privileges'] = claims.privileges;
185
+ }
186
+ return out;
187
+ }
188
+ /**
189
+ * The billing targeting attributes, `bridge:billing.*`, for a billing
190
+ * snapshot — the one mapping `BillingAttributeProvider` uses in the browser and
191
+ * bridge-nestjs uses on the server from `/session/init` (TBP-757):
192
+ * - `bridge:billing.plan` string (plan slug)
193
+ * - `bridge:billing.subscription.status` string
194
+ * - `bridge:billing.trial` boolean (status === 'trial')
195
+ * - `bridge:billing.quota.<metric>.used|limit|remaining|percent_used` number
196
+ * - `bridge:billing.entitlement.<name>` boolean
197
+ *
198
+ * Pure and defensive: missing or mistyped parts contribute no keys.
199
+ */
200
+ export function flattenBillingSnapshot(input) {
201
+ const out = {};
202
+ if (!input || typeof input !== 'object')
203
+ return out;
204
+ const sub = input.subscription;
205
+ if (sub && typeof sub === 'object') {
206
+ if (sub.plan && typeof sub.plan.slug === 'string') {
207
+ out[`${BILLING_NS_PREFIX}plan`] = sub.plan.slug;
155
208
  }
156
- if (typeof claims.plan === 'string') {
157
- out['tenant.plan'] = claims.plan;
209
+ if (typeof sub.status === 'string') {
210
+ out[`${BILLING_NS_PREFIX}subscription.status`] = sub.status;
211
+ out[`${BILLING_NS_PREFIX}trial`] = sub.status === 'trial';
158
212
  }
159
- if (Array.isArray(claims.privileges)) {
160
- out['privileges'] = claims.privileges;
213
+ }
214
+ const quotas = input.quotas;
215
+ if (quotas && typeof quotas === 'object') {
216
+ const entries = quotas instanceof Map ? quotas.entries() : Object.entries(quotas);
217
+ for (const [metric, snap] of entries) {
218
+ if (!snap || typeof snap !== 'object')
219
+ continue;
220
+ const base = `${BILLING_NS_PREFIX}quota.${metric}`;
221
+ if (typeof snap.used === 'number')
222
+ out[`${base}.used`] = snap.used;
223
+ if (typeof snap.limit === 'number')
224
+ out[`${base}.limit`] = snap.limit;
225
+ if (typeof snap.remaining === 'number')
226
+ out[`${base}.remaining`] = snap.remaining;
227
+ if (typeof snap.percent_used === 'number')
228
+ out[`${base}.percent_used`] = snap.percent_used;
161
229
  }
162
- else if (typeof claims.privileges === 'string') {
163
- out['privileges'] = claims.privileges;
230
+ }
231
+ const ent = input.entitlements;
232
+ if (ent && typeof ent === 'object') {
233
+ for (const [name, value] of Object.entries(ent)) {
234
+ if (typeof value === 'boolean') {
235
+ out[`${BILLING_NS_PREFIX}entitlement.${name}`] = value;
236
+ }
164
237
  }
165
- return out;
166
238
  }
239
+ return out;
167
240
  }
168
- const BILLING_NS_PREFIX = 'bridge:billing.';
169
241
  export class BillingAttributeProvider {
170
242
  name = 'bridge:billing';
171
243
  namespace = 'bridge';
@@ -260,68 +332,34 @@ export class BillingAttributeProvider {
260
332
  * reserved for a future story — no live source today, so it's left empty.
261
333
  */
262
334
  flattenStores() {
263
- const out = {};
264
- // Subscription — plan slug, trial flag, status string.
335
+ // Each store is read in isolation so one misbehaving store can't hide the
336
+ // others; the flattening itself is the shared pure `flattenBillingSnapshot`.
337
+ const input = {};
265
338
  try {
266
- const sub = this.stores.subscription;
267
- if (sub) {
268
- const snap = sub.snapshot();
269
- const state = snap.state;
270
- if (state) {
271
- if (state.plan && typeof state.plan.slug === 'string') {
272
- out[`${BILLING_NS_PREFIX}plan`] = state.plan.slug;
273
- }
274
- if (typeof state.status === 'string') {
275
- out[`${BILLING_NS_PREFIX}subscription.status`] = state.status;
276
- out[`${BILLING_NS_PREFIX}trial`] = state.status === 'trial';
277
- }
278
- }
279
- }
339
+ const state = this.stores.subscription?.snapshot().state;
340
+ if (state)
341
+ input.subscription = state;
280
342
  }
281
343
  catch (err) {
282
344
  this.warnOnce(err);
283
345
  }
284
- // Quotas — per-metric used / limit / remaining / percent_used.
285
346
  try {
286
347
  const quotas = this.stores.quotas;
287
- if (quotas) {
288
- const all = quotas.getAll();
289
- for (const [metric, snap] of all.entries()) {
290
- if (!snap)
291
- continue;
292
- const base = `${BILLING_NS_PREFIX}quota.${metric}`;
293
- if (typeof snap.used === 'number')
294
- out[`${base}.used`] = snap.used;
295
- if (typeof snap.limit === 'number')
296
- out[`${base}.limit`] = snap.limit;
297
- if (typeof snap.remaining === 'number') {
298
- out[`${base}.remaining`] = snap.remaining;
299
- }
300
- if (typeof snap.percent_used === 'number') {
301
- out[`${base}.percent_used`] = snap.percent_used;
302
- }
303
- }
304
- }
348
+ if (quotas)
349
+ input.quotas = quotas.getAll();
305
350
  }
306
351
  catch (err) {
307
352
  this.warnOnce(err);
308
353
  }
309
- // Entitlements — boolean per name (incl. `app_active`).
310
354
  try {
311
355
  const ent = this.stores.entitlements;
312
- if (ent && ent.isHydrated()) {
313
- const all = ent.all();
314
- for (const [name, value] of Object.entries(all)) {
315
- if (typeof value === 'boolean') {
316
- out[`${BILLING_NS_PREFIX}entitlement.${name}`] = value;
317
- }
318
- }
319
- }
356
+ if (ent && ent.isHydrated())
357
+ input.entitlements = ent.all();
320
358
  }
321
359
  catch (err) {
322
360
  this.warnOnce(err);
323
361
  }
324
- return out;
362
+ return flattenBillingSnapshot(input);
325
363
  }
326
364
  flatten(snapshot) {
327
365
  if (!snapshot || typeof snapshot !== 'object')
@@ -1 +1 @@
1
- {"version":3,"file":"attribute-providers.js","sourceRoot":"","sources":["../../src/flags/attribute-providers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attribute-providers.js","sourceRoot":"","sources":["../../src/flags/attribute-providers.ts"],"names":[],"mappings":"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"}
@@ -27,7 +27,43 @@ export interface EvalResult {
27
27
  variantIndex: number;
28
28
  matched: boolean;
29
29
  excludedByRollout: boolean;
30
+ /**
31
+ * TBP-756 — why the feature is off. Set only when the served value is off
32
+ * (`false`, `null` or `undefined`); absent when it is on. See
33
+ * {@link FlagOffReason}.
34
+ */
35
+ reason?: FlagOffReason;
36
+ /**
37
+ * TBP-756 — with `reason: 'plan'`, the plan feature the decisive rule
38
+ * condition asks for (`bridge:billing.entitlement.<feature>`), so an upgrade
39
+ * dialog can name the plans that include it. Absent when the condition is on
40
+ * the plan itself (`tenant.plan`, `bridge:billing.plan`).
41
+ */
42
+ feature?: string;
30
43
  }
44
+ /**
45
+ * Why a flag served its off value:
46
+ * - `plan` — an upgrade alone would turn it on (the failing conditions
47
+ * are all about the plan: `tenant.plan`, `bridge:billing.*`)
48
+ * - `permission` — this person's role or privileges keep it off (a condition
49
+ * on `user.role` or `privileges` failed; also when the plan
50
+ * failed too, since an upgrade alone would not help)
51
+ * - `off` — the flag is switched off for everyone
52
+ * - `rule` — some other condition keeps it off
53
+ * - `rollout` — the person is outside the rollout percentage
54
+ */
55
+ export type FlagOffReason = 'plan' | 'permission' | 'off' | 'rule' | 'rollout';
56
+ /** The family a rule attribute belongs to, for {@link FlagOffReason}. */
57
+ export type AttributeFamily = 'plan' | 'permission' | 'other';
58
+ /**
59
+ * The family table: `tenant.plan` and every `bridge:billing.*` attribute are
60
+ * the plan; `user.role` and `privileges` are permission; everything else is
61
+ * other. bridge-api keeps a copy of this table for its server-side evaluate;
62
+ * the two must stay identical.
63
+ */
64
+ export declare function attributeFamily(attribute: string): AttributeFamily;
65
+ /** True for a served value that means "the feature is off". */
66
+ export declare function isOffValue(value: unknown): boolean;
31
67
  /**
32
68
  * Resolve a dotted-path attribute name against the eval context.
33
69
  * Tries the flat key first, then walks dots.
@@ -1 +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"}
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;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,YAAY,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;AAE/E,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,YAAY,GAAG,OAAO,CAAC;AAK9D;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAIlE;AAED,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAElD;AAsED;;;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,CAmCtF;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"}
@@ -13,6 +13,86 @@
13
13
  // on top of those primitives.
14
14
  import { evaluateCondition } from './operators.js';
15
15
  import { isOperator, isOperatorValidForType, validOperatorsForType, } from './operators.js';
16
+ const BILLING_PREFIX = 'bridge:billing.';
17
+ const ENTITLEMENT_PREFIX = 'bridge:billing.entitlement.';
18
+ /**
19
+ * The family table: `tenant.plan` and every `bridge:billing.*` attribute are
20
+ * the plan; `user.role` and `privileges` are permission; everything else is
21
+ * other. bridge-api keeps a copy of this table for its server-side evaluate;
22
+ * the two must stay identical.
23
+ */
24
+ export function attributeFamily(attribute) {
25
+ if (attribute === 'tenant.plan' || attribute.startsWith(BILLING_PREFIX))
26
+ return 'plan';
27
+ if (attribute === 'user.role' || attribute === 'privileges')
28
+ return 'permission';
29
+ return 'other';
30
+ }
31
+ /** True for a served value that means "the feature is off". */
32
+ export function isOffValue(value) {
33
+ return value === false || value === null || value === undefined;
34
+ }
35
+ function reasonForFamilies(families) {
36
+ if (families.size === 0)
37
+ return 'rule';
38
+ if (families.has('other'))
39
+ return 'rule';
40
+ if (families.has('permission'))
41
+ return 'permission';
42
+ return 'plan';
43
+ }
44
+ function entitlementFeature(conditions) {
45
+ for (const c of conditions) {
46
+ if (c.attribute.startsWith(ENTITLEMENT_PREFIX)) {
47
+ const key = c.attribute.slice(ENTITLEMENT_PREFIX.length);
48
+ if (key)
49
+ return key;
50
+ }
51
+ }
52
+ return undefined;
53
+ }
54
+ /**
55
+ * Explain an off result of a rule. `matchedIndex` is the branch that fired
56
+ * (it returned an off value), or -1 when the otherwise value was served.
57
+ *
58
+ * - A branch that fired: its own conditions decide the family (a
59
+ * `plan eq free → false` branch is a plan reason).
60
+ * - Nothing fired: every branch that would have turned the feature on is
61
+ * asked which of its conditions failed. If any of them failed only on the
62
+ * plan, an upgrade alone unlocks it → `plan`. Otherwise, if any failed only
63
+ * on plan and permission → `permission`. Otherwise `rule`.
64
+ */
65
+ function explainOff(rule, ctx, matchedIndex) {
66
+ const branches = rule.branches ?? [];
67
+ if (matchedIndex >= 0) {
68
+ const conditions = branches[matchedIndex]?.conditions ?? [];
69
+ const families = new Set(conditions.map((c) => attributeFamily(c.attribute)));
70
+ const reason = reasonForFamilies(families);
71
+ return reason === 'plan' ? withFeature(reason, conditions) : { reason };
72
+ }
73
+ let best;
74
+ const rank = { plan: 0, permission: 1, rule: 2, off: 3, rollout: 4 };
75
+ for (const branch of branches) {
76
+ if (isOffValue(branch.returnValue))
77
+ continue;
78
+ const conditions = branch.conditions ?? [];
79
+ if (conditions.length === 0)
80
+ continue;
81
+ const failed = conditions.filter((c) => !evaluateCondition(c, resolveAttribute(ctx, c.attribute)));
82
+ if (failed.length === 0)
83
+ continue;
84
+ const reason = reasonForFamilies(new Set(failed.map((c) => attributeFamily(c.attribute))));
85
+ if (!best || rank[reason] < rank[best.reason])
86
+ best = { reason, failed };
87
+ }
88
+ if (!best)
89
+ return { reason: 'rule' };
90
+ return best.reason === 'plan' ? withFeature(best.reason, best.failed) : { reason: best.reason };
91
+ }
92
+ function withFeature(reason, conditions) {
93
+ const feature = entitlementFeature(conditions);
94
+ return feature ? { reason, feature } : { reason };
95
+ }
16
96
  // ── Attribute resolution ────────────────────────────────────────────────────
17
97
  /**
18
98
  * Resolve a dotted-path attribute name against the eval context.
@@ -62,25 +142,36 @@ export function evaluateBranch(branch, ctx) {
62
142
  export function evaluateRule(rule, flagKey, ctx) {
63
143
  const rolloutPct = clampPct(rule.rolloutPct ?? 100);
64
144
  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 };
145
+ if (!ctx.identity || bucket(flagKey, ctx.identity) >= rolloutPct) {
146
+ return {
147
+ value: rule.otherwiseValue,
148
+ variantIndex: -1,
149
+ matched: false,
150
+ excludedByRollout: true,
151
+ ...(isOffValue(rule.otherwiseValue) ? { reason: 'rollout' } : {}),
152
+ };
70
153
  }
71
154
  }
72
155
  const branches = rule.branches ?? [];
73
156
  for (let i = 0; i < branches.length; i++) {
74
157
  if (evaluateBranch(branches[i], ctx)) {
158
+ const value = branches[i].returnValue;
75
159
  return {
76
- value: branches[i].returnValue,
160
+ value,
77
161
  variantIndex: i,
78
162
  matched: true,
79
163
  excludedByRollout: false,
164
+ ...(isOffValue(value) ? explainOff(rule, ctx, i) : {}),
80
165
  };
81
166
  }
82
167
  }
83
- return { value: rule.otherwiseValue, variantIndex: -1, matched: false, excludedByRollout: false };
168
+ return {
169
+ value: rule.otherwiseValue,
170
+ variantIndex: -1,
171
+ matched: false,
172
+ excludedByRollout: false,
173
+ ...(isOffValue(rule.otherwiseValue) ? explainOff(rule, ctx, -1) : {}),
174
+ };
84
175
  }
85
176
  function clampPct(p) {
86
177
  if (!Number.isFinite(p))