@quonfig/node 0.0.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.
@@ -0,0 +1,755 @@
1
+ type ValueType = "bool" | "int" | "double" | "string" | "json" | "string_list" | "log_level" | "weighted_values" | "schema" | "provided" | "duration";
2
+ type ConfigTypeString = "feature_flag" | "config" | "segment" | "log_level" | "schema";
3
+ interface ProvidedData {
4
+ source: string;
5
+ lookup: string;
6
+ }
7
+ interface WeightedValue {
8
+ weight: number;
9
+ value: Value;
10
+ }
11
+ interface WeightedValuesData {
12
+ weightedValues: WeightedValue[];
13
+ hashByPropertyName?: string;
14
+ }
15
+ interface SchemaData {
16
+ schemaType: string;
17
+ schema: string;
18
+ }
19
+ interface Value {
20
+ type: ValueType;
21
+ value: any;
22
+ confidential?: boolean;
23
+ decryptWith?: string;
24
+ }
25
+ interface Criterion {
26
+ propertyName?: string;
27
+ operator: string;
28
+ valueToMatch?: Value;
29
+ }
30
+ interface Rule {
31
+ criteria: Criterion[];
32
+ value: Value;
33
+ }
34
+ interface RuleSet {
35
+ rules: Rule[];
36
+ }
37
+ interface Environment {
38
+ id: string;
39
+ rules: Rule[];
40
+ }
41
+ interface ConfigResponse {
42
+ id: string;
43
+ key: string;
44
+ type: ConfigTypeString;
45
+ valueType: ValueType;
46
+ sendToClientSdk: boolean;
47
+ default: RuleSet;
48
+ environment?: Environment;
49
+ }
50
+ interface Meta {
51
+ version: string;
52
+ environment: string;
53
+ workspaceId?: string;
54
+ }
55
+ interface ConfigEnvelope {
56
+ configs: ConfigResponse[];
57
+ meta: Meta;
58
+ }
59
+ type ContextValue = string | number | boolean | string[] | null | undefined;
60
+ type Contexts = {
61
+ [contextName: string]: {
62
+ [key: string]: ContextValue;
63
+ };
64
+ };
65
+ type GetValue = string | number | boolean | string[] | undefined;
66
+ type OnNoDefault = "error" | "warn" | "ignore";
67
+ type ContextUploadMode = "none" | "shapes_only" | "periodic_example";
68
+ interface QuonfigOptions {
69
+ sdkKey: string;
70
+ apiUrl?: string;
71
+ /** Base URL for the dedicated telemetry service. Defaults to https://telemetry.quonfig.com. Overridden by QUONFIG_TELEMETRY_URL env var. */
72
+ telemetryUrl?: string;
73
+ enableSSE?: boolean;
74
+ enablePolling?: boolean;
75
+ pollInterval?: number;
76
+ namespace?: string;
77
+ globalContext?: Contexts;
78
+ onNoDefault?: OnNoDefault;
79
+ collectEvaluationSummaries?: boolean;
80
+ collectLoggerCounts?: boolean;
81
+ contextUploadMode?: ContextUploadMode;
82
+ initTimeout?: number;
83
+ datafile?: string | object;
84
+ }
85
+ interface EvalMatch {
86
+ isMatch: boolean;
87
+ value?: Value;
88
+ ruleIndex: number;
89
+ weightedValueIndex: number;
90
+ }
91
+ type LogLevelName = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
92
+ type LogLevelNumber = 1 | 2 | 3 | 5 | 6 | 9;
93
+ interface EvaluationCounter {
94
+ configId: string;
95
+ conditionalValueIndex: number;
96
+ configRowIndex: number;
97
+ selectedValue: any;
98
+ count: number;
99
+ weightedValueIndex?: number;
100
+ }
101
+ interface EvaluationSummary {
102
+ key: string;
103
+ type: string;
104
+ counters: EvaluationCounter[];
105
+ }
106
+ interface ContextShape {
107
+ name: string;
108
+ fieldTypes: {
109
+ [key: string]: number;
110
+ };
111
+ }
112
+ interface ExampleContextEntry {
113
+ timestamp: number;
114
+ contextSet: {
115
+ contexts: Array<{
116
+ type: string;
117
+ values: {
118
+ [key: string]: any;
119
+ };
120
+ }>;
121
+ };
122
+ }
123
+ interface TelemetryEvent {
124
+ summaries?: {
125
+ start: number;
126
+ end: number;
127
+ summaries: EvaluationSummary[];
128
+ };
129
+ contextShapes?: {
130
+ shapes: ContextShape[];
131
+ };
132
+ exampleContexts?: {
133
+ examples: ExampleContextEntry[];
134
+ };
135
+ }
136
+ interface Evaluation {
137
+ configId: string;
138
+ configKey: string;
139
+ configType: ConfigTypeString;
140
+ unwrappedValue: GetValue;
141
+ reportableValue?: GetValue;
142
+ ruleIndex: number;
143
+ weightedValueIndex?: number;
144
+ }
145
+ declare const ConfigType: {
146
+ readonly FeatureFlag: ConfigTypeString;
147
+ readonly Config: ConfigTypeString;
148
+ readonly Segment: ConfigTypeString;
149
+ readonly LogLevel: ConfigTypeString;
150
+ readonly Schema: ConfigTypeString;
151
+ };
152
+ declare const ProvidedSource: {
153
+ readonly EnvVar: "ENV_VAR";
154
+ };
155
+ interface NodeServerConfigurationRaw {
156
+ }
157
+ interface NodeServerConfigurationAccessor {
158
+ }
159
+ type TypedNodeServerConfigurationRaw = NodeServerConfigurationRaw;
160
+ type TypedNodeServerConfigurationAccessor = NodeServerConfigurationAccessor;
161
+
162
+ /**
163
+ * BoundQuonfig is a Quonfig client bound to a specific context.
164
+ * All get* calls automatically include the bound context.
165
+ */
166
+ declare class BoundQuonfig {
167
+ private client;
168
+ private boundContexts;
169
+ constructor(client: Quonfig, contexts: Contexts);
170
+ get(key: string, contexts?: Contexts, defaultValue?: any): any;
171
+ getString(key: string, contexts?: Contexts): string | undefined;
172
+ getNumber(key: string, contexts?: Contexts): number | undefined;
173
+ getBool(key: string, contexts?: Contexts): boolean | undefined;
174
+ getStringList(key: string, contexts?: Contexts): string[] | undefined;
175
+ getDuration(key: string, contexts?: Contexts): number | undefined;
176
+ getJSON(key: string, contexts?: Contexts): any;
177
+ isFeatureEnabled(key: string, contexts?: Contexts): boolean;
178
+ shouldLog(args: {
179
+ loggerName: string;
180
+ desiredLevel: string;
181
+ defaultLevel?: string;
182
+ contexts?: Contexts;
183
+ }): boolean;
184
+ keys(): string[];
185
+ inContext(contexts: Contexts): BoundQuonfig;
186
+ }
187
+ /**
188
+ * Quonfig is the main SDK client.
189
+ *
190
+ * Usage:
191
+ * ```typescript
192
+ * const quonfig = new Quonfig({ sdkKey: "your-key" });
193
+ * await quonfig.init();
194
+ * const value = quonfig.get("my-config");
195
+ * ```
196
+ */
197
+ declare class Quonfig {
198
+ private readonly sdkKey;
199
+ private readonly apiUrl;
200
+ private readonly telemetryUrl?;
201
+ private readonly enableSSE;
202
+ private readonly enablePolling;
203
+ private readonly pollInterval;
204
+ private readonly namespace?;
205
+ private readonly onNoDefault;
206
+ private readonly globalContext?;
207
+ private readonly initTimeout;
208
+ private readonly datafile?;
209
+ private store;
210
+ private evaluator;
211
+ private resolver;
212
+ private transport;
213
+ private sseConnection?;
214
+ private pollTimer?;
215
+ private telemetryReporter?;
216
+ private instanceHash;
217
+ private environmentId;
218
+ private initialized;
219
+ private evaluationSummaries;
220
+ private contextShapes;
221
+ private exampleContexts;
222
+ constructor(options: QuonfigOptions);
223
+ /**
224
+ * Initialize the SDK. Downloads configs from the API (or loads from datafile)
225
+ * and starts background update mechanisms (SSE/polling).
226
+ *
227
+ * Must be called before using any get* methods.
228
+ */
229
+ init(): Promise<void>;
230
+ /**
231
+ * Get a config value by key. Evaluates rules against the provided context.
232
+ */
233
+ get(key: string, contexts?: Contexts, defaultValue?: any): any;
234
+ /**
235
+ * Get a string config value.
236
+ */
237
+ getString(key: string, contexts?: Contexts): string | undefined;
238
+ /**
239
+ * Get a number config value.
240
+ */
241
+ getNumber(key: string, contexts?: Contexts): number | undefined;
242
+ /**
243
+ * Get a boolean config value.
244
+ */
245
+ getBool(key: string, contexts?: Contexts): boolean | undefined;
246
+ /**
247
+ * Get a string list config value.
248
+ */
249
+ getStringList(key: string, contexts?: Contexts): string[] | undefined;
250
+ /**
251
+ * Get a duration config value in milliseconds.
252
+ */
253
+ getDuration(key: string, contexts?: Contexts): number | undefined;
254
+ /**
255
+ * Get a JSON config value (parsed).
256
+ */
257
+ getJSON(key: string, contexts?: Contexts): any;
258
+ /**
259
+ * Check if a feature flag is enabled.
260
+ * Returns false if the key is not found or the value is not a boolean.
261
+ */
262
+ isFeatureEnabled(key: string, contexts?: Contexts): boolean;
263
+ /**
264
+ * Check if a log message should be logged at the given level.
265
+ */
266
+ shouldLog(args: {
267
+ loggerName: string;
268
+ desiredLevel: string;
269
+ defaultLevel?: string;
270
+ contexts?: Contexts;
271
+ }): boolean;
272
+ /**
273
+ * Get all config keys currently in the store.
274
+ */
275
+ keys(): string[];
276
+ /**
277
+ * Get the raw ConfigResponse for a key (for advanced usage / CLI tooling).
278
+ */
279
+ rawConfig(key: string): ConfigResponse | undefined;
280
+ /**
281
+ * Create a BoundQuonfig with the given context baked in.
282
+ */
283
+ inContext(contexts: Contexts): BoundQuonfig;
284
+ /**
285
+ * Close the SDK. Stops SSE, polling, and telemetry.
286
+ */
287
+ close(): void;
288
+ private requireInitialized;
289
+ private handleNoDefault;
290
+ private loadDatafile;
291
+ private fetchAndInstall;
292
+ private startSSE;
293
+ private startPolling;
294
+ private startTelemetry;
295
+ }
296
+
297
+ /**
298
+ * Look up a property value from contexts using dotted notation.
299
+ * "user.email" -> contexts["user"]["email"]
300
+ * If there is no dot, look up in the unnamed ("") context: "domain" -> contexts[""]["domain"]
301
+ */
302
+ declare function contextLookup(contexts: Contexts, propertyName: string | undefined): ContextValue | undefined;
303
+ /**
304
+ * Merge multiple context sets. Later sets override earlier ones at the key level
305
+ * within each named context.
306
+ */
307
+ declare function mergeContexts(...sets: (Contexts | undefined)[]): Contexts;
308
+ /**
309
+ * Get context value with support for magic properties.
310
+ * "prefab.current-time" and "quonfig.current-time" return current UTC millis.
311
+ */
312
+ declare function getContextValue(contexts: Contexts, propertyName: string): {
313
+ value: any;
314
+ exists: boolean;
315
+ };
316
+
317
+ /**
318
+ * Generate a new random hex-encoded 32-byte key for AES-256-GCM encryption.
319
+ */
320
+ declare function generateNewHexKey(): string;
321
+ /**
322
+ * Encrypt a string using AES-256-GCM.
323
+ *
324
+ * Returns a string in format: "DATA--IV--AUTH_TAG" where each part is hex-encoded.
325
+ */
326
+ declare function encrypt(clearText: string, keyStringHex: string): string;
327
+ /**
328
+ * Decrypt an AES-256-GCM encrypted value.
329
+ *
330
+ * The encrypted string must be in format: "DATA--IV--AUTH_TAG" where each part is hex-encoded.
331
+ */
332
+ declare function decrypt(encryptedString: string, keyStringHex: string): string;
333
+
334
+ /**
335
+ * Parse an ISO 8601 duration string and return the number of milliseconds.
336
+ *
337
+ * Supports formats like: PT0.2S, PT90S, PT1.5M, PT0.5H, P1DT6H2M1.5S
338
+ */
339
+ declare function durationToMilliseconds(duration: string): number;
340
+
341
+ interface SemanticVersion {
342
+ major: number;
343
+ minor: number;
344
+ patch: number;
345
+ prerelease: string;
346
+ buildMetadata: string;
347
+ }
348
+ /**
349
+ * Parse a semantic version string. Returns undefined if invalid.
350
+ */
351
+ declare function parseSemver(version: string): SemanticVersion | undefined;
352
+ /**
353
+ * Compare two semantic versions.
354
+ * Returns -1 if a < b, 0 if a == b, 1 if a > b.
355
+ */
356
+ declare function compareSemver(a: SemanticVersion, b: SemanticVersion): number;
357
+
358
+ /**
359
+ * Hash a string to a float64 in [0, 1) using Murmur3.
360
+ * This matches the Go SDK's HashZeroToOne implementation.
361
+ */
362
+ declare function hashZeroToOne(value: string): number;
363
+
364
+ declare const LOG_LEVEL_PREFIX = "log-level.";
365
+ /**
366
+ * Convert a log level name to its numeric value.
367
+ */
368
+ declare function wordLevelToNumber(level: LogLevelName): LogLevelNumber | undefined;
369
+ /**
370
+ * Parse a log level (string name or number) to a numeric value.
371
+ */
372
+ declare function parseLevel(level: string | number | undefined): LogLevelNumber | undefined;
373
+ /**
374
+ * Check if a log message at desiredLevel should be logged, given the logger hierarchy.
375
+ *
376
+ * Walks up the logger name hierarchy (e.g., "log-level.a.b.c" -> "log-level.a.b" -> "log-level.a")
377
+ * looking for a matching config. If no config is found, uses defaultLevel.
378
+ */
379
+ declare function shouldLog(args: {
380
+ loggerName: string;
381
+ desiredLevel: LogLevelNumber;
382
+ defaultLevel: LogLevelNumber;
383
+ getConfig: (key: string) => GetValue;
384
+ }): boolean;
385
+
386
+ /**
387
+ * In-memory config store.
388
+ *
389
+ * Stores parsed ConfigResponse objects keyed by config key.
390
+ * The store replaces all configs atomically on each update.
391
+ */
392
+ declare class ConfigStore {
393
+ private configs;
394
+ private version;
395
+ private environmentId;
396
+ get(key: string): ConfigResponse | undefined;
397
+ keys(): string[];
398
+ getEnvironmentId(): string;
399
+ getVersion(): string;
400
+ /**
401
+ * Replace all configs with those from the given envelope.
402
+ * Also normalizes values that need special deserialization (weighted_values, provided).
403
+ */
404
+ update(envelope: ConfigEnvelope): void;
405
+ /**
406
+ * Load from a raw datafile (JSON object).
407
+ */
408
+ loadFromDatafile(data: ConfigEnvelope): void;
409
+ }
410
+
411
+ /**
412
+ * Evaluator is the main evaluation engine. It evaluates configs against contexts,
413
+ * resolving rules, operators, segments, and weighted values.
414
+ *
415
+ * This is a faithful port of the Go SDK's evalcore.Evaluator.
416
+ */
417
+ declare class Evaluator {
418
+ private configStore;
419
+ private weighted;
420
+ constructor(configStore: ConfigStore);
421
+ /**
422
+ * Evaluate a config for the given environment and context.
423
+ *
424
+ * Evaluation flow:
425
+ * 1. Find the environment block matching envID (if any)
426
+ * 2. Iterate its rules top-to-bottom; first match wins
427
+ * 3. If no env-specific match, fall back to default.rules
428
+ * 4. For each rule, all criteria must match (AND logic)
429
+ * 5. If matched value is weighted_values, resolve through WeightedValueResolver
430
+ */
431
+ evaluateConfig(cfg: ConfigResponse, envID: string, contexts: Contexts): EvalMatch;
432
+ private evaluateRules;
433
+ private evaluateAllCriteria;
434
+ private evaluateSingleCriterion;
435
+ }
436
+
437
+ /**
438
+ * Resolver handles post-evaluation value resolution:
439
+ * - ENV_VAR provided values
440
+ * - Decryption of confidential values
441
+ * - Type coercion
442
+ * - Duration parsing
443
+ * - JSON parsing
444
+ */
445
+ declare class Resolver {
446
+ private store;
447
+ private evaluator;
448
+ constructor(store: ConfigStore, evaluator: Evaluator);
449
+ /**
450
+ * Resolve a matched value. Handles:
451
+ * - provided values (ENV_VAR lookup)
452
+ * - decryption of confidential values
453
+ */
454
+ resolveValue(val: Value, configKey: string, valueType: ValueType, envID: string, contexts: Contexts): {
455
+ resolved: Value;
456
+ reportableValue?: GetValue;
457
+ };
458
+ /**
459
+ * Unwrap a resolved value to a plain JS value.
460
+ */
461
+ unwrapValue(val: Value): GetValue;
462
+ }
463
+
464
+ interface FetchResult {
465
+ envelope?: ConfigEnvelope;
466
+ notChanged: boolean;
467
+ }
468
+ declare class Transport {
469
+ private baseUrl;
470
+ private telemetryBaseUrl;
471
+ private sdkKey;
472
+ private etag;
473
+ constructor(baseUrl: string, sdkKey: string, telemetryBaseUrl?: string);
474
+ /**
475
+ * Build the Basic auth header value.
476
+ * Uses username "1" like the Go SDK: base64("1:{sdkKey}")
477
+ */
478
+ private getAuthHeader;
479
+ /**
480
+ * Common headers for all requests.
481
+ */
482
+ private getHeaders;
483
+ /**
484
+ * Fetch configs from GET /api/v2/configs with ETag caching.
485
+ *
486
+ * Returns `{ notChanged: true }` if the server responds with 304.
487
+ */
488
+ fetchConfigs(): Promise<FetchResult>;
489
+ /**
490
+ * Post telemetry data to the telemetry endpoint.
491
+ */
492
+ postTelemetry(data: any): Promise<void>;
493
+ /**
494
+ * Get the SSE URL for config streaming.
495
+ */
496
+ getSSEUrl(): string;
497
+ /**
498
+ * Get auth headers for SSE connection.
499
+ */
500
+ getSSEHeaders(): Record<string, string>;
501
+ }
502
+
503
+ /**
504
+ * WeightedValueResolver resolves weighted value distributions to a single value.
505
+ *
506
+ * This is a faithful port of the Go SDK's WeightedValueResolver.
507
+ */
508
+ declare class WeightedValueResolver {
509
+ /**
510
+ * Resolve picks a value from the weighted distribution.
511
+ *
512
+ * If hashByPropertyName is set and the context has a value for that property,
513
+ * the selection is deterministic via Murmur3 hash. Otherwise, it falls back
514
+ * to Math.random().
515
+ *
516
+ * Returns the selected value and its index, or [undefined, -1] if no values.
517
+ */
518
+ resolve(wv: WeightedValuesData, configKey: string, contexts: Contexts): {
519
+ value: Value | undefined;
520
+ index: number;
521
+ };
522
+ private getUserFraction;
523
+ }
524
+
525
+ declare const OP_NOT_SET = "NOT_SET";
526
+ declare const OP_ALWAYS_TRUE = "ALWAYS_TRUE";
527
+ declare const OP_PROP_IS_ONE_OF = "PROP_IS_ONE_OF";
528
+ declare const OP_PROP_IS_NOT_ONE_OF = "PROP_IS_NOT_ONE_OF";
529
+ declare const OP_PROP_STARTS_WITH_ONE_OF = "PROP_STARTS_WITH_ONE_OF";
530
+ declare const OP_PROP_DOES_NOT_START_WITH_ONE_OF = "PROP_DOES_NOT_START_WITH_ONE_OF";
531
+ declare const OP_PROP_ENDS_WITH_ONE_OF = "PROP_ENDS_WITH_ONE_OF";
532
+ declare const OP_PROP_DOES_NOT_END_WITH_ONE_OF = "PROP_DOES_NOT_END_WITH_ONE_OF";
533
+ declare const OP_PROP_CONTAINS_ONE_OF = "PROP_CONTAINS_ONE_OF";
534
+ declare const OP_PROP_DOES_NOT_CONTAIN_ONE_OF = "PROP_DOES_NOT_CONTAIN_ONE_OF";
535
+ declare const OP_PROP_MATCHES = "PROP_MATCHES";
536
+ declare const OP_PROP_DOES_NOT_MATCH = "PROP_DOES_NOT_MATCH";
537
+ declare const OP_HIERARCHICAL_MATCH = "HIERARCHICAL_MATCH";
538
+ declare const OP_IN_INT_RANGE = "IN_INT_RANGE";
539
+ declare const OP_PROP_GREATER_THAN = "PROP_GREATER_THAN";
540
+ declare const OP_PROP_GREATER_THAN_OR_EQUAL = "PROP_GREATER_THAN_OR_EQUAL";
541
+ declare const OP_PROP_LESS_THAN = "PROP_LESS_THAN";
542
+ declare const OP_PROP_LESS_THAN_OR_EQUAL = "PROP_LESS_THAN_OR_EQUAL";
543
+ declare const OP_PROP_BEFORE = "PROP_BEFORE";
544
+ declare const OP_PROP_AFTER = "PROP_AFTER";
545
+ declare const OP_PROP_SEMVER_LESS_THAN = "PROP_SEMVER_LESS_THAN";
546
+ declare const OP_PROP_SEMVER_EQUAL = "PROP_SEMVER_EQUAL";
547
+ declare const OP_PROP_SEMVER_GREATER_THAN = "PROP_SEMVER_GREATER_THAN";
548
+ declare const OP_IN_SEG = "IN_SEG";
549
+ declare const OP_NOT_IN_SEG = "NOT_IN_SEG";
550
+ type SegmentResolver = (segmentKey: string) => {
551
+ result: boolean;
552
+ found: boolean;
553
+ };
554
+ /**
555
+ * Evaluate a single criterion against a context value.
556
+ *
557
+ * This is a faithful port of the Go SDK's EvaluateCriterion function.
558
+ */
559
+ declare function evaluateCriterion(contextValue: any, contextExists: boolean, criterion: Criterion, segmentResolver?: SegmentResolver): boolean;
560
+
561
+ /**
562
+ * Collects evaluation summaries for telemetry reporting.
563
+ *
564
+ * Each evaluation is aggregated by (configKey, configType) and
565
+ * counted by (configId, ruleIndex, value, weightedValueIndex).
566
+ */
567
+ declare class EvaluationSummaryCollector {
568
+ private enabled;
569
+ private data;
570
+ private startAt;
571
+ private maxDataSize;
572
+ constructor(enabled: boolean, maxDataSize?: number);
573
+ isEnabled(): boolean;
574
+ push(evaluation: Evaluation): void;
575
+ /**
576
+ * Drain collected summaries into a TelemetryEvent, or return undefined if empty.
577
+ */
578
+ drain(): TelemetryEvent | undefined;
579
+ }
580
+
581
+ /**
582
+ * Collects context shapes (field names + types) for telemetry reporting.
583
+ */
584
+ declare class ContextShapeCollector {
585
+ private enabled;
586
+ private data;
587
+ private maxDataSize;
588
+ constructor(contextUploadMode: ContextUploadMode, maxDataSize?: number);
589
+ isEnabled(): boolean;
590
+ push(contexts: Contexts): void;
591
+ /**
592
+ * Drain collected shapes into a TelemetryEvent, or return undefined if empty.
593
+ */
594
+ drain(): TelemetryEvent | undefined;
595
+ }
596
+
597
+ /**
598
+ * Collects example contexts for telemetry reporting.
599
+ * Only collects when contextUploadMode is "periodic_example".
600
+ */
601
+ declare class ExampleContextCollector {
602
+ private enabled;
603
+ private data;
604
+ private seen;
605
+ private maxDataSize;
606
+ private rateLimitMs;
607
+ constructor(contextUploadMode: ContextUploadMode, maxDataSize?: number, rateLimitMs?: number);
608
+ isEnabled(): boolean;
609
+ push(contexts: Contexts): void;
610
+ /**
611
+ * Drain collected examples into a TelemetryEvent, or return undefined if empty.
612
+ */
613
+ drain(): TelemetryEvent | undefined;
614
+ private groupedKey;
615
+ private pruneCache;
616
+ }
617
+
618
+ /**
619
+ * TelemetryReporter periodically drains collected telemetry data and sends it
620
+ * to the Quonfig telemetry endpoint.
621
+ */
622
+ declare class TelemetryReporter {
623
+ private transport;
624
+ private instanceHash;
625
+ private evaluationSummaries;
626
+ private contextShapes;
627
+ private exampleContexts;
628
+ private timer;
629
+ private initialDelay;
630
+ private maxDelay;
631
+ private currentDelay;
632
+ private stopped;
633
+ constructor(args: {
634
+ transport: Transport;
635
+ instanceHash: string;
636
+ evaluationSummaries: EvaluationSummaryCollector;
637
+ contextShapes: ContextShapeCollector;
638
+ exampleContexts: ExampleContextCollector;
639
+ initialDelay?: number;
640
+ maxDelay?: number;
641
+ });
642
+ /**
643
+ * Start the periodic telemetry reporting loop.
644
+ */
645
+ start(): void;
646
+ /**
647
+ * Stop telemetry reporting.
648
+ */
649
+ stop(): void;
650
+ private scheduleNext;
651
+ private sync;
652
+ }
653
+
654
+ /**
655
+ * CLI-compatibility types and utilities.
656
+ *
657
+ * These are needed by @quonfig/cli but are NOT part of the core SDK.
658
+ * They provide the HTTP API client, SDK-key parsing, and legacy
659
+ * config-value types that the CLI's CRUD commands depend on.
660
+ */
661
+
662
+ interface ClientOptions {
663
+ jwt?: string;
664
+ sdkKey?: string;
665
+ apiUrl: string;
666
+ clientIdentifier: string;
667
+ log?: (category: string | unknown, message?: unknown) => void;
668
+ }
669
+ /**
670
+ * Minimal HTTP client for the Quonfig REST API.
671
+ * Used by the CLI for CRUD operations (create, set-default, download, etc.).
672
+ */
673
+ declare class Client {
674
+ private jwt?;
675
+ private sdkKey?;
676
+ private apiUrl;
677
+ private clientIdentifier;
678
+ private log;
679
+ constructor(options: ClientOptions);
680
+ private headers;
681
+ get(path: string): Promise<Response>;
682
+ post(path: string, payload: unknown): Promise<Response>;
683
+ put(path: string, payload: unknown): Promise<Response>;
684
+ }
685
+ interface ProjectEnvId {
686
+ id: string;
687
+ projectId: number;
688
+ }
689
+ /**
690
+ * Parse a Prefab/Quonfig SDK key to extract the project-environment ID.
691
+ * SDK keys are typically in the format: `<projectId>-<envId>-<secret>`
692
+ */
693
+ declare function getProjectEnvFromSdkKey(sdkKey: string): ProjectEnvId;
694
+ /**
695
+ * ConfigValueType enum, matching the legacy quonfig-common types.
696
+ * Used by the CLI's coerce and config-value-dto utilities.
697
+ */
698
+ declare enum ConfigValueType {
699
+ NotSetValue = 0,
700
+ Int = 1,
701
+ String = 2,
702
+ Bytes = 3,
703
+ Double = 4,
704
+ Bool = 5,
705
+ LimitDefinition = 7,
706
+ LogLevel = 8,
707
+ StringList = 9,
708
+ IntRange = 10,
709
+ Duration = 11,
710
+ Json = 12
711
+ }
712
+ /**
713
+ * ConfigValue represents a typed value in the legacy format.
714
+ * Used by the CLI for constructing API request payloads.
715
+ */
716
+ interface ConfigValue {
717
+ int?: bigint | number;
718
+ string?: string;
719
+ bytes?: Uint8Array;
720
+ double?: number;
721
+ bool?: boolean;
722
+ logLevel?: string;
723
+ stringList?: {
724
+ values: string[];
725
+ };
726
+ intRange?: {
727
+ start?: number;
728
+ end?: number;
729
+ };
730
+ duration?: {
731
+ definition?: string;
732
+ millis?: number;
733
+ };
734
+ json?: {
735
+ json: string;
736
+ };
737
+ provided?: {
738
+ source: string;
739
+ lookup: string;
740
+ };
741
+ confidential?: boolean;
742
+ decryptWith?: string;
743
+ }
744
+ /**
745
+ * Extract the value-type string for a ConfigResponse (e.g., "bool", "string", "int").
746
+ * Used by the CLI's `serve` command to format evaluation responses.
747
+ */
748
+ declare function valueTypeStringForConfig(config: ConfigResponse): ValueType | undefined;
749
+
750
+ declare const encryption: {
751
+ encrypt: typeof encrypt;
752
+ generateNewHexKey: typeof generateNewHexKey;
753
+ };
754
+
755
+ export { BoundQuonfig, Client, type ClientOptions, type ConfigEnvelope, type ConfigResponse, ConfigStore, ConfigType, type ConfigTypeString, type ConfigValue, ConfigValueType, ContextShapeCollector, type ContextUploadMode, type ContextValue, type Contexts, type Criterion, type Environment, type EvalMatch, type Evaluation, EvaluationSummaryCollector, Evaluator, ExampleContextCollector, type GetValue, LOG_LEVEL_PREFIX, type LogLevelName, type LogLevelNumber, type Meta, type NodeServerConfigurationAccessor, type NodeServerConfigurationRaw, OP_ALWAYS_TRUE, OP_HIERARCHICAL_MATCH, OP_IN_INT_RANGE, OP_IN_SEG, OP_NOT_IN_SEG, OP_NOT_SET, OP_PROP_AFTER, OP_PROP_BEFORE, OP_PROP_CONTAINS_ONE_OF, OP_PROP_DOES_NOT_CONTAIN_ONE_OF, OP_PROP_DOES_NOT_END_WITH_ONE_OF, OP_PROP_DOES_NOT_MATCH, OP_PROP_DOES_NOT_START_WITH_ONE_OF, OP_PROP_ENDS_WITH_ONE_OF, OP_PROP_GREATER_THAN, OP_PROP_GREATER_THAN_OR_EQUAL, OP_PROP_IS_NOT_ONE_OF, OP_PROP_IS_ONE_OF, OP_PROP_LESS_THAN, OP_PROP_LESS_THAN_OR_EQUAL, OP_PROP_MATCHES, OP_PROP_SEMVER_EQUAL, OP_PROP_SEMVER_GREATER_THAN, OP_PROP_SEMVER_LESS_THAN, OP_PROP_STARTS_WITH_ONE_OF, type OnNoDefault, type ProjectEnvId, type ProvidedData, ProvidedSource, Quonfig, type QuonfigOptions, Resolver, type Rule, type RuleSet, type SchemaData, type SegmentResolver, type SemanticVersion, TelemetryReporter, Transport, type TypedNodeServerConfigurationAccessor, type TypedNodeServerConfigurationRaw, type Value, type ValueType, type WeightedValue, WeightedValueResolver, type WeightedValuesData, compareSemver, contextLookup, decrypt, durationToMilliseconds, encrypt, encryption, evaluateCriterion, generateNewHexKey, getContextValue, getProjectEnvFromSdkKey, hashZeroToOne, mergeContexts, parseLevel, parseSemver, shouldLog, valueTypeStringForConfig, wordLevelToNumber };