@nebulr-group/bridge-auth-core 0.1.2 → 0.4.0-beta.1
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 +39 -1
- package/dist/bridge-auth.d.ts.map +1 -1
- package/dist/bridge-auth.js +89 -6
- 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 +353 -0
- package/dist/flags/realtime.d.ts.map +1 -0
- package/dist/flags/realtime.js +779 -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 +4 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +44 -12
- 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,229 @@
|
|
|
1
|
+
import type { BridgeFlags } from './flag.js';
|
|
2
|
+
import type { BridgeSubscription } from '../billing/bridge-subscription.js';
|
|
3
|
+
import type { QuotaStore } from '../billing/quota-store.js';
|
|
4
|
+
import type { EntitlementsStore } from '../billing/entitlements-store.js';
|
|
5
|
+
/**
|
|
6
|
+
* A provider contributes a set of attributes for the current user/session.
|
|
7
|
+
* `provide()` is called on every flag eval; implementations should be cheap
|
|
8
|
+
* and synchronous (or fast async). Provider errors fall back to empty
|
|
9
|
+
* attributes — never break the eval.
|
|
10
|
+
*/
|
|
11
|
+
export interface AttributeProvider {
|
|
12
|
+
/** Stable name for logging + collision messaging. */
|
|
13
|
+
readonly name: string;
|
|
14
|
+
/** Whether the keys this provider supplies count as bridge-managed (`bridge:`) or custom (`custom:`). */
|
|
15
|
+
readonly namespace?: 'bridge' | 'custom';
|
|
16
|
+
/**
|
|
17
|
+
* Return the attributes this provider currently supplies. May return a
|
|
18
|
+
* Promise; for hot paths, implementations should cache and return sync.
|
|
19
|
+
*/
|
|
20
|
+
provide(): Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Registry attached to a BridgeFlags instance. Framework SDKs (bridge-svelte's
|
|
24
|
+
* Bridge.init) wire this up during bootstrap.
|
|
25
|
+
*/
|
|
26
|
+
export declare class AttributeProviderRegistry {
|
|
27
|
+
private providers;
|
|
28
|
+
/** Register a provider. Idempotent on `name` — re-registering with the same name replaces. */
|
|
29
|
+
register(provider: AttributeProvider): void;
|
|
30
|
+
/** Remove a provider by name. */
|
|
31
|
+
unregister(name: string): void;
|
|
32
|
+
/** Number of providers currently registered. */
|
|
33
|
+
size(): number;
|
|
34
|
+
/** List provider names. */
|
|
35
|
+
names(): string[];
|
|
36
|
+
/**
|
|
37
|
+
* Collect attributes from every registered provider, merged in registration
|
|
38
|
+
* order. Later providers' keys overwrite earlier ones; this is INTERNAL
|
|
39
|
+
* merge order — dev-supplied attributes always win at the call boundary
|
|
40
|
+
* (handled in `applyTo`).
|
|
41
|
+
*
|
|
42
|
+
* Provider failures are isolated — one provider throwing doesn't block the
|
|
43
|
+
* rest. The failing provider contributes an empty attribute set for that call.
|
|
44
|
+
*/
|
|
45
|
+
collect(): Promise<Record<string, unknown>>;
|
|
46
|
+
/**
|
|
47
|
+
* Sync variant of `collect()` — used by `BridgeFlags.flag()` on the hot eval
|
|
48
|
+
* path (FF 2.0 evaluates inline on every flag check, so the merge must be
|
|
49
|
+
* sync). Async providers are SKIPPED for this eval; they should self-cache
|
|
50
|
+
* their result and return sync values once warmed.
|
|
51
|
+
*
|
|
52
|
+
* Same isolation guarantee as `collect()`: one throwing provider doesn't
|
|
53
|
+
* block the rest.
|
|
54
|
+
*/
|
|
55
|
+
collectSync(): Record<string, unknown>;
|
|
56
|
+
/**
|
|
57
|
+
* Apply provider attributes to a BridgeFlags instance's global context.
|
|
58
|
+
* Should be called on a sensible cadence by the framework SDK — typically:
|
|
59
|
+
* - once at bootstrap
|
|
60
|
+
* - when auth state changes (logout/login, role change)
|
|
61
|
+
* - on a periodic refresh if attributes drift
|
|
62
|
+
*
|
|
63
|
+
* Dev-supplied attributes are preserved on collision (locked decision #20).
|
|
64
|
+
*/
|
|
65
|
+
applyTo(bridge: BridgeFlags): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Shape of the JWT claims that AuthAttributeProvider reads. Every field is
|
|
69
|
+
* optional — the provider emits an attribute only when the corresponding
|
|
70
|
+
* claim is present.
|
|
71
|
+
*/
|
|
72
|
+
export interface AuthJwtClaims {
|
|
73
|
+
/** Subject — the user's id. */
|
|
74
|
+
sub?: string;
|
|
75
|
+
role?: string;
|
|
76
|
+
email?: string;
|
|
77
|
+
/** Tenant id. */
|
|
78
|
+
tid?: string;
|
|
79
|
+
/** Tenant plan (mirrored into `tenant.plan`). Authoritative source for
|
|
80
|
+
* `bridge:billing.plan` is the BillingAttributeProvider — keep them in sync. */
|
|
81
|
+
plan?: string;
|
|
82
|
+
/** Privilege list (or a single comma-joined string). */
|
|
83
|
+
privileges?: string[] | string;
|
|
84
|
+
/** Catch-all so unknown claims don't break the type. */
|
|
85
|
+
[k: string]: unknown;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Configuration for `AuthAttributeProvider`. The framework SDK supplies a
|
|
89
|
+
* sync getter that returns the current decoded JWT claims (or `undefined`
|
|
90
|
+
* when logged out). Sync read is critical: FF 2.0 evaluates inline.
|
|
91
|
+
*/
|
|
92
|
+
export interface AuthProviderConfig {
|
|
93
|
+
getClaims: () => AuthJwtClaims | undefined;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Canonical auth-derived attribute source. Reads decoded JWT claims through
|
|
97
|
+
* a sync callback the framework SDK provides, and flattens them into the
|
|
98
|
+
* eval namespace:
|
|
99
|
+
* - `user.id` ← `sub`
|
|
100
|
+
* - `user.role` ← `role`
|
|
101
|
+
* - `user.email` ← `email`
|
|
102
|
+
* - `tenant.id` ← `tid`
|
|
103
|
+
* - `tenant.plan` ← `plan`
|
|
104
|
+
* - `privileges` ← `privileges` (array or string)
|
|
105
|
+
*
|
|
106
|
+
* Construct with no config for the empty stub (every workspace gets the
|
|
107
|
+
* provider in its registry by default; unconfigured ones contribute nothing).
|
|
108
|
+
*/
|
|
109
|
+
export declare class AuthAttributeProvider implements AttributeProvider {
|
|
110
|
+
readonly name = "bridge:auth";
|
|
111
|
+
readonly namespace: "bridge";
|
|
112
|
+
private readonly config;
|
|
113
|
+
constructor(config?: AuthProviderConfig);
|
|
114
|
+
provide(): Record<string, unknown>;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* A snapshot of the current billing state. All fields optional — apps can
|
|
118
|
+
* surface only what they have. `quota` exposes `{used, limit}` per resource;
|
|
119
|
+
* the provider auto-derives `percent_used` when both fields are numeric and
|
|
120
|
+
* `limit > 0`. `limit` exposes scalar plan caps (seats, max_projects, etc).
|
|
121
|
+
*/
|
|
122
|
+
export interface BillingSnapshot {
|
|
123
|
+
/** Current plan tier (e.g. 'FREE' | 'TEAM' | 'PRO'). */
|
|
124
|
+
plan?: string;
|
|
125
|
+
/** True when the tenant is on a time-limited trial. */
|
|
126
|
+
trial?: boolean;
|
|
127
|
+
/** Metered usage per resource. */
|
|
128
|
+
quota?: Record<string, {
|
|
129
|
+
used?: number;
|
|
130
|
+
limit?: number;
|
|
131
|
+
}>;
|
|
132
|
+
/** Plan-defined scalar caps. */
|
|
133
|
+
limit?: Record<string, number | string>;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Configuration for `BillingAttributeProvider`. The dev supplies a callable
|
|
137
|
+
* that returns the current snapshot — sync or async. Returning `undefined`
|
|
138
|
+
* means "no billing data right now" → the provider contributes no attributes.
|
|
139
|
+
*/
|
|
140
|
+
export interface BillingProviderConfig {
|
|
141
|
+
getBillingSnapshot: () => BillingSnapshot | Promise<BillingSnapshot | undefined> | undefined;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Billing 2.0 US-13 — store-backed wiring for the BillingAttributeProvider.
|
|
145
|
+
*
|
|
146
|
+
* Framework wrappers pass the three Phase A/B stores from `useBridge()`. The
|
|
147
|
+
* provider reads them synchronously on every flag eval and flattens the live
|
|
148
|
+
* state into the `bridge:billing.*` namespace:
|
|
149
|
+
* - subscription: `plan`, `trial`, `subscription.status`
|
|
150
|
+
* - quotas: `quota.<metric>.{used,limit,remaining,percent_used}`
|
|
151
|
+
* - entitlements: `entitlement.<name>` (incl. `entitlement.app_active`)
|
|
152
|
+
*
|
|
153
|
+
* All store reads are O(stores in cache). `provide()` MUST stay sync — the FF
|
|
154
|
+
* 2.0 eval path calls it inline on every flag check. No HTTP, no awaits.
|
|
155
|
+
*/
|
|
156
|
+
export interface BillingProviderStores {
|
|
157
|
+
/** `useBridge().subscription` — reactive container for canonical sub state. */
|
|
158
|
+
subscription?: BridgeSubscription;
|
|
159
|
+
/** `useBridge().quotas` — per-metric snapshot cache. */
|
|
160
|
+
quotas?: QuotaStore;
|
|
161
|
+
/** `useBridge().entitlementsStore` — fail-closed boolean map. */
|
|
162
|
+
entitlements?: EntitlementsStore;
|
|
163
|
+
}
|
|
164
|
+
export declare class BillingAttributeProvider implements AttributeProvider {
|
|
165
|
+
readonly name = "bridge:billing";
|
|
166
|
+
readonly namespace: "bridge";
|
|
167
|
+
private readonly config;
|
|
168
|
+
private stores;
|
|
169
|
+
private warnedOnce;
|
|
170
|
+
/**
|
|
171
|
+
* Construct with an explicit config that supplies the billing snapshot.
|
|
172
|
+
* No config → treated as an empty provider (returns `{}` on every call)
|
|
173
|
+
* so accidentally instantiating without wiring doesn't crash.
|
|
174
|
+
*/
|
|
175
|
+
constructor(config?: BillingProviderConfig);
|
|
176
|
+
/**
|
|
177
|
+
* Billing 2.0 US-13 — wire the three reactive stores from `useBridge()` so
|
|
178
|
+
* `provide()` can flatten live billing state synchronously on every flag
|
|
179
|
+
* eval. Idempotent: re-binding replaces the previous store references. Any
|
|
180
|
+
* subset of stores may be supplied — missing stores simply contribute no
|
|
181
|
+
* keys to the flattened map (eg. unattached subscription → no `plan` key).
|
|
182
|
+
*
|
|
183
|
+
* Framework wrappers (bridge-svelte's `Bridge.init`) call this once after
|
|
184
|
+
* `useBridge()` has been bootstrapped, then `register()` the provider on
|
|
185
|
+
* the FF 2.0 AttributeProviderRegistry.
|
|
186
|
+
*/
|
|
187
|
+
bindStores(stores: BillingProviderStores): void;
|
|
188
|
+
/**
|
|
189
|
+
* Flatten the live billing state into the `bridge:billing.*` namespace.
|
|
190
|
+
*
|
|
191
|
+
* Two sources are merged:
|
|
192
|
+
* 1. US-13 store path: reads the three `useBridge()` stores synchronously
|
|
193
|
+
* and emits canonical `plan`, `trial`, `subscription.status`,
|
|
194
|
+
* `quota.<metric>.*`, and `entitlement.<name>` keys.
|
|
195
|
+
* 2. Legacy `getBillingSnapshot` callback path (pre-US-13): preserved so
|
|
196
|
+
* standalone-FF apps that wired the provider before US-13 keep
|
|
197
|
+
* working. Store-derived keys win on collision (newer = canonical).
|
|
198
|
+
*
|
|
199
|
+
* The store path is sync, no HTTP, no awaits — safe in the FF 2.0 hot eval
|
|
200
|
+
* path. The legacy path may be async; when it is, the merged result is a
|
|
201
|
+
* Promise (consumers awaiting `provide()` already handle this).
|
|
202
|
+
*
|
|
203
|
+
* Failures in any branch degrade silently to whatever was successfully
|
|
204
|
+
* collected — never throws, never breaks the eval.
|
|
205
|
+
*/
|
|
206
|
+
provide(): Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
207
|
+
/**
|
|
208
|
+
* US-13 — read the three stores and emit the canonical `bridge:billing.*`
|
|
209
|
+
* flat map. Sync, defensive: every store ref is optional and every read is
|
|
210
|
+
* wrapped so a single misbehaving store can't break the eval path.
|
|
211
|
+
*
|
|
212
|
+
* Output key set per `BillingAttributeProvider`'s ticket contract:
|
|
213
|
+
* - `bridge:billing.plan` string (plan slug)
|
|
214
|
+
* - `bridge:billing.trial` boolean
|
|
215
|
+
* - `bridge:billing.subscription.status` string
|
|
216
|
+
* - `bridge:billing.quota.<metric>.used` number
|
|
217
|
+
* - `bridge:billing.quota.<metric>.limit` number
|
|
218
|
+
* - `bridge:billing.quota.<metric>.remaining` number
|
|
219
|
+
* - `bridge:billing.quota.<metric>.percent_used` number (0..1+)
|
|
220
|
+
* - `bridge:billing.entitlement.<name>` boolean (incl. `app_active`)
|
|
221
|
+
*
|
|
222
|
+
* Note: `bridge:billing.limit.<name>` (non-quota plan caps like seats) is
|
|
223
|
+
* reserved for a future story — no live source today, so it's left empty.
|
|
224
|
+
*/
|
|
225
|
+
private flattenStores;
|
|
226
|
+
private flatten;
|
|
227
|
+
private warnOnce;
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=attribute-providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-providers.d.ts","sourceRoot":"","sources":["../../src/flags/attribute-providers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
// AttributeProvider plugin model for Bridge Feature Flags (TBP-173).
|
|
2
|
+
//
|
|
3
|
+
// AttributeProvider is THE canonical mechanism for feeding attributes into
|
|
4
|
+
// flag evaluation. Every framework SDK wires the bridge-managed providers
|
|
5
|
+
// (`AuthAttributeProvider`, `BillingAttributeProvider`) automatically on
|
|
6
|
+
// bootstrap so `user.role`, `tenant.plan`, billing entitlements etc. flow in
|
|
7
|
+
// without app code. Apps push their own state into eval by implementing
|
|
8
|
+
// `AttributeProvider` and `register()`ing the instance on the registry — that
|
|
9
|
+
// is the canonical pattern for any attribute backed by app state (cohort,
|
|
10
|
+
// route segment, current workspace, anything reactive).
|
|
11
|
+
//
|
|
12
|
+
// Per-call attributes (via `setContext` or the `<FeatureFlag context>` /
|
|
13
|
+
// `useFlag(key, default, context)` prop) are the *override* path — for
|
|
14
|
+
// transient, one-off, or per-instance values, and to override a provider
|
|
15
|
+
// value at a specific call site. Collision rule (locked decision #20):
|
|
16
|
+
// dev-supplied attributes WIN over provider-supplied attributes on key
|
|
17
|
+
// overlap. The admin UI surfaces the collision so it's debuggable (TBP-178).
|
|
18
|
+
/**
|
|
19
|
+
* Registry attached to a BridgeFlags instance. Framework SDKs (bridge-svelte's
|
|
20
|
+
* Bridge.init) wire this up during bootstrap.
|
|
21
|
+
*/
|
|
22
|
+
export class AttributeProviderRegistry {
|
|
23
|
+
providers = [];
|
|
24
|
+
/** Register a provider. Idempotent on `name` — re-registering with the same name replaces. */
|
|
25
|
+
register(provider) {
|
|
26
|
+
if (!provider.name) {
|
|
27
|
+
throw new Error('AttributeProvider must have a non-empty name');
|
|
28
|
+
}
|
|
29
|
+
this.providers = this.providers.filter((p) => p.name !== provider.name);
|
|
30
|
+
this.providers.push(provider);
|
|
31
|
+
}
|
|
32
|
+
/** Remove a provider by name. */
|
|
33
|
+
unregister(name) {
|
|
34
|
+
this.providers = this.providers.filter((p) => p.name !== name);
|
|
35
|
+
}
|
|
36
|
+
/** Number of providers currently registered. */
|
|
37
|
+
size() {
|
|
38
|
+
return this.providers.length;
|
|
39
|
+
}
|
|
40
|
+
/** List provider names. */
|
|
41
|
+
names() {
|
|
42
|
+
return this.providers.map((p) => p.name);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Collect attributes from every registered provider, merged in registration
|
|
46
|
+
* order. Later providers' keys overwrite earlier ones; this is INTERNAL
|
|
47
|
+
* merge order — dev-supplied attributes always win at the call boundary
|
|
48
|
+
* (handled in `applyTo`).
|
|
49
|
+
*
|
|
50
|
+
* Provider failures are isolated — one provider throwing doesn't block the
|
|
51
|
+
* rest. The failing provider contributes an empty attribute set for that call.
|
|
52
|
+
*/
|
|
53
|
+
async collect() {
|
|
54
|
+
const out = {};
|
|
55
|
+
for (const provider of this.providers) {
|
|
56
|
+
try {
|
|
57
|
+
const attrs = await provider.provide();
|
|
58
|
+
Object.assign(out, attrs ?? {});
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Silently skip a failing provider for this eval.
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Sync variant of `collect()` — used by `BridgeFlags.flag()` on the hot eval
|
|
68
|
+
* path (FF 2.0 evaluates inline on every flag check, so the merge must be
|
|
69
|
+
* sync). Async providers are SKIPPED for this eval; they should self-cache
|
|
70
|
+
* their result and return sync values once warmed.
|
|
71
|
+
*
|
|
72
|
+
* Same isolation guarantee as `collect()`: one throwing provider doesn't
|
|
73
|
+
* block the rest.
|
|
74
|
+
*/
|
|
75
|
+
collectSync() {
|
|
76
|
+
const out = {};
|
|
77
|
+
for (const provider of this.providers) {
|
|
78
|
+
try {
|
|
79
|
+
const attrs = provider.provide();
|
|
80
|
+
if (attrs instanceof Promise) {
|
|
81
|
+
// Async providers can't participate in the sync hot path. They run
|
|
82
|
+
// through `collect()`/`applyTo()` on demand instead.
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
Object.assign(out, attrs ?? {});
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Silently skip a failing provider for this eval.
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Apply provider attributes to a BridgeFlags instance's global context.
|
|
95
|
+
* Should be called on a sensible cadence by the framework SDK — typically:
|
|
96
|
+
* - once at bootstrap
|
|
97
|
+
* - when auth state changes (logout/login, role change)
|
|
98
|
+
* - on a periodic refresh if attributes drift
|
|
99
|
+
*
|
|
100
|
+
* Dev-supplied attributes are preserved on collision (locked decision #20).
|
|
101
|
+
*/
|
|
102
|
+
async applyTo(bridge) {
|
|
103
|
+
const providerAttrs = await this.collect();
|
|
104
|
+
const current = bridge.getContext().attributes;
|
|
105
|
+
// Provider attrs first, dev-supplied attrs second (dev wins on collision)
|
|
106
|
+
bridge.setContext({
|
|
107
|
+
identity: bridge.getContext().identity,
|
|
108
|
+
attributes: { ...providerAttrs, ...current },
|
|
109
|
+
}, false);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Canonical auth-derived attribute source. Reads decoded JWT claims through
|
|
114
|
+
* a sync callback the framework SDK provides, and flattens them into the
|
|
115
|
+
* eval namespace:
|
|
116
|
+
* - `user.id` ← `sub`
|
|
117
|
+
* - `user.role` ← `role`
|
|
118
|
+
* - `user.email` ← `email`
|
|
119
|
+
* - `tenant.id` ← `tid`
|
|
120
|
+
* - `tenant.plan` ← `plan`
|
|
121
|
+
* - `privileges` ← `privileges` (array or string)
|
|
122
|
+
*
|
|
123
|
+
* Construct with no config for the empty stub (every workspace gets the
|
|
124
|
+
* provider in its registry by default; unconfigured ones contribute nothing).
|
|
125
|
+
*/
|
|
126
|
+
export class AuthAttributeProvider {
|
|
127
|
+
name = 'bridge:auth';
|
|
128
|
+
namespace = 'bridge';
|
|
129
|
+
config;
|
|
130
|
+
constructor(config) {
|
|
131
|
+
this.config = config ?? { getClaims: () => undefined };
|
|
132
|
+
}
|
|
133
|
+
provide() {
|
|
134
|
+
let claims;
|
|
135
|
+
try {
|
|
136
|
+
claims = this.config.getClaims();
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return {};
|
|
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;
|
|
155
|
+
}
|
|
156
|
+
if (typeof claims.plan === 'string') {
|
|
157
|
+
out['tenant.plan'] = claims.plan;
|
|
158
|
+
}
|
|
159
|
+
if (Array.isArray(claims.privileges)) {
|
|
160
|
+
out['privileges'] = claims.privileges;
|
|
161
|
+
}
|
|
162
|
+
else if (typeof claims.privileges === 'string') {
|
|
163
|
+
out['privileges'] = claims.privileges;
|
|
164
|
+
}
|
|
165
|
+
return out;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const BILLING_NS_PREFIX = 'bridge:billing.';
|
|
169
|
+
export class BillingAttributeProvider {
|
|
170
|
+
name = 'bridge:billing';
|
|
171
|
+
namespace = 'bridge';
|
|
172
|
+
config;
|
|
173
|
+
stores = {};
|
|
174
|
+
warnedOnce = false;
|
|
175
|
+
/**
|
|
176
|
+
* Construct with an explicit config that supplies the billing snapshot.
|
|
177
|
+
* No config → treated as an empty provider (returns `{}` on every call)
|
|
178
|
+
* so accidentally instantiating without wiring doesn't crash.
|
|
179
|
+
*/
|
|
180
|
+
constructor(config) {
|
|
181
|
+
this.config = config ?? { getBillingSnapshot: () => undefined };
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Billing 2.0 US-13 — wire the three reactive stores from `useBridge()` so
|
|
185
|
+
* `provide()` can flatten live billing state synchronously on every flag
|
|
186
|
+
* eval. Idempotent: re-binding replaces the previous store references. Any
|
|
187
|
+
* subset of stores may be supplied — missing stores simply contribute no
|
|
188
|
+
* keys to the flattened map (eg. unattached subscription → no `plan` key).
|
|
189
|
+
*
|
|
190
|
+
* Framework wrappers (bridge-svelte's `Bridge.init`) call this once after
|
|
191
|
+
* `useBridge()` has been bootstrapped, then `register()` the provider on
|
|
192
|
+
* the FF 2.0 AttributeProviderRegistry.
|
|
193
|
+
*/
|
|
194
|
+
bindStores(stores) {
|
|
195
|
+
this.stores = { ...stores };
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Flatten the live billing state into the `bridge:billing.*` namespace.
|
|
199
|
+
*
|
|
200
|
+
* Two sources are merged:
|
|
201
|
+
* 1. US-13 store path: reads the three `useBridge()` stores synchronously
|
|
202
|
+
* and emits canonical `plan`, `trial`, `subscription.status`,
|
|
203
|
+
* `quota.<metric>.*`, and `entitlement.<name>` keys.
|
|
204
|
+
* 2. Legacy `getBillingSnapshot` callback path (pre-US-13): preserved so
|
|
205
|
+
* standalone-FF apps that wired the provider before US-13 keep
|
|
206
|
+
* working. Store-derived keys win on collision (newer = canonical).
|
|
207
|
+
*
|
|
208
|
+
* The store path is sync, no HTTP, no awaits — safe in the FF 2.0 hot eval
|
|
209
|
+
* path. The legacy path may be async; when it is, the merged result is a
|
|
210
|
+
* Promise (consumers awaiting `provide()` already handle this).
|
|
211
|
+
*
|
|
212
|
+
* Failures in any branch degrade silently to whatever was successfully
|
|
213
|
+
* collected — never throws, never breaks the eval.
|
|
214
|
+
*/
|
|
215
|
+
provide() {
|
|
216
|
+
// US-13 — store-backed path. Synchronous, no HTTP. Reads the live state
|
|
217
|
+
// of the three Phase A/B stores (subscription, quotas, entitlements) and
|
|
218
|
+
// flattens into the `bridge:billing.*` namespace. Safe to call before any
|
|
219
|
+
// store is wired — missing stores simply contribute no keys.
|
|
220
|
+
const storeAttrs = this.flattenStores();
|
|
221
|
+
// Legacy path — the `getBillingSnapshot` callback config. Preserved so
|
|
222
|
+
// standalone-FF apps that wired the provider before US-13 keep working.
|
|
223
|
+
let result;
|
|
224
|
+
try {
|
|
225
|
+
result = this.config.getBillingSnapshot();
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
this.warnOnce(err);
|
|
229
|
+
return storeAttrs;
|
|
230
|
+
}
|
|
231
|
+
if (result instanceof Promise) {
|
|
232
|
+
// Async legacy snapshot — merge async; store attrs are returned now and
|
|
233
|
+
// also re-emitted under the resolved promise. Provider attrs from the
|
|
234
|
+
// store path win on collision (newer = US-13 canonical).
|
|
235
|
+
return result.then((snap) => ({ ...this.flatten(snap), ...storeAttrs }), (err) => {
|
|
236
|
+
this.warnOnce(err);
|
|
237
|
+
return storeAttrs;
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
// Sync legacy snapshot (or undefined) — merge sync. Store attrs win.
|
|
241
|
+
const legacyAttrs = this.flatten(result);
|
|
242
|
+
return { ...legacyAttrs, ...storeAttrs };
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* US-13 — read the three stores and emit the canonical `bridge:billing.*`
|
|
246
|
+
* flat map. Sync, defensive: every store ref is optional and every read is
|
|
247
|
+
* wrapped so a single misbehaving store can't break the eval path.
|
|
248
|
+
*
|
|
249
|
+
* Output key set per `BillingAttributeProvider`'s ticket contract:
|
|
250
|
+
* - `bridge:billing.plan` string (plan slug)
|
|
251
|
+
* - `bridge:billing.trial` boolean
|
|
252
|
+
* - `bridge:billing.subscription.status` string
|
|
253
|
+
* - `bridge:billing.quota.<metric>.used` number
|
|
254
|
+
* - `bridge:billing.quota.<metric>.limit` number
|
|
255
|
+
* - `bridge:billing.quota.<metric>.remaining` number
|
|
256
|
+
* - `bridge:billing.quota.<metric>.percent_used` number (0..1+)
|
|
257
|
+
* - `bridge:billing.entitlement.<name>` boolean (incl. `app_active`)
|
|
258
|
+
*
|
|
259
|
+
* Note: `bridge:billing.limit.<name>` (non-quota plan caps like seats) is
|
|
260
|
+
* reserved for a future story — no live source today, so it's left empty.
|
|
261
|
+
*/
|
|
262
|
+
flattenStores() {
|
|
263
|
+
const out = {};
|
|
264
|
+
// Subscription — plan slug, trial flag, status string.
|
|
265
|
+
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
|
+
}
|
|
280
|
+
}
|
|
281
|
+
catch (err) {
|
|
282
|
+
this.warnOnce(err);
|
|
283
|
+
}
|
|
284
|
+
// Quotas — per-metric used / limit / remaining / percent_used.
|
|
285
|
+
try {
|
|
286
|
+
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
|
+
}
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
this.warnOnce(err);
|
|
308
|
+
}
|
|
309
|
+
// Entitlements — boolean per name (incl. `app_active`).
|
|
310
|
+
try {
|
|
311
|
+
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
|
+
}
|
|
320
|
+
}
|
|
321
|
+
catch (err) {
|
|
322
|
+
this.warnOnce(err);
|
|
323
|
+
}
|
|
324
|
+
return out;
|
|
325
|
+
}
|
|
326
|
+
flatten(snapshot) {
|
|
327
|
+
if (!snapshot || typeof snapshot !== 'object')
|
|
328
|
+
return {};
|
|
329
|
+
const out = {};
|
|
330
|
+
if (typeof snapshot.plan === 'string') {
|
|
331
|
+
out[`${BILLING_NS_PREFIX}plan`] = snapshot.plan;
|
|
332
|
+
}
|
|
333
|
+
if (typeof snapshot.trial === 'boolean') {
|
|
334
|
+
out[`${BILLING_NS_PREFIX}trial`] = snapshot.trial;
|
|
335
|
+
}
|
|
336
|
+
if (snapshot.quota && typeof snapshot.quota === 'object') {
|
|
337
|
+
for (const [resource, q] of Object.entries(snapshot.quota)) {
|
|
338
|
+
if (!q || typeof q !== 'object')
|
|
339
|
+
continue;
|
|
340
|
+
const base = `${BILLING_NS_PREFIX}quota.${resource}`;
|
|
341
|
+
const used = typeof q.used === 'number' ? q.used : undefined;
|
|
342
|
+
const limit = typeof q.limit === 'number' ? q.limit : undefined;
|
|
343
|
+
if (used !== undefined)
|
|
344
|
+
out[`${base}.used`] = used;
|
|
345
|
+
if (limit !== undefined)
|
|
346
|
+
out[`${base}.limit`] = limit;
|
|
347
|
+
if (used !== undefined && limit !== undefined && limit > 0) {
|
|
348
|
+
out[`${base}.percent_used`] = Math.floor((used / limit) * 100);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (snapshot.limit && typeof snapshot.limit === 'object') {
|
|
353
|
+
for (const [name, value] of Object.entries(snapshot.limit)) {
|
|
354
|
+
if (typeof value === 'number' || typeof value === 'string') {
|
|
355
|
+
out[`${BILLING_NS_PREFIX}limit.${name}`] = value;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return out;
|
|
360
|
+
}
|
|
361
|
+
warnOnce(err) {
|
|
362
|
+
if (this.warnedOnce)
|
|
363
|
+
return;
|
|
364
|
+
this.warnedOnce = true;
|
|
365
|
+
try {
|
|
366
|
+
// eslint-disable-next-line no-console
|
|
367
|
+
globalThis.console?.warn?.(`[BillingAttributeProvider] getBillingSnapshot threw; ` +
|
|
368
|
+
`returning empty attributes. Error: ${err?.message ?? String(err)}`);
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
// ignore console errors
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
//# sourceMappingURL=attribute-providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-providers.js","sourceRoot":"","sources":["../../src/flags/attribute-providers.ts"],"names":[],"mappings":"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"}
|