@posthog/convex 0.2.33 → 1.0.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/README.md +132 -16
- package/dist/client/feature-flags/crypto.d.ts +2 -0
- package/dist/client/feature-flags/crypto.d.ts.map +1 -0
- package/dist/client/feature-flags/crypto.js +11 -0
- package/dist/client/feature-flags/crypto.js.map +1 -0
- package/dist/client/feature-flags/evaluator.d.ts +47 -0
- package/dist/client/feature-flags/evaluator.d.ts.map +1 -0
- package/dist/client/feature-flags/evaluator.js +346 -0
- package/dist/client/feature-flags/evaluator.js.map +1 -0
- package/dist/client/feature-flags/index.d.ts +4 -0
- package/dist/client/feature-flags/index.d.ts.map +1 -0
- package/dist/client/feature-flags/index.js +3 -0
- package/dist/client/feature-flags/index.js.map +1 -0
- package/dist/client/feature-flags/match-property.d.ts +12 -0
- package/dist/client/feature-flags/match-property.d.ts.map +1 -0
- package/dist/client/feature-flags/match-property.js +340 -0
- package/dist/client/feature-flags/match-property.js.map +1 -0
- package/dist/client/feature-flags/types.d.ts +63 -0
- package/dist/client/feature-flags/types.d.ts.map +1 -0
- package/dist/client/feature-flags/types.js +2 -0
- package/dist/client/feature-flags/types.js.map +1 -0
- package/dist/client/index.d.ts +71 -36
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +143 -32
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/component.d.ts +8 -35
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/lib.d.ts +76 -46
- package/dist/component/lib.d.ts.map +1 -1
- package/dist/component/lib.js +311 -99
- package/dist/component/lib.js.map +1 -1
- package/dist/component/schema.d.ts +18 -1
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +16 -2
- package/dist/component/schema.js.map +1 -1
- package/dist/component/version.d.ts +2 -0
- package/dist/component/version.d.ts.map +1 -0
- package/dist/component/version.js +2 -0
- package/dist/component/version.js.map +1 -0
- package/package.json +5 -5
- package/src/client/feature-flags/crypto.ts +12 -0
- package/src/client/feature-flags/evaluator.test.ts +401 -0
- package/src/client/feature-flags/evaluator.ts +467 -0
- package/src/client/feature-flags/index.ts +15 -0
- package/src/client/feature-flags/match-property.test.ts +75 -0
- package/src/client/feature-flags/match-property.ts +347 -0
- package/src/client/feature-flags/types.ts +72 -0
- package/src/client/index.test.ts +60 -12
- package/src/client/index.ts +227 -70
- package/src/component/_generated/component.ts +7 -50
- package/src/component/lib.ts +340 -127
- package/src/component/schema.ts +16 -2
- package/src/component/version.ts +1 -0
package/src/client/index.ts
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
import type { Scheduler } from 'convex/server'
|
|
2
2
|
import type { ComponentApi } from '../component/_generated/component.js'
|
|
3
|
+
import {
|
|
4
|
+
type FeatureFlagResult,
|
|
5
|
+
type FeatureFlagValue,
|
|
6
|
+
type FlagDefinitions,
|
|
7
|
+
type JsonType,
|
|
8
|
+
LocalFeatureFlagEvaluator,
|
|
9
|
+
} from './feature-flags/index.js'
|
|
3
10
|
|
|
4
11
|
/** Context with a scheduler — available in mutations and actions. */
|
|
5
12
|
type SchedulerCtx = { scheduler: Scheduler }
|
|
6
13
|
|
|
7
|
-
/** Context with
|
|
8
|
-
type
|
|
14
|
+
/** Context with runQuery — available in queries, mutations, and actions. */
|
|
15
|
+
type RunQueryCtx = { runQuery: (reference: any, args: any) => Promise<any> }
|
|
9
16
|
|
|
10
17
|
type FeatureFlagOptions = {
|
|
11
18
|
groups?: Record<string, string>
|
|
12
|
-
personProperties?: Record<string,
|
|
13
|
-
groupProperties?: Record<string, Record<string,
|
|
14
|
-
sendFeatureFlagEvents?: boolean
|
|
19
|
+
personProperties?: Record<string, any>
|
|
20
|
+
groupProperties?: Record<string, Record<string, any>>
|
|
15
21
|
disableGeoip?: boolean
|
|
16
22
|
}
|
|
17
23
|
|
|
24
|
+
type AllFlagsOptions = FeatureFlagOptions & { flagKeys?: string[] }
|
|
25
|
+
|
|
18
26
|
const DEFAULT_HOST = 'https://us.i.posthog.com'
|
|
19
27
|
|
|
20
28
|
function normalizeApiKey(value?: unknown): string {
|
|
@@ -26,12 +34,7 @@ function normalizeHost(value?: unknown): string {
|
|
|
26
34
|
return normalizedValue || DEFAULT_HOST
|
|
27
35
|
}
|
|
28
36
|
|
|
29
|
-
export type FeatureFlagResult
|
|
30
|
-
key: string
|
|
31
|
-
enabled: boolean
|
|
32
|
-
variant: string | null
|
|
33
|
-
payload: unknown
|
|
34
|
-
}
|
|
37
|
+
export type { FeatureFlagResult, FeatureFlagValue, JsonType }
|
|
35
38
|
|
|
36
39
|
export type PostHogEvent = {
|
|
37
40
|
event: string
|
|
@@ -74,8 +77,12 @@ export function normalizeError(error: unknown): {
|
|
|
74
77
|
return { message: String(error) }
|
|
75
78
|
}
|
|
76
79
|
|
|
80
|
+
/** Context with runAction — available in actions. Used by `refreshFlagDefinitions`. */
|
|
81
|
+
type RunActionCtx = { runAction: (reference: any, args: any) => Promise<any> }
|
|
82
|
+
|
|
77
83
|
export class PostHog {
|
|
78
84
|
private apiKey: string
|
|
85
|
+
private personalApiKey: string
|
|
79
86
|
private host: string
|
|
80
87
|
private beforeSend?: BeforeSendFn | BeforeSendFn[]
|
|
81
88
|
private identifyFn?: IdentifyFn
|
|
@@ -84,17 +91,40 @@ export class PostHog {
|
|
|
84
91
|
public component: ComponentApi,
|
|
85
92
|
options?: {
|
|
86
93
|
apiKey?: string
|
|
94
|
+
/**
|
|
95
|
+
* Either a [feature flags secure API key](https://posthog.com/docs/feature-flags/local-evaluation#step-1-find-your-feature-flags-secure-api-key)
|
|
96
|
+
* (`phs_…`, recommended) or a personal API key (`phx_…`) with feature-flag read access.
|
|
97
|
+
* Required for local feature flag evaluation; defaults to `process.env.POSTHOG_PERSONAL_API_KEY`.
|
|
98
|
+
* The key is captured at construction time and forwarded to the component whenever you call
|
|
99
|
+
* `refreshFlagDefinitions(ctx)`.
|
|
100
|
+
*/
|
|
101
|
+
personalApiKey?: string
|
|
87
102
|
host?: string
|
|
88
103
|
beforeSend?: BeforeSendFn | BeforeSendFn[]
|
|
89
104
|
identify?: IdentifyFn
|
|
90
105
|
}
|
|
91
106
|
) {
|
|
92
107
|
this.apiKey = normalizeApiKey(options?.apiKey ?? process.env.POSTHOG_API_KEY)
|
|
108
|
+
this.personalApiKey = normalizeApiKey(options?.personalApiKey ?? process.env.POSTHOG_PERSONAL_API_KEY)
|
|
93
109
|
this.host = normalizeHost(options?.host ?? process.env.POSTHOG_HOST)
|
|
94
110
|
this.beforeSend = options?.beforeSend
|
|
95
111
|
this.identifyFn = options?.identify
|
|
96
112
|
}
|
|
97
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Trigger a refresh of the cached feature flag definitions. Must be called from an action
|
|
116
|
+
* context (typically a cron handler) — the component fetches `/flags/definitions` and writes
|
|
117
|
+
* the result to its singleton table. Returns the component's status object so callers can log
|
|
118
|
+
* misconfiguration without throwing.
|
|
119
|
+
*/
|
|
120
|
+
async refreshFlagDefinitions(ctx: RunActionCtx): Promise<unknown> {
|
|
121
|
+
return await ctx.runAction(this.component.lib.refreshFlagDefinitions, {
|
|
122
|
+
apiKey: this.apiKey,
|
|
123
|
+
personalApiKey: this.personalApiKey,
|
|
124
|
+
host: this.host,
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
|
|
98
128
|
private async resolveDistinctId(ctx: unknown, argsDistinctId?: string): Promise<string> {
|
|
99
129
|
if (this.identifyFn) {
|
|
100
130
|
const result = await this.identifyFn(ctx)
|
|
@@ -118,6 +148,23 @@ export class PostHog {
|
|
|
118
148
|
return result
|
|
119
149
|
}
|
|
120
150
|
|
|
151
|
+
private async loadEvaluator(ctx: RunQueryCtx): Promise<LocalFeatureFlagEvaluator | null> {
|
|
152
|
+
const row = (await ctx.runQuery(this.component.lib.getFlagDefinitions, {})) as {
|
|
153
|
+
data: string
|
|
154
|
+
fetchedAt: number
|
|
155
|
+
etag?: string
|
|
156
|
+
} | null
|
|
157
|
+
if (!row) return null
|
|
158
|
+
let parsed: FlagDefinitions
|
|
159
|
+
try {
|
|
160
|
+
parsed = JSON.parse(row.data) as FlagDefinitions
|
|
161
|
+
} catch (e) {
|
|
162
|
+
console.warn('[PostHog] Failed to parse cached flag definitions; treating as unavailable.', e)
|
|
163
|
+
return null
|
|
164
|
+
}
|
|
165
|
+
return new LocalFeatureFlagEvaluator(parsed)
|
|
166
|
+
}
|
|
167
|
+
|
|
121
168
|
// --- Fire-and-forget methods (work in mutations and actions) ---
|
|
122
169
|
|
|
123
170
|
async capture(
|
|
@@ -207,7 +254,10 @@ export class PostHog {
|
|
|
207
254
|
groupType: args.groupType,
|
|
208
255
|
groupKey: args.groupKey,
|
|
209
256
|
properties: result.properties ? JSON.stringify(result.properties) : undefined,
|
|
210
|
-
distinctId
|
|
257
|
+
// Use the post-beforeSend distinctId so any mutation (redaction, remapping) is honoured.
|
|
258
|
+
// Fall back to undefined when the result is the empty placeholder so we don't ship "" to
|
|
259
|
+
// the component (which would then send `distinct_id: ""` for a group identify).
|
|
260
|
+
distinctId: result.distinctId || undefined,
|
|
211
261
|
disableGeoip: args.disableGeoip,
|
|
212
262
|
})
|
|
213
263
|
}
|
|
@@ -271,104 +321,211 @@ export class PostHog {
|
|
|
271
321
|
})
|
|
272
322
|
}
|
|
273
323
|
|
|
274
|
-
// --- Feature flag methods (
|
|
324
|
+
// --- Feature flag methods (locally evaluated; work in queries, mutations, and actions) ---
|
|
325
|
+
//
|
|
326
|
+
// All feature flag methods evaluate flags locally against the definitions cached by the
|
|
327
|
+
// component's cron. `undefined` signals that the eval couldn't reach a verdict — either
|
|
328
|
+
// definitions haven't been fetched yet (POSTHOG_PERSONAL_API_KEY missing, or the cron hasn't
|
|
329
|
+
// run for the first time), or the flag uses features incompatible with local evaluation
|
|
330
|
+
// (experience continuity, static cohorts, properties not provided). For payload methods,
|
|
331
|
+
// `null` is reserved for the case where the flag was evaluated but matched no payload — so
|
|
332
|
+
// callers can distinguish "no payload" from "eval unavailable".
|
|
275
333
|
|
|
276
334
|
async getFeatureFlag(
|
|
277
|
-
ctx:
|
|
335
|
+
ctx: RunQueryCtx,
|
|
278
336
|
args: { key: string; distinctId?: string } & FeatureFlagOptions
|
|
279
|
-
): Promise<
|
|
337
|
+
): Promise<FeatureFlagValue | undefined> {
|
|
280
338
|
const distinctId = await this.resolveDistinctId(ctx, args.distinctId)
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
339
|
+
const evaluator = await this.loadEvaluator(ctx)
|
|
340
|
+
if (!evaluator) return undefined
|
|
341
|
+
return await evaluator.getFeatureFlag(
|
|
342
|
+
args.key,
|
|
285
343
|
distinctId,
|
|
286
|
-
|
|
344
|
+
args.groups ?? {},
|
|
345
|
+
args.personProperties ?? {},
|
|
346
|
+
args.groupProperties ?? {}
|
|
347
|
+
)
|
|
287
348
|
}
|
|
288
349
|
|
|
289
350
|
async isFeatureEnabled(
|
|
290
|
-
ctx:
|
|
351
|
+
ctx: RunQueryCtx,
|
|
291
352
|
args: { key: string; distinctId?: string } & FeatureFlagOptions
|
|
292
|
-
): Promise<boolean |
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
host: this.host,
|
|
297
|
-
...args,
|
|
298
|
-
distinctId,
|
|
299
|
-
})
|
|
353
|
+
): Promise<boolean | undefined> {
|
|
354
|
+
const value = await this.getFeatureFlag(ctx, args)
|
|
355
|
+
if (value === undefined) return undefined
|
|
356
|
+
return value !== false && value !== null
|
|
300
357
|
}
|
|
301
358
|
|
|
302
359
|
async getFeatureFlagPayload(
|
|
303
|
-
ctx:
|
|
360
|
+
ctx: RunQueryCtx,
|
|
304
361
|
args: {
|
|
305
362
|
key: string
|
|
306
363
|
distinctId?: string
|
|
307
364
|
matchValue?: boolean | string
|
|
308
365
|
} & FeatureFlagOptions
|
|
309
|
-
): Promise<
|
|
366
|
+
): Promise<JsonType | null | undefined> {
|
|
367
|
+
const evaluator = await this.loadEvaluator(ctx)
|
|
368
|
+
// `undefined` means we couldn't evaluate (no definitions cached, or the evaluator returned
|
|
369
|
+
// inconclusive). `null` means we did evaluate and there's no payload — distinguishing the
|
|
370
|
+
// two lets callers handle the "definitions not loaded yet" case explicitly.
|
|
371
|
+
if (!evaluator) return undefined
|
|
372
|
+
// When a caller supplies `matchValue` the payload lookup doesn't need a distinctId — it's a
|
|
373
|
+
// pure key+value lookup. Defer resolution until we actually need it, so callers using the
|
|
374
|
+
// "look up payload for a flag value I already evaluated" pattern don't have to configure an
|
|
375
|
+
// identify callback or pass a distinctId they don't have.
|
|
376
|
+
if (args.matchValue !== undefined) {
|
|
377
|
+
return evaluator.getFeatureFlagPayload(args.key, '', args.matchValue)
|
|
378
|
+
}
|
|
310
379
|
const distinctId = await this.resolveDistinctId(ctx, args.distinctId)
|
|
311
|
-
return await
|
|
312
|
-
|
|
313
|
-
host: this.host,
|
|
314
|
-
...args,
|
|
380
|
+
return await evaluator.getFeatureFlagPayload(
|
|
381
|
+
args.key,
|
|
315
382
|
distinctId,
|
|
316
|
-
|
|
383
|
+
undefined,
|
|
384
|
+
args.groups ?? {},
|
|
385
|
+
args.personProperties ?? {},
|
|
386
|
+
args.groupProperties ?? {}
|
|
387
|
+
)
|
|
317
388
|
}
|
|
318
389
|
|
|
319
390
|
async getFeatureFlagResult(
|
|
320
|
-
ctx:
|
|
391
|
+
ctx: RunQueryCtx,
|
|
392
|
+
args: { key: string; distinctId?: string } & FeatureFlagOptions
|
|
393
|
+
): Promise<FeatureFlagResult | undefined> {
|
|
394
|
+
const distinctId = await this.resolveDistinctId(ctx, args.distinctId)
|
|
395
|
+
const evaluator = await this.loadEvaluator(ctx)
|
|
396
|
+
if (!evaluator) return undefined
|
|
397
|
+
const result = await evaluator.getFeatureFlagResult(
|
|
398
|
+
args.key,
|
|
399
|
+
distinctId,
|
|
400
|
+
args.groups ?? {},
|
|
401
|
+
args.personProperties ?? {},
|
|
402
|
+
args.groupProperties ?? {}
|
|
403
|
+
)
|
|
404
|
+
if (!result) return undefined
|
|
405
|
+
// `null` isn't in `FeatureFlagValue`'s declared type but the evaluator handles it defensively
|
|
406
|
+
// in several places (payload lookup, flag-dependency cache). Treat it as a disabled value
|
|
407
|
+
// here so a stray `null` can't slip through as `enabled: true, variant: null`.
|
|
408
|
+
if (result.value === false || result.value === null) {
|
|
409
|
+
return { key: args.key, enabled: false, variant: null, payload: result.payload ?? null }
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
key: args.key,
|
|
413
|
+
enabled: true,
|
|
414
|
+
variant: typeof result.value === 'string' ? result.value : null,
|
|
415
|
+
payload: result.payload ?? null,
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
async getAllFlags(
|
|
420
|
+
ctx: RunQueryCtx,
|
|
421
|
+
args: { distinctId?: string } & AllFlagsOptions
|
|
422
|
+
): Promise<Record<string, FeatureFlagValue>> {
|
|
423
|
+
const distinctId = await this.resolveDistinctId(ctx, args.distinctId)
|
|
424
|
+
const evaluator = await this.loadEvaluator(ctx)
|
|
425
|
+
if (!evaluator) return {}
|
|
426
|
+
const { featureFlags } = await evaluator.getAllFlagsAndPayloads(
|
|
427
|
+
distinctId,
|
|
428
|
+
args.groups ?? {},
|
|
429
|
+
args.personProperties ?? {},
|
|
430
|
+
args.groupProperties ?? {},
|
|
431
|
+
args.flagKeys
|
|
432
|
+
)
|
|
433
|
+
return featureFlags
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
async getAllFlagsAndPayloads(
|
|
437
|
+
ctx: RunQueryCtx,
|
|
438
|
+
args: { distinctId?: string } & AllFlagsOptions
|
|
439
|
+
): Promise<{
|
|
440
|
+
featureFlags: Record<string, FeatureFlagValue>
|
|
441
|
+
featureFlagPayloads: Record<string, JsonType>
|
|
442
|
+
}> {
|
|
443
|
+
const distinctId = await this.resolveDistinctId(ctx, args.distinctId)
|
|
444
|
+
const evaluator = await this.loadEvaluator(ctx)
|
|
445
|
+
if (!evaluator) return { featureFlags: {}, featureFlagPayloads: {} }
|
|
446
|
+
return await evaluator.getAllFlagsAndPayloads(
|
|
447
|
+
distinctId,
|
|
448
|
+
args.groups ?? {},
|
|
449
|
+
args.personProperties ?? {},
|
|
450
|
+
args.groupProperties ?? {},
|
|
451
|
+
args.flagKeys
|
|
452
|
+
)
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// --- Remote feature flag evaluation (action context) ---
|
|
456
|
+
//
|
|
457
|
+
// For flags that can't be evaluated locally — experience continuity, static cohorts,
|
|
458
|
+
// properties you can't pass in — or when you haven't configured a personal API key. These
|
|
459
|
+
// hit PostHog's `/flags` endpoint via a component action, so they require an action ctx and
|
|
460
|
+
// incur a per-call network round trip.
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Evaluate a single flag remotely against PostHog's `/flags` endpoint. Action context only.
|
|
464
|
+
* Returns the flag value, or `null` if the flag doesn't exist.
|
|
465
|
+
*/
|
|
466
|
+
async evaluateFlag(
|
|
467
|
+
ctx: RunActionCtx,
|
|
321
468
|
args: { key: string; distinctId?: string } & FeatureFlagOptions
|
|
322
|
-
): Promise<
|
|
469
|
+
): Promise<FeatureFlagValue | null> {
|
|
323
470
|
const distinctId = await this.resolveDistinctId(ctx, args.distinctId)
|
|
324
|
-
return await ctx.runAction(this.component.lib.
|
|
471
|
+
return (await ctx.runAction(this.component.lib.evaluateFlag, {
|
|
325
472
|
apiKey: this.apiKey,
|
|
326
473
|
host: this.host,
|
|
327
|
-
|
|
474
|
+
key: args.key,
|
|
328
475
|
distinctId,
|
|
329
|
-
|
|
476
|
+
groups: args.groups,
|
|
477
|
+
personProperties: args.personProperties,
|
|
478
|
+
groupProperties: args.groupProperties,
|
|
479
|
+
disableGeoip: args.disableGeoip,
|
|
480
|
+
})) as FeatureFlagValue | null
|
|
330
481
|
}
|
|
331
482
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
flagKeys?: string[]
|
|
341
|
-
}
|
|
342
|
-
): Promise<Record<string, boolean | string>> {
|
|
483
|
+
/**
|
|
484
|
+
* Evaluate a single flag's payload remotely against PostHog's `/flags` endpoint. Action context
|
|
485
|
+
* only. Returns the payload, or `null` if the flag doesn't match or has no payload configured.
|
|
486
|
+
*/
|
|
487
|
+
async evaluateFlagPayload(
|
|
488
|
+
ctx: RunActionCtx,
|
|
489
|
+
args: { key: string; distinctId?: string } & FeatureFlagOptions
|
|
490
|
+
): Promise<JsonType | null> {
|
|
343
491
|
const distinctId = await this.resolveDistinctId(ctx, args.distinctId)
|
|
344
|
-
return await ctx.runAction(this.component.lib.
|
|
492
|
+
return (await ctx.runAction(this.component.lib.evaluateFlagPayload, {
|
|
345
493
|
apiKey: this.apiKey,
|
|
346
494
|
host: this.host,
|
|
347
|
-
|
|
495
|
+
key: args.key,
|
|
348
496
|
distinctId,
|
|
349
|
-
|
|
497
|
+
groups: args.groups,
|
|
498
|
+
personProperties: args.personProperties,
|
|
499
|
+
groupProperties: args.groupProperties,
|
|
500
|
+
disableGeoip: args.disableGeoip,
|
|
501
|
+
})) as JsonType | null
|
|
350
502
|
}
|
|
351
503
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
flagKeys?: string[]
|
|
361
|
-
}
|
|
504
|
+
/**
|
|
505
|
+
* Evaluate every flag for the user remotely in one `/flags` request. Action context only.
|
|
506
|
+
* Returns both `featureFlags` (key → value) and `featureFlagPayloads` (key → payload). Use
|
|
507
|
+
* `flagKeys` to scope the request to a specific subset.
|
|
508
|
+
*/
|
|
509
|
+
async evaluateAllFlags(
|
|
510
|
+
ctx: RunActionCtx,
|
|
511
|
+
args: { distinctId?: string } & AllFlagsOptions
|
|
362
512
|
): Promise<{
|
|
363
|
-
featureFlags: Record<string,
|
|
364
|
-
featureFlagPayloads: Record<string,
|
|
513
|
+
featureFlags: Record<string, FeatureFlagValue>
|
|
514
|
+
featureFlagPayloads: Record<string, JsonType>
|
|
365
515
|
}> {
|
|
366
516
|
const distinctId = await this.resolveDistinctId(ctx, args.distinctId)
|
|
367
|
-
return await ctx.runAction(this.component.lib.
|
|
517
|
+
return (await ctx.runAction(this.component.lib.evaluateAllFlags, {
|
|
368
518
|
apiKey: this.apiKey,
|
|
369
519
|
host: this.host,
|
|
370
|
-
...args,
|
|
371
520
|
distinctId,
|
|
372
|
-
|
|
521
|
+
groups: args.groups,
|
|
522
|
+
personProperties: args.personProperties,
|
|
523
|
+
groupProperties: args.groupProperties,
|
|
524
|
+
disableGeoip: args.disableGeoip,
|
|
525
|
+
flagKeys: args.flagKeys,
|
|
526
|
+
})) as {
|
|
527
|
+
featureFlags: Record<string, FeatureFlagValue>
|
|
528
|
+
featureFlagPayloads: Record<string, JsonType>
|
|
529
|
+
}
|
|
373
530
|
}
|
|
374
531
|
}
|
|
@@ -70,7 +70,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
70
70
|
any,
|
|
71
71
|
Name
|
|
72
72
|
>;
|
|
73
|
-
|
|
73
|
+
evaluateAllFlags: FunctionReference<
|
|
74
74
|
"action",
|
|
75
75
|
"internal",
|
|
76
76
|
{
|
|
@@ -86,7 +86,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
86
86
|
any,
|
|
87
87
|
Name
|
|
88
88
|
>;
|
|
89
|
-
|
|
89
|
+
evaluateFlag: FunctionReference<
|
|
90
90
|
"action",
|
|
91
91
|
"internal",
|
|
92
92
|
{
|
|
@@ -97,63 +97,30 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
97
97
|
groupProperties?: any;
|
|
98
98
|
groups?: any;
|
|
99
99
|
host: string;
|
|
100
|
-
personProperties?: any;
|
|
101
|
-
},
|
|
102
|
-
any,
|
|
103
|
-
Name
|
|
104
|
-
>;
|
|
105
|
-
getFeatureFlag: FunctionReference<
|
|
106
|
-
"action",
|
|
107
|
-
"internal",
|
|
108
|
-
{
|
|
109
|
-
apiKey: string;
|
|
110
|
-
disableGeoip?: boolean;
|
|
111
|
-
distinctId: string;
|
|
112
|
-
groupProperties?: any;
|
|
113
|
-
groups?: any;
|
|
114
|
-
host: string;
|
|
115
|
-
key: string;
|
|
116
|
-
personProperties?: any;
|
|
117
|
-
sendFeatureFlagEvents?: boolean;
|
|
118
|
-
},
|
|
119
|
-
any,
|
|
120
|
-
Name
|
|
121
|
-
>;
|
|
122
|
-
getFeatureFlagPayload: FunctionReference<
|
|
123
|
-
"action",
|
|
124
|
-
"internal",
|
|
125
|
-
{
|
|
126
|
-
apiKey: string;
|
|
127
|
-
disableGeoip?: boolean;
|
|
128
|
-
distinctId: string;
|
|
129
|
-
groupProperties?: any;
|
|
130
|
-
groups?: any;
|
|
131
|
-
host: string;
|
|
132
100
|
key: string;
|
|
133
|
-
matchValue?: string | boolean;
|
|
134
101
|
personProperties?: any;
|
|
135
|
-
sendFeatureFlagEvents?: boolean;
|
|
136
102
|
},
|
|
137
103
|
any,
|
|
138
104
|
Name
|
|
139
105
|
>;
|
|
140
|
-
|
|
106
|
+
evaluateFlagPayload: FunctionReference<
|
|
141
107
|
"action",
|
|
142
108
|
"internal",
|
|
143
109
|
{
|
|
144
110
|
apiKey: string;
|
|
145
111
|
disableGeoip?: boolean;
|
|
146
112
|
distinctId: string;
|
|
113
|
+
flagKeys?: Array<string>;
|
|
147
114
|
groupProperties?: any;
|
|
148
115
|
groups?: any;
|
|
149
116
|
host: string;
|
|
150
117
|
key: string;
|
|
151
118
|
personProperties?: any;
|
|
152
|
-
sendFeatureFlagEvents?: boolean;
|
|
153
119
|
},
|
|
154
120
|
any,
|
|
155
121
|
Name
|
|
156
122
|
>;
|
|
123
|
+
getFlagDefinitions: FunctionReference<"query", "internal", {}, any, Name>;
|
|
157
124
|
groupIdentify: FunctionReference<
|
|
158
125
|
"action",
|
|
159
126
|
"internal",
|
|
@@ -182,20 +149,10 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
182
149
|
any,
|
|
183
150
|
Name
|
|
184
151
|
>;
|
|
185
|
-
|
|
152
|
+
refreshFlagDefinitions: FunctionReference<
|
|
186
153
|
"action",
|
|
187
154
|
"internal",
|
|
188
|
-
{
|
|
189
|
-
apiKey: string;
|
|
190
|
-
disableGeoip?: boolean;
|
|
191
|
-
distinctId: string;
|
|
192
|
-
groupProperties?: any;
|
|
193
|
-
groups?: any;
|
|
194
|
-
host: string;
|
|
195
|
-
key: string;
|
|
196
|
-
personProperties?: any;
|
|
197
|
-
sendFeatureFlagEvents?: boolean;
|
|
198
|
-
},
|
|
155
|
+
{ apiKey: string; host?: string; personalApiKey: string },
|
|
199
156
|
any,
|
|
200
157
|
Name
|
|
201
158
|
>;
|