@revturbine/sdk 0.7.1 → 0.7.3
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/growthbook.d.ts +298 -0
- package/dist/growthbook.js +2 -0
- package/dist/growthbook.js.map +1 -0
- package/dist/headless.d.ts +1636 -645
- package/dist/headless.js +2 -2
- package/dist/headless.js.map +1 -1
- package/dist/index.d.ts +1636 -645
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/types/web-sdk/controllers.d.ts.map +1 -1
- package/dist/types/web-sdk/growthbook.d.ts +9 -0
- package/dist/types/web-sdk/growthbook.d.ts.map +1 -0
- package/dist/types/web-sdk/providers/growthbook-experiment-provider.d.ts +47 -0
- package/dist/types/web-sdk/providers/growthbook-experiment-provider.d.ts.map +1 -0
- package/dist/types/web-sdk/react/PlacementDecisionInspector.d.ts.map +1 -1
- package/dist/types/web-sdk/react/UserProfile.d.ts.map +1 -1
- package/package.json +15 -5
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { GrowthBook } from '@growthbook/growthbook';
|
|
2
|
+
import { toJSONSchema, JSONSchemaMeta } from 'zod/v4/core';
|
|
3
|
+
|
|
4
|
+
type OverrideParameters = Parameters<NonNullable<NonNullable<Parameters<typeof toJSONSchema>[1]>['override']>>[0];
|
|
5
|
+
type OverrideSchemaParameters = Omit<OverrideParameters, 'zodSchema'>;
|
|
6
|
+
type IExtensionType = any;
|
|
7
|
+
type ISpecificationExtension = {
|
|
8
|
+
[extensionName: IExtensionName]: IExtensionType;
|
|
9
|
+
};
|
|
10
|
+
interface ExternalDocumentationObject extends ISpecificationExtension {
|
|
11
|
+
description?: string;
|
|
12
|
+
url: string;
|
|
13
|
+
}
|
|
14
|
+
type ParameterLocation = 'query' | 'header' | 'path' | 'cookie';
|
|
15
|
+
type ParameterStyle = 'matrix' | 'label' | 'form' | 'simple' | 'spaceDelimited' | 'pipeDelimited' | 'deepObject';
|
|
16
|
+
interface BaseParameterObject extends ISpecificationExtension {
|
|
17
|
+
description?: string;
|
|
18
|
+
required?: boolean;
|
|
19
|
+
deprecated?: boolean;
|
|
20
|
+
allowEmptyValue?: boolean;
|
|
21
|
+
style?: ParameterStyle;
|
|
22
|
+
explode?: boolean;
|
|
23
|
+
allowReserved?: boolean;
|
|
24
|
+
schema?: SchemaObject | ReferenceObject;
|
|
25
|
+
examples?: {
|
|
26
|
+
[param: string]: ExampleObject | ReferenceObject;
|
|
27
|
+
};
|
|
28
|
+
example?: any;
|
|
29
|
+
content?: ContentObject;
|
|
30
|
+
}
|
|
31
|
+
interface ParameterObject extends BaseParameterObject {
|
|
32
|
+
name: string;
|
|
33
|
+
in: ParameterLocation;
|
|
34
|
+
}
|
|
35
|
+
interface ContentObject {
|
|
36
|
+
[mediatype: string]: MediaTypeObject;
|
|
37
|
+
}
|
|
38
|
+
interface MediaTypeObject extends ISpecificationExtension {
|
|
39
|
+
schema?: SchemaObject | ReferenceObject;
|
|
40
|
+
examples?: ExamplesObject;
|
|
41
|
+
example?: any;
|
|
42
|
+
encoding?: EncodingObject;
|
|
43
|
+
}
|
|
44
|
+
interface EncodingObject extends ISpecificationExtension {
|
|
45
|
+
[property: string]: EncodingPropertyObject | any;
|
|
46
|
+
}
|
|
47
|
+
interface EncodingPropertyObject {
|
|
48
|
+
contentType?: string;
|
|
49
|
+
headers?: {
|
|
50
|
+
[key: string]: HeaderObject | ReferenceObject;
|
|
51
|
+
};
|
|
52
|
+
style?: string;
|
|
53
|
+
explode?: boolean;
|
|
54
|
+
allowReserved?: boolean;
|
|
55
|
+
[key: string]: any;
|
|
56
|
+
}
|
|
57
|
+
interface ExampleObject {
|
|
58
|
+
summary?: string;
|
|
59
|
+
description?: string;
|
|
60
|
+
value?: any;
|
|
61
|
+
externalValue?: string;
|
|
62
|
+
[property: string]: any;
|
|
63
|
+
}
|
|
64
|
+
interface HeaderObject extends BaseParameterObject {
|
|
65
|
+
$ref?: string;
|
|
66
|
+
}
|
|
67
|
+
interface ExamplesObject {
|
|
68
|
+
[name: string]: ExampleObject | ReferenceObject;
|
|
69
|
+
}
|
|
70
|
+
interface ReferenceObject {
|
|
71
|
+
$ref: string;
|
|
72
|
+
summary?: string;
|
|
73
|
+
description?: string;
|
|
74
|
+
}
|
|
75
|
+
type SchemaObjectType = 'integer' | 'number' | 'string' | 'boolean' | 'object' | 'null' | 'array';
|
|
76
|
+
interface SchemaObject extends ISpecificationExtension {
|
|
77
|
+
$ref?: string;
|
|
78
|
+
discriminator?: DiscriminatorObject;
|
|
79
|
+
readOnly?: boolean;
|
|
80
|
+
writeOnly?: boolean;
|
|
81
|
+
xml?: XmlObject;
|
|
82
|
+
externalDocs?: ExternalDocumentationObject;
|
|
83
|
+
example?: any;
|
|
84
|
+
examples?: any[];
|
|
85
|
+
deprecated?: boolean;
|
|
86
|
+
type?: SchemaObjectType | SchemaObjectType[];
|
|
87
|
+
format?: 'int32' | 'int64' | 'float' | 'double' | 'byte' | 'binary' | 'date' | 'date-time' | 'password' | string;
|
|
88
|
+
allOf?: (SchemaObject | ReferenceObject)[];
|
|
89
|
+
oneOf?: (SchemaObject | ReferenceObject)[];
|
|
90
|
+
anyOf?: (SchemaObject | ReferenceObject)[];
|
|
91
|
+
not?: SchemaObject | ReferenceObject;
|
|
92
|
+
items?: SchemaObject | ReferenceObject;
|
|
93
|
+
properties?: {
|
|
94
|
+
[propertyName: string]: SchemaObject | ReferenceObject;
|
|
95
|
+
};
|
|
96
|
+
additionalProperties?: SchemaObject | ReferenceObject | boolean;
|
|
97
|
+
propertyNames?: SchemaObject | ReferenceObject;
|
|
98
|
+
description?: string;
|
|
99
|
+
default?: any;
|
|
100
|
+
title?: string;
|
|
101
|
+
multipleOf?: number;
|
|
102
|
+
maximum?: number;
|
|
103
|
+
const?: any;
|
|
104
|
+
exclusiveMaximum?: number;
|
|
105
|
+
minimum?: number;
|
|
106
|
+
exclusiveMinimum?: number;
|
|
107
|
+
maxLength?: number;
|
|
108
|
+
minLength?: number;
|
|
109
|
+
pattern?: string;
|
|
110
|
+
maxItems?: number;
|
|
111
|
+
minItems?: number;
|
|
112
|
+
uniqueItems?: boolean;
|
|
113
|
+
maxProperties?: number;
|
|
114
|
+
minProperties?: number;
|
|
115
|
+
required?: string[];
|
|
116
|
+
enum?: any[];
|
|
117
|
+
prefixItems?: (SchemaObject | ReferenceObject)[];
|
|
118
|
+
contentMediaType?: string;
|
|
119
|
+
contentEncoding?: string;
|
|
120
|
+
}
|
|
121
|
+
interface DiscriminatorObject {
|
|
122
|
+
propertyName: string;
|
|
123
|
+
mapping?: {
|
|
124
|
+
[key: string]: string;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
interface XmlObject extends ISpecificationExtension {
|
|
128
|
+
name?: string;
|
|
129
|
+
namespace?: string;
|
|
130
|
+
prefix?: string;
|
|
131
|
+
attribute?: boolean;
|
|
132
|
+
wrapped?: boolean;
|
|
133
|
+
}
|
|
134
|
+
type ZodOpenApiOverrideMetaContext = OverrideSchemaParameters;
|
|
135
|
+
type ZodOpenApiOverrideMeta = (ctx: ZodOpenApiOverrideMetaContext) => void;
|
|
136
|
+
interface ZodOpenApiBaseMetadata {
|
|
137
|
+
/**
|
|
138
|
+
* Used to set metadata for a parameter
|
|
139
|
+
*/
|
|
140
|
+
param?: Partial<ParameterObject> & {
|
|
141
|
+
/**
|
|
142
|
+
* Used to output this Zod Schema in the components parameters section. Any usage of this Zod Schema will then be transformed into a $ref.
|
|
143
|
+
*/
|
|
144
|
+
id?: string;
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* Used to set metadata for a response header
|
|
148
|
+
*/
|
|
149
|
+
header?: Partial<HeaderObject> & {
|
|
150
|
+
/**
|
|
151
|
+
* Used to output this Zod Schema in the components headers section. Any usage of this Zod Schema will then be transformed into a $ref.
|
|
152
|
+
*/
|
|
153
|
+
id?: string;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Use to override the rendered schema
|
|
157
|
+
*/
|
|
158
|
+
override?: SchemaObject | ZodOpenApiOverrideMeta;
|
|
159
|
+
/**
|
|
160
|
+
* For use only if this Zod Schema is manually registered in the `components` section
|
|
161
|
+
* and is not used anywhere else in the document.
|
|
162
|
+
* Defaults to `output` if not specified.
|
|
163
|
+
*/
|
|
164
|
+
unusedIO?: 'input' | 'output';
|
|
165
|
+
/**
|
|
166
|
+
* An alternate id to use for this schema in the event a registered schema is used in both a request and response schema.
|
|
167
|
+
* If not specified, the id will be simply derived as the id of the schema plus an `Output` suffix. Please note that `id` must be set.
|
|
168
|
+
*/
|
|
169
|
+
outputId?: string;
|
|
170
|
+
}
|
|
171
|
+
interface ZodOpenApiMetadata extends ZodOpenApiBaseMetadata, JSONSchemaMeta {
|
|
172
|
+
examples?: unknown[];
|
|
173
|
+
/**
|
|
174
|
+
* @deprecated - Use `examples` instead.
|
|
175
|
+
* Use of `example` is discouraged, and later versions of OpenAPI specification may remove it.
|
|
176
|
+
*/
|
|
177
|
+
example?: unknown;
|
|
178
|
+
}
|
|
179
|
+
declare module 'zod/v4' {
|
|
180
|
+
interface GlobalMeta extends ZodOpenApiMetadata {}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Trait namespace — allows multiple trait-contributing providers to register
|
|
185
|
+
* under `traits:<namespace>` and merge into the unified traits bag.
|
|
186
|
+
*
|
|
187
|
+
* SDK built-ins: `'traits:trial'`, `'traits:usage'`.
|
|
188
|
+
* Customers can register any namespace (e.g. `'traits:permissions'`,
|
|
189
|
+
* `'traits:feature_flags'`).
|
|
190
|
+
*/
|
|
191
|
+
type TraitsNamespace = `traits:${string}`;
|
|
192
|
+
/**
|
|
193
|
+
* Domain names recognized by the SDK provider registry.
|
|
194
|
+
* Each domain maps to a specific decision-engine input primitive.
|
|
195
|
+
*
|
|
196
|
+
* The `traits` domain and any `traits:<namespace>` domain are merged
|
|
197
|
+
* into a single `traits` slot in `ResolvedProviderContext`.
|
|
198
|
+
*/
|
|
199
|
+
type DomainProviderName = 'plan' | 'entitlements' | 'segments' | 'experiments' | 'content' | 'rules' | 'traits' | 'theme' | 'events' | 'cta' | TraitsNamespace;
|
|
200
|
+
/**
|
|
201
|
+
* Base interface all domain providers implement.
|
|
202
|
+
*
|
|
203
|
+
* A domain provider supplies a named slice of the decision-engine's input:
|
|
204
|
+
* current plan, entitlement state, user segments, marketing content, rules,
|
|
205
|
+
* or custom traits.
|
|
206
|
+
*/
|
|
207
|
+
interface DomainProvider<D extends DomainProviderName = DomainProviderName, T = unknown> {
|
|
208
|
+
/** Provider domain name — used as the registry key. */
|
|
209
|
+
readonly domain: D;
|
|
210
|
+
/**
|
|
211
|
+
* Resolve the current value. Called before placement decisions.
|
|
212
|
+
* May be async (e.g. reading from a database or API).
|
|
213
|
+
*/
|
|
214
|
+
resolve(): T | Promise<T>;
|
|
215
|
+
/**
|
|
216
|
+
* Optional: subscribe to changes (enables push-based invalidation).
|
|
217
|
+
* Returns an unsubscribe function.
|
|
218
|
+
*/
|
|
219
|
+
subscribe?(listener: (next: T) => void): () => void;
|
|
220
|
+
/** Cache TTL in ms. 0 = re-resolve every call (default). */
|
|
221
|
+
cacheTtlMs?: number;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* The user's experiment assignments, keyed by **experiment handle** with the
|
|
225
|
+
* assigned **variant handle** as the value (plan 183).
|
|
226
|
+
*
|
|
227
|
+
* Handles on both sides, deliberately: a handle is the canonical, version-stable
|
|
228
|
+
* identifier, which is what a `Segment.experiment_id` match and an analytics
|
|
229
|
+
* grouping must key on. The version id — which *definition* of the experiment
|
|
230
|
+
* was live — travels separately in telemetry, never as the match key.
|
|
231
|
+
*
|
|
232
|
+
* A map because a user can be enrolled in several experiments at once. Absent or
|
|
233
|
+
* empty means enrolled in nothing, which is distinct from "assigned to control".
|
|
234
|
+
*/
|
|
235
|
+
interface ExperimentProviderState {
|
|
236
|
+
/** `{ [experimentHandle]: variantHandle }`. */
|
|
237
|
+
assignments: Record<string, string>;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Supplies experiment enrollment and variant assignment.
|
|
241
|
+
*
|
|
242
|
+
* The binding declares whether RevTurbine manages the desired allocation or an
|
|
243
|
+
* external provider is authoritative. Both modes satisfy this one interface,
|
|
244
|
+
* so segment matching, decisions and telemetry never need to know which
|
|
245
|
+
* produced a value.
|
|
246
|
+
*/
|
|
247
|
+
interface ExperimentAssignmentProvider extends DomainProvider<'experiments', ExperimentProviderState> {
|
|
248
|
+
readonly domain: 'experiments';
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* GrowthBook-backed experiment assignment provider.
|
|
253
|
+
*
|
|
254
|
+
* The GrowthBook client is injected by the customer. This adapter therefore
|
|
255
|
+
* evaluates the customer's real GrowthBook instance without bundling its SDK,
|
|
256
|
+
* fetching credentials, or accepting executable customer code.
|
|
257
|
+
*/
|
|
258
|
+
|
|
259
|
+
/** One RevTurbine experiment handle mapped to its GrowthBook feature key. */
|
|
260
|
+
interface GrowthBookExperimentBinding {
|
|
261
|
+
/** Stable RevTurbine experiment handle emitted in normalized assignments. */
|
|
262
|
+
experimentHandle: string;
|
|
263
|
+
/** GrowthBook feature key whose evaluated string value is the variant handle. */
|
|
264
|
+
featureKey: string;
|
|
265
|
+
/** Optional allowlist that rejects unexpected GrowthBook variant values. */
|
|
266
|
+
allowedVariants?: readonly string[];
|
|
267
|
+
}
|
|
268
|
+
/** Options for the separately bundled GrowthBook assignment adapter. */
|
|
269
|
+
interface GrowthBookExperimentAssignmentOptions {
|
|
270
|
+
/** An initialized customer-owned GrowthBook client. */
|
|
271
|
+
client: Pick<GrowthBook<Record<string, string>>, 'evalFeature'>;
|
|
272
|
+
/** Explicit experiment-to-feature mappings; no naming convention is assumed. */
|
|
273
|
+
bindings: readonly GrowthBookExperimentBinding[];
|
|
274
|
+
}
|
|
275
|
+
/** Machine-readable reasons a GrowthBook assignment cannot be normalized. */
|
|
276
|
+
type GrowthBookAssignmentErrorReason = 'duplicate_experiment_handle' | 'unknown_feature' | 'invalid_variant' | 'unexpected_variant';
|
|
277
|
+
/** Raised when GrowthBook cannot produce a valid normalized assignment. */
|
|
278
|
+
declare class GrowthBookAssignmentError extends Error {
|
|
279
|
+
/** Stable reason suitable for logs and error handling. */
|
|
280
|
+
readonly reason: GrowthBookAssignmentErrorReason;
|
|
281
|
+
/** RevTurbine experiment whose assignment failed. */
|
|
282
|
+
readonly experimentHandle: string;
|
|
283
|
+
/** GrowthBook feature evaluated for the assignment. */
|
|
284
|
+
readonly featureKey: string;
|
|
285
|
+
/** Construct a named GrowthBook normalization failure. */
|
|
286
|
+
constructor(reason: GrowthBookAssignmentErrorReason, binding: GrowthBookExperimentBinding, detail: string);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Create an assignment provider backed by an initialized GrowthBook client.
|
|
290
|
+
*
|
|
291
|
+
* Each GrowthBook feature must evaluate to a non-empty string variant handle.
|
|
292
|
+
* Unknown features and invalid values fail explicitly instead of being
|
|
293
|
+
* converted to an empty assignment or fabricated fallback.
|
|
294
|
+
*/
|
|
295
|
+
declare function createGrowthBookExperimentAssignmentProvider(options: GrowthBookExperimentAssignmentOptions): ExperimentAssignmentProvider;
|
|
296
|
+
|
|
297
|
+
export { GrowthBookAssignmentError, createGrowthBookExperimentAssignmentProvider };
|
|
298
|
+
export type { GrowthBookAssignmentErrorReason, GrowthBookExperimentAssignmentOptions, GrowthBookExperimentBinding };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var s=Object.defineProperty;var d=(r,n,e)=>n in r?s(r,n,{enumerable:true,configurable:true,writable:true,value:e}):r[n]=e;var i=(r,n,e)=>d(r,typeof n!="symbol"?n+"":n,e);var o=class extends Error{constructor(e,t,a){super(`GrowthBook assignment for experiment "${t.experimentHandle}" (feature "${t.featureKey}") failed: ${a}`);i(this,"reason");i(this,"experimentHandle");i(this,"featureKey");this.name="GrowthBookAssignmentError",this.reason=e,this.experimentHandle=t.experimentHandle,this.featureKey=t.featureKey;}};function m(r){let n=new Set;for(let e of r){if(n.has(e.experimentHandle))throw new o("duplicate_experiment_handle",e,"the experiment handle is mapped more than once");n.add(e.experimentHandle);}}function p(r){return m(r.bindings),{domain:"experiments",resolve(){let n={};for(let e of r.bindings){let t=r.client.evalFeature(e.featureKey);if(t.source==="unknownFeature")throw new o("unknown_feature",e,"GrowthBook reported an unknown feature");if(typeof t.value!="string"||t.value.length===0)throw new o("invalid_variant",e,"the evaluated value must be a non-empty string variant handle");if(e.allowedVariants&&!e.allowedVariants.includes(t.value))throw new o("unexpected_variant",e,`variant "${t.value}" is outside the configured allowlist`);n[e.experimentHandle]=t.value;}return {assignments:n}}}}export{o as GrowthBookAssignmentError,p as createGrowthBookExperimentAssignmentProvider};//# sourceMappingURL=growthbook.js.map
|
|
2
|
+
//# sourceMappingURL=growthbook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../providers/growthbook-experiment-provider.ts"],"names":["GrowthBookAssignmentError","reason","binding","detail","__publicField","validateBindings","bindings","handles","createGrowthBookExperimentAssignmentProvider","options","assignments","result"],"mappings":"AAuCO,IAAA,CAAA,CAAA,MAAA,CAAA,cAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,UAAA,CAAA,IAAA,CAAA,YAAA,CAAA,IAAA,CAAA,QAAA,CAAA,IAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,OAAA,CAAA,EAAA,QAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,IAAMA,EAAN,cAAwC,KAAM,CASnD,WAAA,CACEC,EACAC,CAAAA,CACAC,CAAAA,CACA,CACA,KAAA,CACE,yCAAyCD,CAAAA,CAAQ,gBAAgB,eAClDA,CAAAA,CAAQ,UAAU,cAAcC,CAAM,CAAA,CACvD,CAAA,CAfFC,CAAAA,CAAA,KAAS,QAAA,CAAA,CAETA,CAAAA,CAAA,KAAS,kBAAA,CAAA,CAETA,CAAAA,CAAA,KAAS,YAAA,CAAA,CAYP,IAAA,CAAK,IAAA,CAAO,2BAAA,CACZ,KAAK,MAAA,CAASH,CAAAA,CACd,KAAK,gBAAA,CAAmBC,CAAAA,CAAQ,iBAChC,IAAA,CAAK,UAAA,CAAaA,CAAAA,CAAQ,WAC5B,CACF,EAEA,SAASG,CAAAA,CAAiBC,CAAAA,CAAwD,CAChF,IAAMC,CAAAA,CAAU,IAAI,GAAA,CACpB,QAAWL,CAAAA,IAAWI,CAAAA,CAAU,CAC9B,GAAIC,CAAAA,CAAQ,IAAIL,CAAAA,CAAQ,gBAAgB,CAAA,CACtC,MAAM,IAAIF,CAAAA,CACR,6BAAA,CACAE,EACA,gDACF,CAAA,CAEFK,EAAQ,GAAA,CAAIL,CAAAA,CAAQ,gBAAgB,EACtC,CACF,CASO,SAASM,EACdC,CAAAA,CAC8B,CAC9B,OAAAJ,CAAAA,CAAiBI,CAAAA,CAAQ,QAAQ,CAAA,CAE1B,CACL,MAAA,CAAQ,aAAA,CACR,OAAA,EAAmC,CACjC,IAAMC,CAAAA,CAAsC,EAAC,CAE7C,IAAA,IAAWR,KAAWO,CAAAA,CAAQ,QAAA,CAAU,CACtC,IAAME,CAAAA,CAASF,EAAQ,MAAA,CAAO,WAAA,CAAYP,CAAAA,CAAQ,UAAU,EAC5D,GAAIS,CAAAA,CAAO,SAAW,gBAAA,CACpB,MAAM,IAAIX,CAAAA,CACR,iBAAA,CACAE,CAAAA,CACA,wCACF,EAGF,GAAI,OAAOS,EAAO,KAAA,EAAU,QAAA,EAAYA,EAAO,KAAA,CAAM,MAAA,GAAW,CAAA,CAC9D,MAAM,IAAIX,CAAAA,CACR,iBAAA,CACAE,CAAAA,CACA,+DACF,EAGF,GAAIA,CAAAA,CAAQ,eAAA,EAAmB,CAACA,EAAQ,eAAA,CAAgB,QAAA,CAASS,EAAO,KAAK,CAAA,CAC3E,MAAM,IAAIX,CAAAA,CACR,oBAAA,CACAE,CAAAA,CACA,YAAYS,CAAAA,CAAO,KAAK,uCAC1B,CAAA,CAGFD,CAAAA,CAAYR,EAAQ,gBAAgB,CAAA,CAAIS,CAAAA,CAAO,MACjD,CAEA,OAAO,CAAE,YAAAD,CAAY,CACvB,CACF,CACF","file":"growthbook.js","sourcesContent":["/**\n * GrowthBook-backed experiment assignment provider.\n *\n * The GrowthBook client is injected by the customer. This adapter therefore\n * evaluates the customer's real GrowthBook instance without bundling its SDK,\n * fetching credentials, or accepting executable customer code.\n */\nimport type { GrowthBook } from '@growthbook/growthbook';\nimport type {\n ExperimentAssignmentProvider,\n ExperimentProviderState,\n} from '@revt-eng/core';\n\n/** One RevTurbine experiment handle mapped to its GrowthBook feature key. */\nexport interface GrowthBookExperimentBinding {\n /** Stable RevTurbine experiment handle emitted in normalized assignments. */\n experimentHandle: string;\n /** GrowthBook feature key whose evaluated string value is the variant handle. */\n featureKey: string;\n /** Optional allowlist that rejects unexpected GrowthBook variant values. */\n allowedVariants?: readonly string[];\n}\n\n/** Options for the separately bundled GrowthBook assignment adapter. */\nexport interface GrowthBookExperimentAssignmentOptions {\n /** An initialized customer-owned GrowthBook client. */\n client: Pick<GrowthBook<Record<string, string>>, 'evalFeature'>;\n /** Explicit experiment-to-feature mappings; no naming convention is assumed. */\n bindings: readonly GrowthBookExperimentBinding[];\n}\n\n/** Machine-readable reasons a GrowthBook assignment cannot be normalized. */\nexport type GrowthBookAssignmentErrorReason =\n | 'duplicate_experiment_handle'\n | 'unknown_feature'\n | 'invalid_variant'\n | 'unexpected_variant';\n\n/** Raised when GrowthBook cannot produce a valid normalized assignment. */\nexport class GrowthBookAssignmentError extends Error {\n /** Stable reason suitable for logs and error handling. */\n readonly reason: GrowthBookAssignmentErrorReason;\n /** RevTurbine experiment whose assignment failed. */\n readonly experimentHandle: string;\n /** GrowthBook feature evaluated for the assignment. */\n readonly featureKey: string;\n\n /** Construct a named GrowthBook normalization failure. */\n constructor(\n reason: GrowthBookAssignmentErrorReason,\n binding: GrowthBookExperimentBinding,\n detail: string,\n ) {\n super(\n `GrowthBook assignment for experiment \"${binding.experimentHandle}\" `\n + `(feature \"${binding.featureKey}\") failed: ${detail}`,\n );\n this.name = 'GrowthBookAssignmentError';\n this.reason = reason;\n this.experimentHandle = binding.experimentHandle;\n this.featureKey = binding.featureKey;\n }\n}\n\nfunction validateBindings(bindings: readonly GrowthBookExperimentBinding[]): void {\n const handles = new Set<string>();\n for (const binding of bindings) {\n if (handles.has(binding.experimentHandle)) {\n throw new GrowthBookAssignmentError(\n 'duplicate_experiment_handle',\n binding,\n 'the experiment handle is mapped more than once',\n );\n }\n handles.add(binding.experimentHandle);\n }\n}\n\n/**\n * Create an assignment provider backed by an initialized GrowthBook client.\n *\n * Each GrowthBook feature must evaluate to a non-empty string variant handle.\n * Unknown features and invalid values fail explicitly instead of being\n * converted to an empty assignment or fabricated fallback.\n */\nexport function createGrowthBookExperimentAssignmentProvider(\n options: GrowthBookExperimentAssignmentOptions,\n): ExperimentAssignmentProvider {\n validateBindings(options.bindings);\n\n return {\n domain: 'experiments',\n resolve(): ExperimentProviderState {\n const assignments: Record<string, string> = {};\n\n for (const binding of options.bindings) {\n const result = options.client.evalFeature(binding.featureKey);\n if (result.source === 'unknownFeature') {\n throw new GrowthBookAssignmentError(\n 'unknown_feature',\n binding,\n 'GrowthBook reported an unknown feature',\n );\n }\n\n if (typeof result.value !== 'string' || result.value.length === 0) {\n throw new GrowthBookAssignmentError(\n 'invalid_variant',\n binding,\n 'the evaluated value must be a non-empty string variant handle',\n );\n }\n\n if (binding.allowedVariants && !binding.allowedVariants.includes(result.value)) {\n throw new GrowthBookAssignmentError(\n 'unexpected_variant',\n binding,\n `variant \"${result.value}\" is outside the configured allowlist`,\n );\n }\n\n assignments[binding.experimentHandle] = result.value;\n }\n\n return { assignments };\n },\n };\n}\n"]}
|