@quonfig/node 0.0.1 → 0.0.2
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 +2 -1
- package/dist/index.cjs +169 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -6
- package/dist/index.d.ts +32 -6
- package/dist/index.js +169 -44
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/quonfig.ts","../src/store.ts","../src/context.ts","../src/semver.ts","../src/operators.ts","../src/hashing.ts","../src/weighted.ts","../src/evaluator.ts","../src/encryption.ts","../src/duration.ts","../src/resolver.ts","../src/transport.ts","../src/sse.ts","../src/logger.ts","../src/telemetry/evaluationSummaries.ts","../src/telemetry/contextShapes.ts","../src/telemetry/exampleContexts.ts","../src/telemetry/reporter.ts","../src/types.ts","../src/cli-compat.ts"],"sourcesContent":["// Main SDK exports\nexport { Quonfig, BoundQuonfig } from \"./quonfig\";\n\n// Types\nexport type {\n QuonfigOptions,\n ConfigEnvelope,\n ConfigResponse,\n ConfigTypeString,\n ValueType,\n Value,\n Rule,\n RuleSet,\n Criterion,\n Environment,\n Meta,\n Contexts,\n ContextValue,\n GetValue,\n OnNoDefault,\n ContextUploadMode,\n LogLevelName,\n LogLevelNumber,\n ProvidedData,\n WeightedValue,\n WeightedValuesData,\n SchemaData,\n EvalMatch,\n Evaluation,\n NodeServerConfigurationRaw,\n NodeServerConfigurationAccessor,\n TypedNodeServerConfigurationRaw,\n TypedNodeServerConfigurationAccessor,\n} from \"./types\";\n\n// Enum-like runtime constants (e.g., ConfigType.FeatureFlag, ProvidedSource.EnvVar)\nexport { ConfigType, ProvidedSource } from \"./types\";\n\n// Context utilities\nexport { contextLookup, mergeContexts, getContextValue } from \"./context\";\n\n// Encryption utilities\nexport { encrypt, decrypt, generateNewHexKey } from \"./encryption\";\n\n// Encryption namespace (for CLI compatibility: `import { encryption } from '@quonfig/node'`)\nimport { encrypt as _encrypt, generateNewHexKey as _generateNewHexKey } from \"./encryption\";\nexport const encryption = {\n encrypt: _encrypt,\n generateNewHexKey: _generateNewHexKey,\n};\n\n// Duration parsing\nexport { durationToMilliseconds } from \"./duration\";\n\n// Semver comparison\nexport { parseSemver, compareSemver } from \"./semver\";\nexport type { SemanticVersion } from \"./semver\";\n\n// Hashing\nexport { hashZeroToOne } from \"./hashing\";\n\n// Logger utilities\nexport { parseLevel, wordLevelToNumber, shouldLog, LOG_LEVEL_PREFIX } from \"./logger\";\n\n// Evaluator (for advanced usage / testing)\nexport { Evaluator } from \"./evaluator\";\nexport { ConfigStore } from \"./store\";\nexport { Resolver } from \"./resolver\";\nexport { Transport } from \"./transport\";\nexport { WeightedValueResolver } from \"./weighted\";\n\n// Operators (for advanced usage / testing)\nexport {\n evaluateCriterion,\n OP_NOT_SET,\n OP_ALWAYS_TRUE,\n OP_PROP_IS_ONE_OF,\n OP_PROP_IS_NOT_ONE_OF,\n OP_PROP_STARTS_WITH_ONE_OF,\n OP_PROP_DOES_NOT_START_WITH_ONE_OF,\n OP_PROP_ENDS_WITH_ONE_OF,\n OP_PROP_DOES_NOT_END_WITH_ONE_OF,\n OP_PROP_CONTAINS_ONE_OF,\n OP_PROP_DOES_NOT_CONTAIN_ONE_OF,\n OP_PROP_MATCHES,\n OP_PROP_DOES_NOT_MATCH,\n OP_HIERARCHICAL_MATCH,\n OP_IN_INT_RANGE,\n OP_PROP_GREATER_THAN,\n OP_PROP_GREATER_THAN_OR_EQUAL,\n OP_PROP_LESS_THAN,\n OP_PROP_LESS_THAN_OR_EQUAL,\n OP_PROP_BEFORE,\n OP_PROP_AFTER,\n OP_PROP_SEMVER_LESS_THAN,\n OP_PROP_SEMVER_EQUAL,\n OP_PROP_SEMVER_GREATER_THAN,\n OP_IN_SEG,\n OP_NOT_IN_SEG,\n} from \"./operators\";\nexport type { SegmentResolver } from \"./operators\";\n\n// Telemetry (for advanced usage / testing)\nexport { EvaluationSummaryCollector } from \"./telemetry/evaluationSummaries\";\nexport { ContextShapeCollector } from \"./telemetry/contextShapes\";\nexport { ExampleContextCollector } from \"./telemetry/exampleContexts\";\nexport { TelemetryReporter } from \"./telemetry/reporter\";\n\n// CLI compatibility (HTTP client, SDK-key parsing, legacy value types)\nexport { Client, getProjectEnvFromSdkKey, ConfigValueType, valueTypeStringForConfig } from \"./cli-compat\";\nexport type { ClientOptions, ProjectEnvId, ConfigValue } from \"./cli-compat\";\n","import { randomUUID } from \"crypto\";\nimport { readFileSync } from \"fs\";\n\nimport type {\n ConfigEnvelope,\n Contexts,\n ContextUploadMode,\n Evaluation,\n GetValue,\n LogLevelName,\n LogLevelNumber,\n OnNoDefault,\n QuonfigOptions,\n Value,\n} from \"./types\";\n\nimport { ConfigStore } from \"./store\";\nimport { Evaluator } from \"./evaluator\";\nimport { Resolver } from \"./resolver\";\nimport { Transport } from \"./transport\";\nimport { SSEConnection } from \"./sse\";\nimport { mergeContexts } from \"./context\";\nimport { parseLevel, shouldLog } from \"./logger\";\nimport { durationToMilliseconds } from \"./duration\";\n\nimport { EvaluationSummaryCollector } from \"./telemetry/evaluationSummaries\";\nimport { ContextShapeCollector } from \"./telemetry/contextShapes\";\nimport { ExampleContextCollector } from \"./telemetry/exampleContexts\";\nimport { TelemetryReporter } from \"./telemetry/reporter\";\n\nconst DEFAULT_API_URL = \"https://api.quonfig.com\";\nconst DEFAULT_POLL_INTERVAL = 60000;\nconst DEFAULT_INIT_TIMEOUT = 10000;\nconst DEFAULT_LOG_LEVEL: LogLevelNumber = 5; // warn\n\n/**\n * BoundQuonfig is a Quonfig client bound to a specific context.\n * All get* calls automatically include the bound context.\n */\nexport class BoundQuonfig {\n private client: Quonfig;\n private boundContexts: Contexts;\n\n constructor(client: Quonfig, contexts: Contexts) {\n this.client = client;\n this.boundContexts = contexts;\n }\n\n get(key: string, contexts?: Contexts, defaultValue?: any): any {\n return this.client.get(key, mergeContexts(this.boundContexts, contexts), defaultValue);\n }\n\n getString(key: string, contexts?: Contexts): string | undefined {\n return this.client.getString(key, mergeContexts(this.boundContexts, contexts));\n }\n\n getNumber(key: string, contexts?: Contexts): number | undefined {\n return this.client.getNumber(key, mergeContexts(this.boundContexts, contexts));\n }\n\n getBool(key: string, contexts?: Contexts): boolean | undefined {\n return this.client.getBool(key, mergeContexts(this.boundContexts, contexts));\n }\n\n getStringList(key: string, contexts?: Contexts): string[] | undefined {\n return this.client.getStringList(key, mergeContexts(this.boundContexts, contexts));\n }\n\n getDuration(key: string, contexts?: Contexts): number | undefined {\n return this.client.getDuration(key, mergeContexts(this.boundContexts, contexts));\n }\n\n getJSON(key: string, contexts?: Contexts): any {\n return this.client.getJSON(key, mergeContexts(this.boundContexts, contexts));\n }\n\n isFeatureEnabled(key: string, contexts?: Contexts): boolean {\n return this.client.isFeatureEnabled(key, mergeContexts(this.boundContexts, contexts));\n }\n\n shouldLog(args: {\n loggerName: string;\n desiredLevel: string;\n defaultLevel?: string;\n contexts?: Contexts;\n }): boolean {\n return this.client.shouldLog({\n ...args,\n contexts: mergeContexts(this.boundContexts, args.contexts),\n });\n }\n\n keys(): string[] {\n return this.client.keys();\n }\n\n inContext(contexts: Contexts): BoundQuonfig {\n return new BoundQuonfig(this.client, mergeContexts(this.boundContexts, contexts));\n }\n}\n\n/**\n * Quonfig is the main SDK client.\n *\n * Usage:\n * ```typescript\n * const quonfig = new Quonfig({ sdkKey: \"your-key\" });\n * await quonfig.init();\n * const value = quonfig.get(\"my-config\");\n * ```\n */\nexport class Quonfig {\n private readonly sdkKey: string;\n private readonly apiUrl: string;\n private readonly telemetryUrl?: string;\n private readonly enableSSE: boolean;\n private readonly enablePolling: boolean;\n private readonly pollInterval: number;\n private readonly namespace?: string;\n private readonly onNoDefault: OnNoDefault;\n private readonly globalContext?: Contexts;\n private readonly initTimeout: number;\n private readonly datafile?: string | object;\n\n private store: ConfigStore;\n private evaluator: Evaluator;\n private resolver: Resolver;\n private transport: Transport;\n private sseConnection?: SSEConnection;\n private pollTimer?: ReturnType<typeof setTimeout>;\n private telemetryReporter?: TelemetryReporter;\n private instanceHash: string;\n private environmentId: string = \"\";\n private initialized: boolean = false;\n\n // Telemetry collectors\n private evaluationSummaries: EvaluationSummaryCollector;\n private contextShapes: ContextShapeCollector;\n private exampleContexts: ExampleContextCollector;\n\n constructor(options: QuonfigOptions) {\n this.sdkKey = options.sdkKey;\n this.apiUrl = (options.apiUrl ?? DEFAULT_API_URL).replace(/\\/$/, \"\");\n this.telemetryUrl = options.telemetryUrl;\n this.enableSSE = options.enableSSE ?? true;\n this.enablePolling = options.enablePolling ?? false;\n this.pollInterval = options.pollInterval ?? DEFAULT_POLL_INTERVAL;\n this.namespace = options.namespace;\n this.onNoDefault = options.onNoDefault ?? \"error\";\n this.globalContext = options.globalContext;\n this.initTimeout = options.initTimeout ?? DEFAULT_INIT_TIMEOUT;\n this.datafile = options.datafile;\n this.instanceHash = randomUUID();\n\n // Initialize core components\n this.store = new ConfigStore();\n this.evaluator = new Evaluator(this.store);\n this.resolver = new Resolver(this.store, this.evaluator);\n this.transport = new Transport(this.apiUrl, this.sdkKey, this.telemetryUrl);\n\n // Initialize telemetry collectors\n const contextUploadMode: ContextUploadMode = options.contextUploadMode ?? \"periodic_example\";\n this.evaluationSummaries = new EvaluationSummaryCollector(\n options.collectEvaluationSummaries ?? true\n );\n this.contextShapes = new ContextShapeCollector(contextUploadMode);\n this.exampleContexts = new ExampleContextCollector(contextUploadMode);\n }\n\n /**\n * Initialize the SDK. Downloads configs from the API (or loads from datafile)\n * and starts background update mechanisms (SSE/polling).\n *\n * Must be called before using any get* methods.\n */\n async init(): Promise<void> {\n if (this.datafile) {\n this.loadDatafile();\n this.initialized = true;\n return;\n }\n\n // Fetch configs with a timeout\n const fetchPromise = this.fetchAndInstall();\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(\"Initialization timed out\")), this.initTimeout);\n });\n\n try {\n await Promise.race([fetchPromise, timeoutPromise]);\n } catch (err) {\n console.warn(\"[quonfig] Initialization failed:\", err);\n throw err;\n }\n\n this.initialized = true;\n\n // Start SSE for real-time updates\n if (this.enableSSE) {\n this.startSSE();\n }\n\n // Start polling if enabled\n if (this.enablePolling) {\n this.startPolling();\n }\n\n // Start telemetry reporter\n this.startTelemetry();\n }\n\n /**\n * Get a config value by key. Evaluates rules against the provided context.\n */\n get(key: string, contexts?: Contexts, defaultValue?: any): any {\n this.requireInitialized();\n\n const mergedContexts = mergeContexts(this.globalContext, contexts);\n const config = this.store.get(key);\n\n if (config === undefined) {\n return this.handleNoDefault(key, defaultValue);\n }\n\n // Record context for telemetry\n this.contextShapes.push(mergedContexts);\n this.exampleContexts.push(mergedContexts);\n\n // Evaluate\n const match = this.evaluator.evaluateConfig(\n config,\n this.environmentId,\n mergedContexts\n );\n\n if (!match.isMatch || match.value === undefined) {\n return this.handleNoDefault(key, defaultValue);\n }\n\n // Resolve (ENV_VAR, decryption)\n const { resolved, reportableValue } = this.resolver.resolveValue(\n match.value,\n config.key,\n config.valueType,\n this.environmentId,\n mergedContexts\n );\n\n // Unwrap to plain value\n const unwrapped = this.resolver.unwrapValue(resolved);\n\n // Record evaluation for telemetry\n const evaluation: Evaluation = {\n configId: config.id,\n configKey: config.key,\n configType: config.type,\n unwrappedValue: unwrapped as GetValue,\n reportableValue: reportableValue,\n ruleIndex: match.ruleIndex,\n weightedValueIndex: match.weightedValueIndex >= 0 ? match.weightedValueIndex : undefined,\n };\n this.evaluationSummaries.push(evaluation);\n\n return unwrapped;\n }\n\n /**\n * Get a string config value.\n */\n getString(key: string, contexts?: Contexts): string | undefined {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n return String(value);\n }\n\n /**\n * Get a number config value.\n */\n getNumber(key: string, contexts?: Contexts): number | undefined {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n return typeof value === \"number\" ? value : Number(value);\n }\n\n /**\n * Get a boolean config value.\n */\n getBool(key: string, contexts?: Contexts): boolean | undefined {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n return !!value;\n }\n\n /**\n * Get a string list config value.\n */\n getStringList(key: string, contexts?: Contexts): string[] | undefined {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n if (Array.isArray(value)) return value.map((v: any) => String(v));\n return undefined;\n }\n\n /**\n * Get a duration config value in milliseconds.\n */\n getDuration(key: string, contexts?: Contexts): number | undefined {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n // If the evaluator already unwrapped it to ms (duration type), return as-is\n if (typeof value === \"number\") return value;\n // If it's a string, parse it\n if (typeof value === \"string\") return durationToMilliseconds(value);\n return undefined;\n }\n\n /**\n * Get a JSON config value (parsed).\n */\n getJSON(key: string, contexts?: Contexts): any {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n // If already parsed (from unwrap), return as-is\n return value;\n }\n\n /**\n * Check if a feature flag is enabled.\n * Returns false if the key is not found or the value is not a boolean.\n */\n isFeatureEnabled(key: string, contexts?: Contexts): boolean {\n const value = this.get(key, contexts, undefined);\n if (typeof value === \"boolean\") return value;\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n return false;\n }\n\n /**\n * Check if a log message should be logged at the given level.\n */\n shouldLog(args: {\n loggerName: string;\n desiredLevel: string;\n defaultLevel?: string;\n contexts?: Contexts;\n }): boolean {\n const desiredLevelNum = parseLevel(args.desiredLevel);\n if (desiredLevelNum === undefined) {\n console.warn(`[quonfig] Invalid desiredLevel \"${args.desiredLevel}\". Returning true.`);\n return true;\n }\n\n const defaultLevelNum = parseLevel(args.defaultLevel) ?? DEFAULT_LOG_LEVEL;\n\n return shouldLog({\n loggerName: args.loggerName,\n desiredLevel: desiredLevelNum,\n defaultLevel: defaultLevelNum,\n getConfig: (logKey: string) => {\n try {\n return this.get(logKey, args.contexts, undefined);\n } catch {\n return undefined;\n }\n },\n });\n }\n\n /**\n * Get all config keys currently in the store.\n */\n keys(): string[] {\n this.requireInitialized();\n return this.store.keys();\n }\n\n /**\n * Get the raw ConfigResponse for a key (for advanced usage / CLI tooling).\n */\n rawConfig(key: string): import(\"./types\").ConfigResponse | undefined {\n this.requireInitialized();\n return this.store.get(key);\n }\n\n /**\n * Create a BoundQuonfig with the given context baked in.\n */\n inContext(contexts: Contexts): BoundQuonfig {\n return new BoundQuonfig(this, mergeContexts(this.globalContext, contexts));\n }\n\n /**\n * Close the SDK. Stops SSE, polling, and telemetry.\n */\n close(): void {\n if (this.sseConnection) {\n this.sseConnection.close();\n this.sseConnection = undefined;\n }\n\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = undefined;\n }\n\n if (this.telemetryReporter) {\n this.telemetryReporter.stop();\n this.telemetryReporter = undefined;\n }\n }\n\n // ---- Private methods ----\n\n private requireInitialized(): void {\n if (!this.initialized) {\n throw new Error(\"[quonfig] Not initialized. Call init() first.\");\n }\n }\n\n private handleNoDefault(key: string, defaultValue?: any): any {\n if (defaultValue !== undefined) {\n return defaultValue;\n }\n\n switch (this.onNoDefault) {\n case \"error\":\n throw new Error(`No value found for key \"${key}\"`);\n case \"warn\":\n console.warn(`[quonfig] No value found for key \"${key}\"`);\n return undefined;\n case \"ignore\":\n return undefined;\n }\n }\n\n private loadDatafile(): void {\n let data: ConfigEnvelope;\n\n if (typeof this.datafile === \"string\") {\n const raw = readFileSync(this.datafile, \"utf-8\");\n data = JSON.parse(raw);\n } else if (typeof this.datafile === \"object\") {\n data = this.datafile as ConfigEnvelope;\n } else {\n throw new Error(\"Invalid datafile option\");\n }\n\n this.store.update(data);\n this.environmentId = data.meta.environment;\n }\n\n private async fetchAndInstall(): Promise<void> {\n const result = await this.transport.fetchConfigs();\n\n if (result.notChanged) {\n return;\n }\n\n if (result.envelope) {\n this.store.update(result.envelope);\n this.environmentId = result.envelope.meta.environment;\n }\n }\n\n private startSSE(): void {\n this.sseConnection = new SSEConnection(this.transport);\n this.sseConnection.start((envelope: ConfigEnvelope) => {\n this.store.update(envelope);\n this.environmentId = envelope.meta.environment;\n });\n }\n\n private startPolling(): void {\n const poll = (): void => {\n this.fetchAndInstall()\n .catch((err) => {\n console.warn(\"[quonfig] Polling error:\", err);\n })\n .finally(() => {\n this.pollTimer = setTimeout(poll, this.pollInterval);\n if (this.pollTimer && typeof this.pollTimer === \"object\" && \"unref\" in this.pollTimer) {\n this.pollTimer.unref();\n }\n });\n };\n\n this.pollTimer = setTimeout(poll, this.pollInterval);\n if (this.pollTimer && typeof this.pollTimer === \"object\" && \"unref\" in this.pollTimer) {\n this.pollTimer.unref();\n }\n }\n\n private startTelemetry(): void {\n const anyEnabled =\n this.evaluationSummaries.isEnabled() ||\n this.contextShapes.isEnabled() ||\n this.exampleContexts.isEnabled();\n\n if (!anyEnabled) return;\n\n this.telemetryReporter = new TelemetryReporter({\n transport: this.transport,\n instanceHash: this.instanceHash,\n evaluationSummaries: this.evaluationSummaries,\n contextShapes: this.contextShapes,\n exampleContexts: this.exampleContexts,\n });\n\n this.telemetryReporter.start();\n }\n}\n","import type { ConfigEnvelope, ConfigResponse, Value, WeightedValuesData, ProvidedData } from \"./types\";\n\n/**\n * In-memory config store.\n *\n * Stores parsed ConfigResponse objects keyed by config key.\n * The store replaces all configs atomically on each update.\n */\nexport class ConfigStore {\n private configs: Map<string, ConfigResponse> = new Map();\n private version: string = \"\";\n private environmentId: string = \"\";\n\n get(key: string): ConfigResponse | undefined {\n return this.configs.get(key);\n }\n\n keys(): string[] {\n return Array.from(this.configs.keys());\n }\n\n getEnvironmentId(): string {\n return this.environmentId;\n }\n\n getVersion(): string {\n return this.version;\n }\n\n /**\n * Replace all configs with those from the given envelope.\n * Also normalizes values that need special deserialization (weighted_values, provided).\n */\n update(envelope: ConfigEnvelope): void {\n const next = new Map<string, ConfigResponse>();\n\n for (const cfg of envelope.configs) {\n // Normalize the config's values to ensure proper typing\n normalizeConfigResponse(cfg);\n next.set(cfg.key, cfg);\n }\n\n this.configs = next;\n this.version = envelope.meta.version;\n this.environmentId = envelope.meta.environment;\n }\n\n /**\n * Load from a raw datafile (JSON object).\n */\n loadFromDatafile(data: ConfigEnvelope): void {\n this.update(data);\n }\n}\n\n/**\n * Normalize a ConfigResponse to ensure all Value objects have proper typing.\n * JSON deserialization may leave weighted_values and provided values as plain objects.\n */\nfunction normalizeConfigResponse(cfg: ConfigResponse): void {\n // The API may return null instead of an empty array for rules\n if (!cfg.default.rules) {\n cfg.default.rules = [];\n }\n for (const rule of cfg.default.rules) {\n normalizeValue(rule.value);\n for (const criterion of rule.criteria ?? []) {\n if (criterion.valueToMatch) {\n normalizeValue(criterion.valueToMatch);\n }\n }\n }\n\n if (cfg.environment) {\n if (!cfg.environment.rules) {\n cfg.environment.rules = [];\n }\n for (const rule of cfg.environment.rules) {\n normalizeValue(rule.value);\n for (const criterion of rule.criteria ?? []) {\n if (criterion.valueToMatch) {\n normalizeValue(criterion.valueToMatch);\n }\n }\n }\n }\n}\n\n/**\n * Normalize a Value - if it's type \"weighted_values\", ensure the value\n * is in the expected WeightedValuesData shape. Similarly for \"provided\".\n */\nfunction normalizeValue(v: Value): void {\n if (v.type === \"weighted_values\" && v.value && typeof v.value === \"object\") {\n // Ensure it looks like WeightedValuesData\n const wvd = v.value as WeightedValuesData;\n if (wvd.weightedValues) {\n for (const wv of wvd.weightedValues) {\n if (wv.value) {\n normalizeValue(wv.value);\n }\n }\n }\n }\n if (v.type === \"provided\" && v.value && typeof v.value === \"object\") {\n // Ensure it's ProvidedData shape\n const pd = v.value as ProvidedData;\n if (!pd.source) {\n pd.source = \"ENV_VAR\";\n }\n }\n}\n","import type { ContextValue, Contexts } from \"./types\";\n\n/**\n * Look up a property value from contexts using dotted notation.\n * \"user.email\" -> contexts[\"user\"][\"email\"]\n * If there is no dot, look up in the unnamed (\"\") context: \"domain\" -> contexts[\"\"][\"domain\"]\n */\nexport function contextLookup(\n contexts: Contexts,\n propertyName: string | undefined\n): ContextValue | undefined {\n if (propertyName === undefined) {\n return undefined;\n }\n\n const dotIndex = propertyName.indexOf(\".\");\n if (dotIndex === -1) {\n // No dot -- look up in the unnamed (\"\") context\n const ctx = contexts[\"\"];\n if (ctx === undefined) {\n return undefined;\n }\n return ctx[propertyName];\n }\n\n const contextName = propertyName.slice(0, dotIndex);\n const key = propertyName.slice(dotIndex + 1);\n\n const ctx = contexts[contextName];\n if (ctx === undefined) {\n return undefined;\n }\n\n return ctx[key];\n}\n\n/**\n * Merge multiple context sets. Later sets override earlier ones at the key level\n * within each named context.\n */\nexport function mergeContexts(...sets: (Contexts | undefined)[]): Contexts {\n const result: Contexts = {};\n\n for (const cs of sets) {\n if (cs === undefined) {\n continue;\n }\n\n for (const [name, ctx] of Object.entries(cs)) {\n if (result[name] === undefined) {\n result[name] = { ...ctx };\n } else {\n result[name] = { ...result[name], ...ctx };\n }\n }\n }\n\n return result;\n}\n\n/**\n * Get context value with support for magic properties.\n * \"prefab.current-time\" and \"quonfig.current-time\" return current UTC millis.\n */\nexport function getContextValue(\n contexts: Contexts,\n propertyName: string\n): { value: any; exists: boolean } {\n // Handle magic current-time properties\n if (\n propertyName === \"prefab.current-time\" ||\n propertyName === \"quonfig.current-time\" ||\n propertyName === \"reforge.current-time\"\n ) {\n return { value: Date.now(), exists: true };\n }\n\n const value = contextLookup(contexts, propertyName);\n return { value, exists: value !== undefined && value !== null };\n}\n","const SEMVER_PATTERN =\n /^(?<major>0|[1-9]\\d*)\\.(?<minor>0|[1-9]\\d*)\\.(?<patch>0|[1-9]\\d*)(?:-(?<prerelease>(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\n\nexport interface SemanticVersion {\n major: number;\n minor: number;\n patch: number;\n prerelease: string;\n buildMetadata: string;\n}\n\n/**\n * Parse a semantic version string. Returns undefined if invalid.\n */\nexport function parseSemver(version: string): SemanticVersion | undefined {\n if (!version) {\n return undefined;\n }\n\n const match = SEMVER_PATTERN.exec(version);\n if (!match || !match.groups) {\n return undefined;\n }\n\n const major = parseInt(match.groups[\"major\"]!, 10);\n const minor = parseInt(match.groups[\"minor\"]!, 10);\n const patch = parseInt(match.groups[\"patch\"]!, 10);\n\n if (isNaN(major) || isNaN(minor) || isNaN(patch)) {\n return undefined;\n }\n\n return {\n major,\n minor,\n patch,\n prerelease: match.groups[\"prerelease\"] ?? \"\",\n buildMetadata: match.groups[\"buildmetadata\"] ?? \"\",\n };\n}\n\nfunction isNumeric(s: string): boolean {\n return /^\\d+$/.test(s);\n}\n\nfunction comparePreReleaseIdentifiers(id1: string, id2: string): number {\n if (isNumeric(id1) && isNumeric(id2)) {\n const num1 = parseInt(id1, 10);\n const num2 = parseInt(id2, 10);\n if (num1 < num2) return -1;\n if (num1 > num2) return 1;\n return 0;\n }\n\n if (isNumeric(id1)) return -1;\n if (isNumeric(id2)) return 1;\n\n if (id1 < id2) return -1;\n if (id1 > id2) return 1;\n return 0;\n}\n\nfunction comparePreRelease(pre1: string, pre2: string): number {\n if (pre1 === \"\" && pre2 === \"\") return 0;\n // A version without prerelease has higher precedence\n if (pre1 === \"\") return 1;\n if (pre2 === \"\") return -1;\n\n const ids1 = pre1.split(\".\");\n const ids2 = pre2.split(\".\");\n const minLen = Math.min(ids1.length, ids2.length);\n\n for (let i = 0; i < minLen; i++) {\n const cmp = comparePreReleaseIdentifiers(ids1[i]!, ids2[i]!);\n if (cmp !== 0) return cmp;\n }\n\n if (ids1.length < ids2.length) return -1;\n if (ids1.length > ids2.length) return 1;\n return 0;\n}\n\n/**\n * Compare two semantic versions.\n * Returns -1 if a < b, 0 if a == b, 1 if a > b.\n */\nexport function compareSemver(a: SemanticVersion, b: SemanticVersion): number {\n if (a.major !== b.major) return a.major > b.major ? 1 : -1;\n if (a.minor !== b.minor) return a.minor > b.minor ? 1 : -1;\n if (a.patch !== b.patch) return a.patch > b.patch ? 1 : -1;\n return comparePreRelease(a.prerelease, b.prerelease);\n}\n","import type { Criterion, Value } from \"./types\";\nimport { parseSemver, compareSemver } from \"./semver\";\n\n// ---- Operator Constants ----\n\nexport const OP_NOT_SET = \"NOT_SET\";\nexport const OP_ALWAYS_TRUE = \"ALWAYS_TRUE\";\nexport const OP_PROP_IS_ONE_OF = \"PROP_IS_ONE_OF\";\nexport const OP_PROP_IS_NOT_ONE_OF = \"PROP_IS_NOT_ONE_OF\";\nexport const OP_PROP_STARTS_WITH_ONE_OF = \"PROP_STARTS_WITH_ONE_OF\";\nexport const OP_PROP_DOES_NOT_START_WITH_ONE_OF = \"PROP_DOES_NOT_START_WITH_ONE_OF\";\nexport const OP_PROP_ENDS_WITH_ONE_OF = \"PROP_ENDS_WITH_ONE_OF\";\nexport const OP_PROP_DOES_NOT_END_WITH_ONE_OF = \"PROP_DOES_NOT_END_WITH_ONE_OF\";\nexport const OP_PROP_CONTAINS_ONE_OF = \"PROP_CONTAINS_ONE_OF\";\nexport const OP_PROP_DOES_NOT_CONTAIN_ONE_OF = \"PROP_DOES_NOT_CONTAIN_ONE_OF\";\nexport const OP_PROP_MATCHES = \"PROP_MATCHES\";\nexport const OP_PROP_DOES_NOT_MATCH = \"PROP_DOES_NOT_MATCH\";\nexport const OP_HIERARCHICAL_MATCH = \"HIERARCHICAL_MATCH\";\nexport const OP_IN_INT_RANGE = \"IN_INT_RANGE\";\nexport const OP_PROP_GREATER_THAN = \"PROP_GREATER_THAN\";\nexport const OP_PROP_GREATER_THAN_OR_EQUAL = \"PROP_GREATER_THAN_OR_EQUAL\";\nexport const OP_PROP_LESS_THAN = \"PROP_LESS_THAN\";\nexport const OP_PROP_LESS_THAN_OR_EQUAL = \"PROP_LESS_THAN_OR_EQUAL\";\nexport const OP_PROP_BEFORE = \"PROP_BEFORE\";\nexport const OP_PROP_AFTER = \"PROP_AFTER\";\nexport const OP_PROP_SEMVER_LESS_THAN = \"PROP_SEMVER_LESS_THAN\";\nexport const OP_PROP_SEMVER_EQUAL = \"PROP_SEMVER_EQUAL\";\nexport const OP_PROP_SEMVER_GREATER_THAN = \"PROP_SEMVER_GREATER_THAN\";\nexport const OP_IN_SEG = \"IN_SEG\";\nexport const OP_NOT_IN_SEG = \"NOT_IN_SEG\";\n\n// ---- Segment resolver type ----\n\nexport type SegmentResolver = (segmentKey: string) => { result: boolean; found: boolean };\n\n// ---- Helper functions ----\n\nfunction toString(v: any): string {\n if (v === null || v === undefined) return \"\";\n return String(v);\n}\n\nfunction toStringSlice(v: any): string[] {\n if (v === null || v === undefined) return [];\n if (Array.isArray(v)) {\n return v.map((item) => toString(item));\n }\n return [toString(v)];\n}\n\nfunction getStringList(v: Value | undefined): string[] | undefined {\n if (v === undefined || v === null) return undefined;\n if (Array.isArray(v.value)) {\n return v.value.map((item: any) => toString(item));\n }\n return undefined;\n}\n\nfunction isString(v: any): v is string {\n return typeof v === \"string\";\n}\n\nfunction isNumber(v: any): boolean {\n return typeof v === \"number\";\n}\n\nfunction isNumericValue(v: any): boolean {\n if (typeof v === \"number\") return true;\n if (typeof v === \"string\") return !isNaN(Number(v)) && v.trim() !== \"\";\n return false;\n}\n\nfunction toFloat64(v: any): number | undefined {\n if (typeof v === \"number\") return v;\n if (typeof v === \"string\") {\n const n = Number(v);\n if (!isNaN(n)) return n;\n }\n return undefined;\n}\n\nfunction compareNumbers(a: any, b: any): number | undefined {\n const af = toFloat64(a);\n const bf = toFloat64(b);\n if (af === undefined || bf === undefined) return undefined;\n if (af < bf) return -1;\n if (af > bf) return 1;\n return 0;\n}\n\nfunction dateToMillis(val: any): number | undefined {\n if (typeof val === \"number\") return val;\n if (typeof val === \"string\") {\n // Try RFC3339 / ISO 8601\n const d = Date.parse(val);\n if (!isNaN(d)) return d;\n // Try as a plain number string\n const n = parseInt(val, 10);\n if (!isNaN(n)) return n;\n }\n return undefined;\n}\n\nfunction stringInSlice(s: string, list: string[]): boolean {\n return list.includes(s);\n}\n\nfunction startsWithAny(prefixes: string[], target: string): boolean {\n return prefixes.some((p) => target.startsWith(p));\n}\n\nfunction endsWithAny(suffixes: string[], target: string): boolean {\n return suffixes.some((s) => target.endsWith(s));\n}\n\nfunction containsAny(substrings: string[], target: string): boolean {\n return substrings.some((s) => target.includes(s));\n}\n\nfunction extractIntRange(v: Value | undefined): { start: number; end: number } {\n let start = Number.MIN_SAFE_INTEGER;\n let end = Number.MAX_SAFE_INTEGER;\n\n if (v === undefined || v === null) return { start, end };\n\n // The value should be a map with \"start\" and \"end\" from JSON\n if (typeof v.value === \"object\" && v.value !== null && !Array.isArray(v.value)) {\n if (\"start\" in v.value) {\n const s = toFloat64(v.value.start);\n if (s !== undefined) start = s;\n }\n if (\"end\" in v.value) {\n const e = toFloat64(v.value.end);\n if (e !== undefined) end = e;\n }\n }\n\n return { start, end };\n}\n\n// ---- Main evaluation function ----\n\n/**\n * Evaluate a single criterion against a context value.\n *\n * This is a faithful port of the Go SDK's EvaluateCriterion function.\n */\nexport function evaluateCriterion(\n contextValue: any,\n contextExists: boolean,\n criterion: Criterion,\n segmentResolver?: SegmentResolver\n): boolean {\n const matchValue = criterion.valueToMatch;\n\n switch (criterion.operator) {\n case OP_NOT_SET:\n return false;\n\n case OP_ALWAYS_TRUE:\n return true;\n\n case OP_PROP_IS_ONE_OF:\n case OP_PROP_IS_NOT_ONE_OF: {\n if (contextExists && matchValue !== undefined) {\n const matchStrings = getStringList(matchValue);\n if (matchStrings !== undefined) {\n const contextStrings = toStringSlice(contextValue);\n let matchFound = false;\n for (const cv of contextStrings) {\n if (stringInSlice(cv, matchStrings)) {\n matchFound = true;\n break;\n }\n }\n return matchFound === (criterion.operator === OP_PROP_IS_ONE_OF);\n }\n }\n return criterion.operator === OP_PROP_IS_NOT_ONE_OF;\n }\n\n case OP_PROP_STARTS_WITH_ONE_OF:\n case OP_PROP_DOES_NOT_START_WITH_ONE_OF: {\n if (contextExists && matchValue !== undefined) {\n const matchStrings = getStringList(matchValue);\n if (matchStrings !== undefined) {\n const cv = toString(contextValue);\n const matchFound = startsWithAny(matchStrings, cv);\n return matchFound === (criterion.operator === OP_PROP_STARTS_WITH_ONE_OF);\n }\n }\n return criterion.operator === OP_PROP_DOES_NOT_START_WITH_ONE_OF;\n }\n\n case OP_PROP_ENDS_WITH_ONE_OF:\n case OP_PROP_DOES_NOT_END_WITH_ONE_OF: {\n if (contextExists && matchValue !== undefined) {\n const matchStrings = getStringList(matchValue);\n if (matchStrings !== undefined) {\n const cv = toString(contextValue);\n const matchFound = endsWithAny(matchStrings, cv);\n return matchFound === (criterion.operator === OP_PROP_ENDS_WITH_ONE_OF);\n }\n }\n return criterion.operator === OP_PROP_DOES_NOT_END_WITH_ONE_OF;\n }\n\n case OP_PROP_CONTAINS_ONE_OF:\n case OP_PROP_DOES_NOT_CONTAIN_ONE_OF: {\n if (contextExists && matchValue !== undefined) {\n const matchStrings = getStringList(matchValue);\n if (matchStrings !== undefined) {\n const cv = toString(contextValue);\n const matchFound = containsAny(matchStrings, cv);\n return matchFound === (criterion.operator === OP_PROP_CONTAINS_ONE_OF);\n }\n }\n return criterion.operator === OP_PROP_DOES_NOT_CONTAIN_ONE_OF;\n }\n\n case OP_PROP_MATCHES:\n case OP_PROP_DOES_NOT_MATCH: {\n if (contextExists && matchValue !== undefined && isString(contextValue) && isString(matchValue.value)) {\n try {\n const re = new RegExp(matchValue.value);\n const matched = re.test(contextValue);\n return matched === (criterion.operator === OP_PROP_MATCHES);\n } catch {\n // Invalid regex\n }\n }\n return false;\n }\n\n case OP_HIERARCHICAL_MATCH: {\n if (contextExists && matchValue !== undefined) {\n const cv = toString(contextValue);\n const mv = toString(matchValue.value);\n return cv.startsWith(mv);\n }\n return false;\n }\n\n case OP_IN_INT_RANGE: {\n if (contextExists && matchValue !== undefined) {\n const { start, end } = extractIntRange(matchValue);\n const numVal = toFloat64(contextValue);\n if (numVal !== undefined) {\n return numVal >= start && numVal < end;\n }\n }\n return false;\n }\n\n case OP_PROP_GREATER_THAN:\n case OP_PROP_GREATER_THAN_OR_EQUAL:\n case OP_PROP_LESS_THAN:\n case OP_PROP_LESS_THAN_OR_EQUAL: {\n if (contextExists && matchValue !== undefined && isNumber(contextValue) && isNumericValue(matchValue.value)) {\n const cmp = compareNumbers(contextValue, matchValue.value);\n if (cmp !== undefined) {\n switch (criterion.operator) {\n case OP_PROP_GREATER_THAN:\n return cmp > 0;\n case OP_PROP_GREATER_THAN_OR_EQUAL:\n return cmp >= 0;\n case OP_PROP_LESS_THAN:\n return cmp < 0;\n case OP_PROP_LESS_THAN_OR_EQUAL:\n return cmp <= 0;\n }\n }\n }\n return false;\n }\n\n case OP_PROP_BEFORE:\n case OP_PROP_AFTER: {\n if (contextExists && matchValue !== undefined) {\n const contextMillis = dateToMillis(contextValue);\n const matchMillis = dateToMillis(matchValue.value);\n if (contextMillis !== undefined && matchMillis !== undefined) {\n if (criterion.operator === OP_PROP_BEFORE) {\n return contextMillis < matchMillis;\n }\n return contextMillis > matchMillis;\n }\n }\n return false;\n }\n\n case OP_PROP_SEMVER_LESS_THAN:\n case OP_PROP_SEMVER_EQUAL:\n case OP_PROP_SEMVER_GREATER_THAN: {\n if (contextExists && matchValue !== undefined && isString(contextValue) && isString(matchValue.value)) {\n const svContext = parseSemver(contextValue);\n const svMatch = parseSemver(matchValue.value);\n if (svContext !== undefined && svMatch !== undefined) {\n const cmp = compareSemver(svContext, svMatch);\n switch (criterion.operator) {\n case OP_PROP_SEMVER_LESS_THAN:\n return cmp < 0;\n case OP_PROP_SEMVER_EQUAL:\n return cmp === 0;\n case OP_PROP_SEMVER_GREATER_THAN:\n return cmp > 0;\n }\n }\n }\n return false;\n }\n\n case OP_IN_SEG:\n case OP_NOT_IN_SEG: {\n if (matchValue !== undefined && segmentResolver !== undefined) {\n const segmentKey = toString(matchValue.value);\n const { result, found } = segmentResolver(segmentKey);\n if (!found) {\n return criterion.operator === OP_NOT_IN_SEG;\n }\n return result === (criterion.operator === OP_IN_SEG);\n }\n return criterion.operator === OP_NOT_IN_SEG;\n }\n\n default:\n return false;\n }\n}\n","import murmurhash from \"murmurhash\";\n\n/**\n * Hash a string to a float64 in [0, 1) using Murmur3.\n * This matches the Go SDK's HashZeroToOne implementation.\n */\nexport function hashZeroToOne(value: string): number {\n const hash = murmurhash.v3(value);\n // MaxUint32 = 4294967295\n return hash / 4294967295;\n}\n","import type { Contexts, Value, WeightedValuesData } from \"./types\";\nimport { hashZeroToOne } from \"./hashing\";\nimport { contextLookup } from \"./context\";\n\n/**\n * WeightedValueResolver resolves weighted value distributions to a single value.\n *\n * This is a faithful port of the Go SDK's WeightedValueResolver.\n */\nexport class WeightedValueResolver {\n /**\n * Resolve picks a value from the weighted distribution.\n *\n * If hashByPropertyName is set and the context has a value for that property,\n * the selection is deterministic via Murmur3 hash. Otherwise, it falls back\n * to Math.random().\n *\n * Returns the selected value and its index, or [undefined, -1] if no values.\n */\n resolve(\n wv: WeightedValuesData,\n configKey: string,\n contexts: Contexts\n ): { value: Value | undefined; index: number } {\n const fraction = this.getUserFraction(wv, configKey, contexts);\n\n let totalWeight = 0;\n for (const entry of wv.weightedValues) {\n totalWeight += entry.weight;\n }\n\n const threshold = fraction * totalWeight;\n\n let runningSum = 0;\n for (let i = 0; i < wv.weightedValues.length; i++) {\n runningSum += wv.weightedValues[i]!.weight;\n if (runningSum >= threshold) {\n return { value: { ...wv.weightedValues[i]!.value }, index: i };\n }\n }\n\n // Fallback: return the first value (should not normally be reached)\n if (wv.weightedValues.length > 0) {\n return { value: { ...wv.weightedValues[0]!.value }, index: 0 };\n }\n return { value: undefined, index: -1 };\n }\n\n private getUserFraction(\n wv: WeightedValuesData,\n configKey: string,\n contexts: Contexts\n ): number {\n if (wv.hashByPropertyName) {\n const value = contextLookup(contexts, wv.hashByPropertyName);\n if (value !== undefined && value !== null) {\n const valueToHash = `${configKey}${value}`;\n return hashZeroToOne(valueToHash);\n }\n }\n return Math.random();\n }\n}\n","import type {\n ConfigResponse,\n Contexts,\n Criterion,\n EvalMatch,\n Rule,\n Value,\n} from \"./types\";\nimport { getContextValue } from \"./context\";\nimport { evaluateCriterion } from \"./operators\";\nimport type { SegmentResolver } from \"./operators\";\nimport { WeightedValueResolver } from \"./weighted\";\nimport type { ConfigStore } from \"./store\";\n\n/**\n * Evaluator is the main evaluation engine. It evaluates configs against contexts,\n * resolving rules, operators, segments, and weighted values.\n *\n * This is a faithful port of the Go SDK's evalcore.Evaluator.\n */\nexport class Evaluator {\n private configStore: ConfigStore;\n private weighted: WeightedValueResolver;\n\n constructor(configStore: ConfigStore) {\n this.configStore = configStore;\n this.weighted = new WeightedValueResolver();\n }\n\n /**\n * Evaluate a config for the given environment and context.\n *\n * Evaluation flow:\n * 1. Find the environment block matching envID (if any)\n * 2. Iterate its rules top-to-bottom; first match wins\n * 3. If no env-specific match, fall back to default.rules\n * 4. For each rule, all criteria must match (AND logic)\n * 5. If matched value is weighted_values, resolve through WeightedValueResolver\n */\n evaluateConfig(\n cfg: ConfigResponse,\n envID: string,\n contexts: Contexts\n ): EvalMatch {\n // Try environment-specific rules first\n if (envID && cfg.environment && cfg.environment.id === envID) {\n const match = this.evaluateRules(cfg, cfg.environment.rules ?? [], contexts, 0);\n if (match !== undefined) {\n return match;\n }\n }\n\n // Fall back to default rules\n const match = this.evaluateRules(cfg, cfg.default.rules ?? [], contexts, 0);\n if (match !== undefined) {\n return match;\n }\n\n return { isMatch: false, ruleIndex: -1, weightedValueIndex: -1 };\n }\n\n private evaluateRules(\n cfg: ConfigResponse,\n rules: Rule[],\n contexts: Contexts,\n ruleIndexOffset: number\n ): EvalMatch | undefined {\n for (let i = 0; i < rules.length; i++) {\n const rule = rules[i]!;\n if (this.evaluateAllCriteria(cfg, rule.criteria, contexts)) {\n const value = { ...rule.value };\n const match: EvalMatch = {\n isMatch: true,\n value,\n ruleIndex: ruleIndexOffset + i,\n weightedValueIndex: -1,\n };\n\n // Resolve weighted values\n if (value.type === \"weighted_values\" && value.value) {\n const wvData = value.value;\n if (wvData && wvData.weightedValues) {\n const resolved = this.weighted.resolve(wvData, cfg.key, contexts);\n if (resolved.value !== undefined) {\n match.value = resolved.value;\n match.weightedValueIndex = resolved.index;\n }\n }\n }\n\n return match;\n }\n }\n return undefined;\n }\n\n private evaluateAllCriteria(\n cfg: ConfigResponse,\n criteria: Criterion[],\n contexts: Contexts\n ): boolean {\n for (const criterion of criteria) {\n if (!this.evaluateSingleCriterion(cfg, criterion, contexts)) {\n return false;\n }\n }\n return true;\n }\n\n private evaluateSingleCriterion(\n cfg: ConfigResponse,\n criterion: Criterion,\n contexts: Contexts\n ): boolean {\n const propertyName = criterion.propertyName ?? \"\";\n const { value: contextValue, exists: contextExists } = getContextValue(\n contexts,\n propertyName\n );\n\n // Build a segment resolver that recursively evaluates segment configs\n const segmentResolver: SegmentResolver = (segmentKey: string) => {\n const segConfig = this.configStore.get(segmentKey);\n if (segConfig === undefined) {\n return { result: false, found: false };\n }\n // Evaluate the segment config (segments have no environment, use default rules)\n const segMatch = this.evaluateConfig(segConfig, \"\", contexts);\n if (!segMatch.isMatch || segMatch.value === undefined) {\n return { result: false, found: false };\n }\n return { result: !!segMatch.value.value, found: true };\n };\n\n return evaluateCriterion(contextValue, contextExists, criterion, segmentResolver);\n }\n}\n","import { randomBytes, createCipheriv, createDecipheriv } from \"crypto\";\nimport type { CipherGCMTypes } from \"crypto\";\n\nconst CIPHER_TYPE: CipherGCMTypes = \"aes-256-gcm\";\nconst SEPARATOR = \"--\";\nconst KEY_LENGTH = 32; // 32 bytes for aes-256-gcm\n\n/**\n * Generate a new random hex-encoded 32-byte key for AES-256-GCM encryption.\n */\nexport function generateNewHexKey(): string {\n return randomBytes(KEY_LENGTH).toString(\"hex\");\n}\n\n/**\n * Encrypt a string using AES-256-GCM.\n *\n * Returns a string in format: \"DATA--IV--AUTH_TAG\" where each part is hex-encoded.\n */\nexport function encrypt(clearText: string, keyStringHex: string): string {\n if (keyStringHex.length !== KEY_LENGTH * 2) {\n throw new Error(\n `Invalid key length. Key must be a 64 character hex string (representing a 32-byte key). You provided ${keyStringHex.length} characters.`\n );\n }\n\n const key = Buffer.from(keyStringHex, \"hex\");\n const iv = randomBytes(12);\n const cipher = createCipheriv(CIPHER_TYPE, key, iv);\n let encrypted = cipher.update(clearText, \"utf8\", \"hex\");\n encrypted += cipher.final(\"hex\");\n const tag = cipher.getAuthTag().toString(\"hex\");\n return [encrypted, iv.toString(\"hex\"), tag].join(SEPARATOR);\n}\n\n/**\n * Decrypt an AES-256-GCM encrypted value.\n *\n * The encrypted string must be in format: \"DATA--IV--AUTH_TAG\" where each part is hex-encoded.\n */\nexport function decrypt(encryptedString: string, keyStringHex: string): string {\n if (keyStringHex.length !== 64) {\n throw new Error(\n \"Invalid key length. Key must be a 64-character hex string.\"\n );\n }\n\n const key = Buffer.from(keyStringHex, \"hex\");\n const parts = encryptedString.split(SEPARATOR);\n\n if (parts.length !== 3) {\n throw new Error(\n \"Invalid encrypted string. Must contain encrypted data, IV, and auth tag.\"\n );\n }\n\n const encryptedDataPart = parts[0]!;\n const ivPart = parts[1]!;\n const authTagPart = parts[2]!;\n\n if (encryptedDataPart === \"\") {\n return \"\";\n }\n\n const encryptedData = Buffer.from(encryptedDataPart, \"hex\");\n const iv = Buffer.from(ivPart, \"hex\");\n const authTag = Buffer.from(authTagPart, \"hex\");\n\n const decipher = createDecipheriv(CIPHER_TYPE, key, iv);\n decipher.setAuthTag(authTag);\n\n let decrypted = decipher.update(encryptedData);\n decrypted = Buffer.concat([decrypted, decipher.final()]);\n return decrypted.toString(\"utf8\");\n}\n","const PATTERN =\n /P(?:(?<days>\\d+(?:\\.\\d+)?)D)?(?:T(?:(?<hours>\\d+(?:\\.\\d+)?)H)?(?:(?<minutes>\\d+(?:\\.\\d+)?)M)?(?:(?<seconds>\\d+(?:\\.\\d+)?)S)?)?/;\n\nconst MINUTES_IN_SECONDS = 60;\nconst HOURS_IN_SECONDS = 60 * MINUTES_IN_SECONDS;\nconst DAYS_IN_SECONDS = 24 * HOURS_IN_SECONDS;\n\n/**\n * Parse an ISO 8601 duration string and return the number of milliseconds.\n *\n * Supports formats like: PT0.2S, PT90S, PT1.5M, PT0.5H, P1DT6H2M1.5S\n */\nexport function durationToMilliseconds(duration: string): number {\n const match = PATTERN.exec(duration);\n if (match === null) {\n return 0;\n }\n\n const days = parseFloat(match.groups?.[\"days\"] ?? \"0\");\n const hours = parseFloat(match.groups?.[\"hours\"] ?? \"0\");\n const minutes = parseFloat(match.groups?.[\"minutes\"] ?? \"0\");\n const seconds = parseFloat(match.groups?.[\"seconds\"] ?? \"0\");\n\n return (\n (days * DAYS_IN_SECONDS +\n hours * HOURS_IN_SECONDS +\n minutes * MINUTES_IN_SECONDS +\n seconds) *\n 1000\n );\n}\n","import type { ConfigResponse, Contexts, GetValue, Value, ValueType } from \"./types\";\nimport type { ConfigStore } from \"./store\";\nimport type { Evaluator } from \"./evaluator\";\nimport { decrypt } from \"./encryption\";\nimport { durationToMilliseconds } from \"./duration\";\nimport { createHash } from \"crypto\";\n\nconst TRUE_VALUES = new Set([\"true\", \"1\", \"t\", \"yes\"]);\n\nconst CONFIDENTIAL_PREFIX = \"*****\";\n\n/**\n * Make a confidential hash for reporting (MD5 last 5 chars).\n */\nfunction makeConfidential(secret: string): string {\n const md5 = createHash(\"md5\").update(secret).digest(\"hex\");\n return `${CONFIDENTIAL_PREFIX}${md5.slice(-5)}`;\n}\n\n/**\n * Resolver handles post-evaluation value resolution:\n * - ENV_VAR provided values\n * - Decryption of confidential values\n * - Type coercion\n * - Duration parsing\n * - JSON parsing\n */\nexport class Resolver {\n private store: ConfigStore;\n private evaluator: Evaluator;\n\n constructor(store: ConfigStore, evaluator: Evaluator) {\n this.store = store;\n this.evaluator = evaluator;\n }\n\n /**\n * Resolve a matched value. Handles:\n * - provided values (ENV_VAR lookup)\n * - decryption of confidential values\n */\n resolveValue(\n val: Value,\n configKey: string,\n valueType: ValueType,\n envID: string,\n contexts: Contexts\n ): { resolved: Value; reportableValue?: GetValue } {\n // Handle provided values (ENV_VAR)\n if (val.type === \"provided\") {\n const provided = val.value;\n if (provided && provided.source === \"ENV_VAR\" && provided.lookup) {\n const envValue = process.env[provided.lookup];\n if (envValue === undefined) {\n throw new Error(\n `Environment variable \"${provided.lookup}\" not set for config \"${configKey}\"`\n );\n }\n\n const coerced = coerceValue(envValue, valueType);\n return {\n resolved: {\n type: valueTypeForCoerced(valueType),\n value: coerced,\n },\n };\n }\n return { resolved: val };\n }\n\n // Handle decryption\n if (val.confidential && val.decryptWith) {\n const keyCfg = this.store.get(val.decryptWith);\n if (keyCfg === undefined) {\n throw new Error(`Decryption key config \"${val.decryptWith}\" not found`);\n }\n\n const keyMatch = this.evaluator.evaluateConfig(keyCfg, envID, contexts);\n if (!keyMatch.isMatch || keyMatch.value === undefined) {\n throw new Error(`Decryption key config \"${val.decryptWith}\" did not match`);\n }\n\n // Resolve the key value recursively (it could itself be a provided ENV_VAR)\n const { resolved: resolvedKey } = this.resolveValue(\n keyMatch.value,\n keyCfg.key,\n keyCfg.valueType,\n envID,\n contexts\n );\n\n const secretKey = String(resolvedKey.value);\n if (!secretKey) {\n throw new Error(`Decryption key from \"${val.decryptWith}\" is empty`);\n }\n\n const decrypted = decrypt(String(val.value), secretKey);\n return {\n resolved: {\n type: \"string\",\n value: decrypted,\n confidential: true,\n },\n reportableValue: makeConfidential(String(val.value)),\n };\n }\n\n // Check if value is confidential (but not encrypted)\n if (val.confidential) {\n return {\n resolved: val,\n reportableValue: makeConfidential(String(val.value)),\n };\n }\n\n return { resolved: val };\n }\n\n /**\n * Unwrap a resolved value to a plain JS value.\n */\n unwrapValue(val: Value): GetValue {\n switch (val.type) {\n case \"bool\":\n return !!val.value;\n case \"int\":\n return typeof val.value === \"number\" ? val.value : parseInt(String(val.value), 10);\n case \"double\":\n return typeof val.value === \"number\" ? val.value : parseFloat(String(val.value));\n case \"string\":\n return String(val.value ?? \"\");\n case \"json\":\n if (typeof val.value === \"string\") {\n try {\n return JSON.parse(val.value);\n } catch {\n return val.value;\n }\n }\n return val.value;\n case \"string_list\":\n if (Array.isArray(val.value)) {\n return val.value.map((v: any) => String(v));\n }\n return [];\n case \"log_level\":\n return typeof val.value === \"number\" ? val.value : String(val.value ?? \"\");\n case \"duration\":\n return durationToMilliseconds(String(val.value ?? \"\"));\n default:\n return val.value;\n }\n }\n}\n\nfunction coerceValue(value: string, valueType: ValueType): any {\n switch (valueType) {\n case \"string\":\n return value;\n case \"int\": {\n const n = parseInt(value, 10);\n if (isNaN(n)) throw new Error(`Cannot convert \"${value}\" to int`);\n return n;\n }\n case \"double\": {\n const n = parseFloat(value);\n if (isNaN(n)) throw new Error(`Cannot convert \"${value}\" to double`);\n return n;\n }\n case \"bool\":\n return TRUE_VALUES.has(value.toLowerCase());\n case \"string_list\":\n return value.split(/\\s*,\\s*/);\n case \"duration\":\n return value;\n default:\n return value;\n }\n}\n\nfunction valueTypeForCoerced(valueType: ValueType): ValueType {\n switch (valueType) {\n case \"int\":\n return \"int\";\n case \"double\":\n return \"double\";\n case \"bool\":\n return \"bool\";\n case \"string_list\":\n return \"string_list\";\n default:\n return \"string\";\n }\n}\n","import type { ConfigEnvelope } from \"./types\";\n\nconst SDK_VERSION = \"0.1.0\";\n\nexport interface FetchResult {\n envelope?: ConfigEnvelope;\n notChanged: boolean;\n}\n\n/**\n * HTTP transport for fetching configs from the Quonfig API.\n *\n * Supports ETag-based caching to avoid re-downloading unchanged configs.\n */\nexport const DEFAULT_TELEMETRY_URL = \"https://telemetry.quonfig.com\";\n\nexport class Transport {\n private baseUrl: string;\n private telemetryBaseUrl: string;\n private sdkKey: string;\n private etag: string = \"\";\n\n constructor(baseUrl: string, sdkKey: string, telemetryBaseUrl?: string) {\n this.baseUrl = baseUrl.replace(/\\/$/, \"\");\n // Priority: QUONFIG_TELEMETRY_URL env var > constructor option > default\n const envUrl = process.env.QUONFIG_TELEMETRY_URL;\n const url = envUrl || telemetryBaseUrl || DEFAULT_TELEMETRY_URL;\n this.telemetryBaseUrl = url.replace(/\\/$/, \"\");\n this.sdkKey = sdkKey;\n }\n\n /**\n * Build the Basic auth header value.\n * Uses username \"1\" like the Go SDK: base64(\"1:{sdkKey}\")\n */\n private getAuthHeader(): string {\n return \"Basic \" + Buffer.from(`1:${this.sdkKey}`).toString(\"base64\");\n }\n\n /**\n * Common headers for all requests.\n */\n private getHeaders(extra?: Record<string, string>): Record<string, string> {\n return {\n Authorization: this.getAuthHeader(),\n \"X-Quonfig-SDK-Version\": `node-${SDK_VERSION}`,\n Accept: \"application/json\",\n ...extra,\n };\n }\n\n /**\n * Fetch configs from GET /api/v2/configs with ETag caching.\n *\n * Returns `{ notChanged: true }` if the server responds with 304.\n */\n async fetchConfigs(): Promise<FetchResult> {\n const headers = this.getHeaders();\n if (this.etag) {\n headers[\"If-None-Match\"] = this.etag;\n }\n\n const response = await fetch(`${this.baseUrl}/api/v2/configs`, {\n method: \"GET\",\n headers,\n });\n\n if (response.status === 304) {\n return { notChanged: true };\n }\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new Error(`Unexpected status ${response.status}: ${body}`);\n }\n\n const etag = response.headers.get(\"ETag\");\n if (etag) {\n this.etag = etag;\n }\n\n const envelope = (await response.json()) as ConfigEnvelope;\n return { envelope, notChanged: false };\n }\n\n /**\n * Post telemetry data to the telemetry endpoint.\n */\n async postTelemetry(data: any): Promise<void> {\n const headers = this.getHeaders({\n \"Content-Type\": \"application/json\",\n });\n\n const response = await fetch(`${this.telemetryBaseUrl}/api/v1/telemetry/`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(data),\n });\n\n if (!response.ok) {\n // Telemetry failures are non-fatal; just log\n const body = await response.text().catch(() => \"\");\n console.warn(`[quonfig] Telemetry POST failed: ${response.status} ${body}`);\n }\n }\n\n /**\n * Get the SSE URL for config streaming.\n */\n getSSEUrl(): string {\n return `${this.baseUrl}/api/v2/sse/config`;\n }\n\n /**\n * Get auth headers for SSE connection.\n */\n getSSEHeaders(): Record<string, string> {\n return this.getHeaders({\n Accept: \"text/event-stream\",\n });\n }\n}\n","import type { ConfigEnvelope } from \"./types\";\nimport type { Transport } from \"./transport\";\n\n/**\n * SSE connection for receiving real-time config updates.\n *\n * Uses the `eventsource` npm package for Server-Sent Events.\n */\nexport class SSEConnection {\n private transport: Transport;\n private eventSource: any = null;\n\n constructor(transport: Transport) {\n this.transport = transport;\n }\n\n /**\n * Start listening for SSE events.\n *\n * The onUpdate callback receives the new config envelope on each event.\n */\n start(onUpdate: (envelope: ConfigEnvelope) => void): void {\n // Dynamic import of eventsource to avoid issues when it's not installed\n this.connectSSE(onUpdate).catch((err) => {\n console.warn(\"[quonfig] SSE connection failed:\", err);\n });\n }\n\n private async connectSSE(onUpdate: (envelope: ConfigEnvelope) => void): Promise<void> {\n try {\n // Use dynamic import for eventsource\n const EventSourceModule = await import(\"eventsource\");\n const EventSource = EventSourceModule.default || EventSourceModule;\n\n const url = this.transport.getSSEUrl();\n const headers = this.transport.getSSEHeaders();\n\n this.eventSource = new EventSource(url, { headers });\n\n this.eventSource.onmessage = (event: any) => {\n try {\n const envelope: ConfigEnvelope = JSON.parse(event.data);\n onUpdate(envelope);\n } catch (err) {\n console.warn(\"[quonfig] SSE message parse error:\", err);\n }\n };\n\n this.eventSource.onerror = (err: any) => {\n console.warn(\"[quonfig] SSE error:\", err);\n // EventSource will auto-reconnect\n };\n } catch (err) {\n console.warn(\"[quonfig] Failed to initialize SSE:\", err);\n }\n }\n\n /**\n * Close the SSE connection.\n */\n close(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n }\n}\n","import type { Contexts, GetValue, LogLevelName, LogLevelNumber } from \"./types\";\n\nexport const LOG_LEVEL_PREFIX = \"log-level.\";\n\nconst VALID_LOG_LEVEL_NAMES: readonly LogLevelName[] = [\n \"trace\",\n \"debug\",\n \"info\",\n \"warn\",\n \"error\",\n \"fatal\",\n] as const;\n\nconst WORD_LEVEL_LOOKUP: Record<LogLevelName, LogLevelNumber> = {\n trace: 1,\n debug: 2,\n info: 3,\n warn: 5,\n error: 6,\n fatal: 9,\n};\n\nconst NUMBER_LEVEL_LOOKUP: Record<LogLevelNumber, LogLevelName> = {\n 1: \"trace\",\n 2: \"debug\",\n 3: \"info\",\n 5: \"warn\",\n 6: \"error\",\n 9: \"fatal\",\n};\n\n/**\n * Convert a log level name to its numeric value.\n */\nexport function wordLevelToNumber(level: LogLevelName): LogLevelNumber | undefined {\n return WORD_LEVEL_LOOKUP[level];\n}\n\n/**\n * Parse a log level (string name or number) to a numeric value.\n */\nexport function parseLevel(level: string | number | undefined): LogLevelNumber | undefined {\n if (typeof level === \"number\") {\n return level as LogLevelNumber;\n }\n if (typeof level === \"string\") {\n // Try as a log level name\n const lower = level.toLowerCase() as LogLevelName;\n if (WORD_LEVEL_LOOKUP[lower] !== undefined) {\n return WORD_LEVEL_LOOKUP[lower];\n }\n // Try as a number string (e.g., from config values)\n const n = parseInt(level, 10);\n if (!isNaN(n) && NUMBER_LEVEL_LOOKUP[n as LogLevelNumber] !== undefined) {\n return n as LogLevelNumber;\n }\n }\n return undefined;\n}\n\n/**\n * Check if a log message at desiredLevel should be logged, given the logger hierarchy.\n *\n * Walks up the logger name hierarchy (e.g., \"log-level.a.b.c\" -> \"log-level.a.b\" -> \"log-level.a\")\n * looking for a matching config. If no config is found, uses defaultLevel.\n */\nexport function shouldLog(args: {\n loggerName: string;\n desiredLevel: LogLevelNumber;\n defaultLevel: LogLevelNumber;\n getConfig: (key: string) => GetValue;\n}): boolean {\n const { loggerName, desiredLevel, defaultLevel, getConfig } = args;\n\n let loggerNameWithPrefix = LOG_LEVEL_PREFIX + loggerName;\n\n while (loggerNameWithPrefix.includes(\".\")) {\n const resolvedLevel = getConfig(loggerNameWithPrefix);\n\n if (resolvedLevel !== undefined) {\n return Number(resolvedLevel) <= desiredLevel;\n }\n\n loggerNameWithPrefix = loggerNameWithPrefix.slice(\n 0,\n loggerNameWithPrefix.lastIndexOf(\".\")\n );\n }\n\n return defaultLevel <= desiredLevel;\n}\n","import type { Evaluation, EvaluationSummary, TelemetryEvent } from \"../types\";\n\n/**\n * Collects evaluation summaries for telemetry reporting.\n *\n * Each evaluation is aggregated by (configKey, configType) and\n * counted by (configId, ruleIndex, value, weightedValueIndex).\n */\nexport class EvaluationSummaryCollector {\n private enabled: boolean;\n private data: Map<string, Map<string, number>> = new Map();\n private startAt: number | undefined;\n private maxDataSize: number;\n\n constructor(enabled: boolean, maxDataSize: number = 10000) {\n this.enabled = enabled;\n this.maxDataSize = maxDataSize;\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n push(evaluation: Evaluation): void {\n if (!this.enabled) return;\n if (this.data.size >= this.maxDataSize) return;\n if (evaluation.unwrappedValue === undefined) return;\n if (evaluation.configType === \"log_level\") return;\n\n this.startAt = this.startAt ?? Date.now();\n\n const key = JSON.stringify([evaluation.configKey, evaluation.configType]);\n const counter = JSON.stringify([\n evaluation.configId,\n evaluation.ruleIndex,\n typeof evaluation.unwrappedValue,\n evaluation.reportableValue ?? evaluation.unwrappedValue,\n evaluation.weightedValueIndex,\n ]);\n\n let countersForKey = this.data.get(key);\n if (countersForKey === undefined) {\n countersForKey = new Map();\n this.data.set(key, countersForKey);\n }\n\n const currentCount = countersForKey.get(counter) ?? 0;\n countersForKey.set(counter, currentCount + 1);\n }\n\n /**\n * Drain collected summaries into a TelemetryEvent, or return undefined if empty.\n */\n drain(): TelemetryEvent | undefined {\n if (this.data.size === 0) return undefined;\n\n const summaries: EvaluationSummary[] = [];\n\n this.data.forEach((rawCounters, keyJSON) => {\n const [configKey, configType] = JSON.parse(keyJSON);\n\n const counters: any[] = [];\n rawCounters.forEach((count, counterJSON) => {\n const [configId, ruleIndex, valueType, value, weightedValueIndex] =\n JSON.parse(counterJSON);\n\n const counter: any = {\n configId,\n conditionalValueIndex: ruleIndex,\n configRowIndex: 0,\n selectedValue: { [valueType]: value },\n count,\n };\n\n if (weightedValueIndex !== undefined && weightedValueIndex >= 0) {\n counter.weightedValueIndex = weightedValueIndex;\n }\n\n counters.push(counter);\n });\n\n summaries.push({\n key: configKey,\n type: configType,\n counters,\n });\n });\n\n const event: TelemetryEvent = {\n summaries: {\n start: this.startAt ?? Date.now(),\n end: Date.now(),\n summaries,\n },\n };\n\n // Clear data after drain\n this.data.clear();\n this.startAt = undefined;\n\n return event;\n }\n}\n","import type { ContextShape, Contexts, ContextUploadMode, TelemetryEvent } from \"../types\";\n\n/**\n * Collects context shapes (field names + types) for telemetry reporting.\n */\nexport class ContextShapeCollector {\n private enabled: boolean;\n private data: Map<string, Record<string, number>> = new Map();\n private maxDataSize: number;\n\n constructor(contextUploadMode: ContextUploadMode, maxDataSize: number = 10000) {\n this.enabled = contextUploadMode !== \"none\";\n this.maxDataSize = maxDataSize;\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n push(contexts: Contexts): void {\n if (!this.enabled) return;\n\n for (const [name, ctx] of Object.entries(contexts)) {\n for (const [key, value] of Object.entries(ctx)) {\n let shape = this.data.get(name);\n\n if (shape === undefined && this.data.size >= this.maxDataSize) {\n continue;\n }\n\n shape = shape ?? {};\n\n if (shape[key] === undefined) {\n shape[key] = fieldTypeForValue(value);\n this.data.set(name, shape);\n }\n }\n }\n }\n\n /**\n * Drain collected shapes into a TelemetryEvent, or return undefined if empty.\n */\n drain(): TelemetryEvent | undefined {\n if (this.data.size === 0) return undefined;\n\n const shapes: ContextShape[] = [];\n this.data.forEach((shape, name) => {\n shapes.push({ name, fieldTypes: shape });\n });\n\n // Clear data after drain\n this.data.clear();\n\n return {\n contextShapes: { shapes },\n };\n }\n}\n\n/**\n * Determine the field type number for a context value.\n * Maps to the same type numbers as the prefab SDK:\n * 1 = int, 2 = string, 4 = double, 5 = bool, 10 = string_list\n */\nexport function fieldTypeForValue(value: unknown): number {\n if (Number.isInteger(value)) return 1;\n if (typeof value === \"number\") return 4;\n if (typeof value === \"boolean\") return 5;\n if (Array.isArray(value)) return 10;\n return 2; // string\n}\n","import type { Contexts, ContextUploadMode, ExampleContextEntry, TelemetryEvent } from \"../types\";\n\n/**\n * Collects example contexts for telemetry reporting.\n * Only collects when contextUploadMode is \"periodic_example\".\n */\nexport class ExampleContextCollector {\n private enabled: boolean;\n private data: Array<[number, Contexts]> = [];\n private seen: Map<string, number> = new Map();\n private maxDataSize: number;\n private rateLimitMs: number;\n\n constructor(\n contextUploadMode: ContextUploadMode,\n maxDataSize: number = 10000,\n rateLimitMs: number = 60 * 60 * 1000 // 1 hour\n ) {\n this.enabled = contextUploadMode === \"periodic_example\";\n this.maxDataSize = maxDataSize;\n this.rateLimitMs = rateLimitMs;\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n push(contexts: Contexts): void {\n if (!this.enabled) return;\n if (this.data.length >= this.maxDataSize) return;\n\n const key = this.groupedKey(contexts);\n if (key.length === 0) return;\n\n // Rate limit: skip if seen recently\n const lastSeen = this.seen.get(key);\n if (lastSeen !== undefined && Date.now() - lastSeen < this.rateLimitMs) {\n return;\n }\n\n this.data.push([Date.now(), contexts]);\n this.seen.set(key, Date.now());\n }\n\n /**\n * Drain collected examples into a TelemetryEvent, or return undefined if empty.\n */\n drain(): TelemetryEvent | undefined {\n if (this.data.length === 0) return undefined;\n\n const examples: ExampleContextEntry[] = this.data.map(([timestamp, contexts]) => {\n const contextsList = Object.entries(contexts).map(([type, ctx]) => {\n const values: Record<string, any> = {};\n for (const [key, value] of Object.entries(ctx)) {\n values[key] = value;\n }\n return { type, values };\n });\n\n return {\n timestamp,\n contextSet: { contexts: contextsList },\n };\n });\n\n // Clear data after drain\n this.data.length = 0;\n this.pruneCache();\n\n return {\n exampleContexts: { examples },\n };\n }\n\n private groupedKey(contexts: Contexts): string {\n return Object.values(contexts)\n .map((ctx) => {\n const key = ctx[\"key\"] ?? ctx[\"trackingId\"];\n return typeof key === \"string\" ? key : JSON.stringify(key);\n })\n .filter((str) => str !== undefined && str !== null && String(str).length > 0)\n .sort()\n .join(\"|\");\n }\n\n private pruneCache(): void {\n const now = Date.now();\n for (const [key, timestamp] of this.seen.entries()) {\n if (now - timestamp > this.rateLimitMs) {\n this.seen.delete(key);\n }\n }\n }\n}\n","import type { TelemetryEvent, TelemetryPayload } from \"../types\";\nimport type { Transport } from \"../transport\";\nimport type { EvaluationSummaryCollector } from \"./evaluationSummaries\";\nimport type { ContextShapeCollector } from \"./contextShapes\";\nimport type { ExampleContextCollector } from \"./exampleContexts\";\n\n/**\n * TelemetryReporter periodically drains collected telemetry data and sends it\n * to the Quonfig telemetry endpoint.\n */\nexport class TelemetryReporter {\n private transport: Transport;\n private instanceHash: string;\n private evaluationSummaries: EvaluationSummaryCollector;\n private contextShapes: ContextShapeCollector;\n private exampleContexts: ExampleContextCollector;\n private timer: ReturnType<typeof setTimeout> | undefined;\n private initialDelay: number;\n private maxDelay: number;\n private currentDelay: number;\n private stopped: boolean = false;\n\n constructor(args: {\n transport: Transport;\n instanceHash: string;\n evaluationSummaries: EvaluationSummaryCollector;\n contextShapes: ContextShapeCollector;\n exampleContexts: ExampleContextCollector;\n initialDelay?: number;\n maxDelay?: number;\n }) {\n this.transport = args.transport;\n this.instanceHash = args.instanceHash;\n this.evaluationSummaries = args.evaluationSummaries;\n this.contextShapes = args.contextShapes;\n this.exampleContexts = args.exampleContexts;\n this.initialDelay = args.initialDelay ?? 8000;\n this.maxDelay = args.maxDelay ?? 600000;\n this.currentDelay = this.initialDelay;\n }\n\n /**\n * Start the periodic telemetry reporting loop.\n */\n start(): void {\n if (this.stopped) return;\n this.scheduleNext();\n }\n\n /**\n * Stop telemetry reporting.\n */\n stop(): void {\n this.stopped = true;\n if (this.timer !== undefined) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n }\n\n private scheduleNext(): void {\n if (this.stopped) return;\n\n this.timer = setTimeout(async () => {\n try {\n await this.sync();\n // Success — reset to base interval\n this.currentDelay = this.initialDelay;\n } catch (err) {\n console.warn(\"[quonfig] Telemetry sync error:\", err);\n // Exponential backoff with cap on failure\n this.currentDelay = Math.min(this.currentDelay * 1.5, this.maxDelay);\n } finally {\n this.scheduleNext();\n }\n }, this.currentDelay);\n\n // Allow the timer to not prevent process exit\n if (this.timer && typeof this.timer === \"object\" && \"unref\" in this.timer) {\n this.timer.unref();\n }\n }\n\n private async sync(): Promise<void> {\n const events: TelemetryEvent[] = [];\n\n // Drain evaluation summaries\n const summaryEvent = this.evaluationSummaries.drain();\n if (summaryEvent) events.push(summaryEvent);\n\n // Drain context shapes\n const shapesEvent = this.contextShapes.drain();\n if (shapesEvent) events.push(shapesEvent);\n\n // Drain example contexts\n const examplesEvent = this.exampleContexts.drain();\n if (examplesEvent) events.push(examplesEvent);\n\n if (events.length === 0) return;\n\n const payload: TelemetryPayload = {\n instanceHash: this.instanceHash,\n events,\n };\n\n await this.transport.postTelemetry(payload);\n }\n}\n","// ---- Value Types ----\n\nexport type ValueType =\n | \"bool\"\n | \"int\"\n | \"double\"\n | \"string\"\n | \"json\"\n | \"string_list\"\n | \"log_level\"\n | \"weighted_values\"\n | \"schema\"\n | \"provided\"\n | \"duration\";\n\n// ---- Config Types ----\n\nexport type ConfigTypeString =\n | \"feature_flag\"\n | \"config\"\n | \"segment\"\n | \"log_level\"\n | \"schema\";\n\n// ---- Provided Data ----\n\nexport interface ProvidedData {\n source: string;\n lookup: string;\n}\n\n// ---- Weighted Values ----\n\nexport interface WeightedValue {\n weight: number;\n value: Value;\n}\n\nexport interface WeightedValuesData {\n weightedValues: WeightedValue[];\n hashByPropertyName?: string;\n}\n\n// ---- Schema ----\n\nexport interface SchemaData {\n schemaType: string;\n schema: string;\n}\n\n// ---- Value ----\n\nexport interface Value {\n type: ValueType;\n value: any;\n confidential?: boolean;\n decryptWith?: string;\n}\n\n// ---- Criterion ----\n\nexport interface Criterion {\n propertyName?: string;\n operator: string;\n valueToMatch?: Value;\n}\n\n// ---- Rule ----\n\nexport interface Rule {\n criteria: Criterion[];\n value: Value;\n}\n\n// ---- RuleSet ----\n\nexport interface RuleSet {\n rules: Rule[];\n}\n\n// ---- Environment ----\n\nexport interface Environment {\n id: string;\n rules: Rule[];\n}\n\n// ---- ConfigResponse ----\n\nexport interface ConfigResponse {\n id: string;\n key: string;\n type: ConfigTypeString;\n valueType: ValueType;\n sendToClientSdk: boolean;\n default: RuleSet;\n environment?: Environment;\n}\n\n// ---- ConfigEnvelope ----\n\nexport interface Meta {\n version: string;\n environment: string;\n workspaceId?: string;\n}\n\nexport interface ConfigEnvelope {\n configs: ConfigResponse[];\n meta: Meta;\n}\n\n// ---- Context ----\n\nexport type ContextValue = string | number | boolean | string[] | null | undefined;\n\nexport type Contexts = { [contextName: string]: { [key: string]: ContextValue } };\n\n// ---- GetValue ----\n\nexport type GetValue = string | number | boolean | string[] | undefined;\n\n// ---- On no default behavior ----\n\nexport type OnNoDefault = \"error\" | \"warn\" | \"ignore\";\n\n// ---- Context upload mode ----\n\nexport type ContextUploadMode = \"none\" | \"shapes_only\" | \"periodic_example\";\n\n// ---- Options ----\n\nexport interface QuonfigOptions {\n sdkKey: string;\n apiUrl?: string;\n /** Base URL for the dedicated telemetry service. Defaults to https://telemetry.quonfig.com. Overridden by QUONFIG_TELEMETRY_URL env var. */\n telemetryUrl?: string;\n enableSSE?: boolean;\n enablePolling?: boolean;\n pollInterval?: number;\n namespace?: string;\n globalContext?: Contexts;\n onNoDefault?: OnNoDefault;\n collectEvaluationSummaries?: boolean;\n collectLoggerCounts?: boolean;\n contextUploadMode?: ContextUploadMode;\n initTimeout?: number;\n datafile?: string | object;\n}\n\n// ---- Evaluation Result ----\n\nexport interface EvalMatch {\n isMatch: boolean;\n value?: Value;\n ruleIndex: number;\n weightedValueIndex: number;\n}\n\n// ---- Log Level ----\n\nexport type LogLevelName = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\nexport type LogLevelNumber = 1 | 2 | 3 | 5 | 6 | 9;\n\n// ---- Telemetry Event Types ----\n\nexport interface EvaluationCounter {\n configId: string;\n conditionalValueIndex: number;\n configRowIndex: number;\n selectedValue: any;\n count: number;\n weightedValueIndex?: number;\n}\n\nexport interface EvaluationSummary {\n key: string;\n type: string;\n counters: EvaluationCounter[];\n}\n\nexport interface ContextShape {\n name: string;\n fieldTypes: { [key: string]: number };\n}\n\nexport interface ExampleContextEntry {\n timestamp: number;\n contextSet: {\n contexts: Array<{\n type: string;\n values: { [key: string]: any };\n }>;\n };\n}\n\nexport interface TelemetryEvent {\n summaries?: {\n start: number;\n end: number;\n summaries: EvaluationSummary[];\n };\n contextShapes?: {\n shapes: ContextShape[];\n };\n exampleContexts?: {\n examples: ExampleContextEntry[];\n };\n}\n\nexport interface TelemetryPayload {\n instanceHash: string;\n events: TelemetryEvent[];\n}\n\n// ---- Internal Evaluation ----\n\nexport interface Evaluation {\n configId: string;\n configKey: string;\n configType: ConfigTypeString;\n unwrappedValue: GetValue;\n reportableValue?: GetValue;\n ruleIndex: number;\n weightedValueIndex?: number;\n}\n\n// ---- Enum-like constants for CLI compatibility ----\n\n// Runtime object for ConfigType enum access (e.g., ConfigType.FeatureFlag)\nexport const ConfigType = {\n FeatureFlag: \"feature_flag\" as ConfigTypeString,\n Config: \"config\" as ConfigTypeString,\n Segment: \"segment\" as ConfigTypeString,\n LogLevel: \"log_level\" as ConfigTypeString,\n Schema: \"schema\" as ConfigTypeString,\n} as const;\n\nexport const ProvidedSource = {\n EnvVar: \"ENV_VAR\",\n} as const;\n\n// ---- Typed Config interfaces (augmented by CLI codegen) ----\n\n// These are placeholder interfaces that the CLI's `gen` command\n// augments via TypeScript module augmentation.\nexport interface NodeServerConfigurationRaw {}\nexport interface NodeServerConfigurationAccessor {}\nexport type TypedNodeServerConfigurationRaw = NodeServerConfigurationRaw;\nexport type TypedNodeServerConfigurationAccessor = NodeServerConfigurationAccessor;\n","/**\n * CLI-compatibility types and utilities.\n *\n * These are needed by @quonfig/cli but are NOT part of the core SDK.\n * They provide the HTTP API client, SDK-key parsing, and legacy\n * config-value types that the CLI's CRUD commands depend on.\n */\n\nimport type { ConfigResponse, ValueType } from \"./types\";\n\n// ---- HTTP API Client ----\n\nexport interface ClientOptions {\n jwt?: string;\n sdkKey?: string;\n apiUrl: string;\n clientIdentifier: string;\n log?: (category: string | unknown, message?: unknown) => void;\n}\n\n/**\n * Minimal HTTP client for the Quonfig REST API.\n * Used by the CLI for CRUD operations (create, set-default, download, etc.).\n */\nexport class Client {\n private jwt?: string;\n private sdkKey?: string;\n private apiUrl: string;\n private clientIdentifier: string;\n private log: (category: string | unknown, message?: unknown) => void;\n\n constructor(options: ClientOptions) {\n this.jwt = options.jwt;\n this.sdkKey = options.sdkKey;\n this.apiUrl = options.apiUrl.replace(/\\/$/, \"\");\n this.clientIdentifier = options.clientIdentifier;\n this.log = options.log ?? (() => {});\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"X-Client-Version\": this.clientIdentifier,\n };\n\n if (this.jwt) {\n h[\"Authorization\"] = `Bearer ${this.jwt}`;\n } else if (this.sdkKey) {\n h[\"Authorization\"] = `Basic ${Buffer.from(this.sdkKey).toString(\"base64\")}`;\n }\n\n return h;\n }\n\n async get(path: string): Promise<Response> {\n const url = `${this.apiUrl}${path}`;\n this.log(\"ApiClient\", `GET ${url}`);\n return fetch(url, { method: \"GET\", headers: this.headers() });\n }\n\n async post(path: string, payload: unknown): Promise<Response> {\n const url = `${this.apiUrl}${path}`;\n this.log(\"ApiClient\", `POST ${url}`);\n return fetch(url, {\n method: \"POST\",\n headers: this.headers(),\n body: JSON.stringify(payload),\n });\n }\n\n async put(path: string, payload: unknown): Promise<Response> {\n const url = `${this.apiUrl}${path}`;\n this.log(\"ApiClient\", `PUT ${url}`);\n return fetch(url, {\n method: \"PUT\",\n headers: this.headers(),\n body: JSON.stringify(payload),\n });\n }\n}\n\n// ---- SDK Key Parsing ----\n\nexport interface ProjectEnvId {\n id: string;\n projectId: number;\n}\n\n/**\n * Parse a Prefab/Quonfig SDK key to extract the project-environment ID.\n * SDK keys are typically in the format: `<projectId>-<envId>-<secret>`\n */\nexport function getProjectEnvFromSdkKey(sdkKey: string): ProjectEnvId {\n const parts = sdkKey.split(\"-\");\n\n if (parts.length < 2) {\n throw new Error(`Invalid SDK key format: cannot extract projectEnvId`);\n }\n\n return {\n id: parts.slice(0, 2).join(\"-\"),\n projectId: Number.parseInt(parts[0], 10) || 0,\n };\n}\n\n// ---- Legacy ConfigValue / ConfigValueType ----\n\n/**\n * ConfigValueType enum, matching the legacy quonfig-common types.\n * Used by the CLI's coerce and config-value-dto utilities.\n */\nexport enum ConfigValueType {\n NotSetValue = 0,\n Int = 1,\n String = 2,\n Bytes = 3,\n Double = 4,\n Bool = 5,\n // 6 was WeightedValues in Prefab\n // 7 was LimitDefinition in Prefab\n LimitDefinition = 7,\n LogLevel = 8,\n StringList = 9,\n IntRange = 10,\n Duration = 11,\n Json = 12,\n}\n\n/**\n * ConfigValue represents a typed value in the legacy format.\n * Used by the CLI for constructing API request payloads.\n */\nexport interface ConfigValue {\n int?: bigint | number;\n string?: string;\n bytes?: Uint8Array;\n double?: number;\n bool?: boolean;\n logLevel?: string;\n stringList?: { values: string[] };\n intRange?: { start?: number; end?: number };\n duration?: { definition?: string; millis?: number };\n json?: { json: string };\n provided?: { source: string; lookup: string };\n confidential?: boolean;\n decryptWith?: string;\n}\n\n// ---- valueTypeStringForConfig ----\n\n/**\n * Extract the value-type string for a ConfigResponse (e.g., \"bool\", \"string\", \"int\").\n * Used by the CLI's `serve` command to format evaluation responses.\n */\nexport function valueTypeStringForConfig(\n config: ConfigResponse\n): ValueType | undefined {\n return config.valueType;\n}\n"],"mappings":"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","names":["import_crypto","ctx","murmurhash","match","import_crypto","ConfigValueType"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/quonfig.ts","../src/store.ts","../src/context.ts","../src/semver.ts","../src/operators.ts","../src/hashing.ts","../src/weighted.ts","../src/evaluator.ts","../src/encryption.ts","../src/duration.ts","../src/resolver.ts","../src/transport.ts","../src/sse.ts","../src/logger.ts","../src/datadir.ts","../src/telemetry/evaluationSummaries.ts","../src/telemetry/contextShapes.ts","../src/telemetry/exampleContexts.ts","../src/telemetry/reporter.ts","../src/types.ts","../src/cli-compat.ts"],"sourcesContent":["// Main SDK exports\nexport { Quonfig, BoundQuonfig } from \"./quonfig\";\n\n// Types\nexport type {\n QuonfigOptions,\n ConfigEnvelope,\n ConfigResponse,\n ConfigTypeString,\n ValueType,\n Value,\n Rule,\n RuleSet,\n Criterion,\n Environment,\n Meta,\n WorkspaceEnvironment,\n WorkspaceConfigDocument,\n QuonfigDatadirEnvironments,\n Contexts,\n ContextValue,\n GetValue,\n OnNoDefault,\n ContextUploadMode,\n LogLevelName,\n LogLevelNumber,\n ProvidedData,\n WeightedValue,\n WeightedValuesData,\n SchemaData,\n EvalMatch,\n Evaluation,\n NodeServerConfigurationRaw,\n NodeServerConfigurationAccessor,\n TypedNodeServerConfigurationRaw,\n TypedNodeServerConfigurationAccessor,\n} from \"./types\";\n\n// Enum-like runtime constants (e.g., ConfigType.FeatureFlag, ProvidedSource.EnvVar)\nexport { ConfigType, ProvidedSource } from \"./types\";\n\n// Context utilities\nexport { contextLookup, mergeContexts, getContextValue } from \"./context\";\n\n// Encryption utilities\nexport { encrypt, decrypt, generateNewHexKey } from \"./encryption\";\n\n// Encryption namespace (for CLI compatibility: `import { encryption } from '@quonfig/node'`)\nimport { encrypt as _encrypt, generateNewHexKey as _generateNewHexKey } from \"./encryption\";\nexport const encryption = {\n encrypt: _encrypt,\n generateNewHexKey: _generateNewHexKey,\n};\n\n// Duration parsing\nexport { durationToMilliseconds } from \"./duration\";\n\n// Semver comparison\nexport { parseSemver, compareSemver } from \"./semver\";\nexport type { SemanticVersion } from \"./semver\";\n\n// Hashing\nexport { hashZeroToOne } from \"./hashing\";\n\n// Logger utilities\nexport { parseLevel, wordLevelToNumber, shouldLog, LOG_LEVEL_PREFIX } from \"./logger\";\n\n// Evaluator (for advanced usage / testing)\nexport { Evaluator } from \"./evaluator\";\nexport { ConfigStore } from \"./store\";\nexport { Resolver } from \"./resolver\";\nexport { Transport } from \"./transport\";\nexport { WeightedValueResolver } from \"./weighted\";\n\n// Operators (for advanced usage / testing)\nexport {\n evaluateCriterion,\n OP_NOT_SET,\n OP_ALWAYS_TRUE,\n OP_PROP_IS_ONE_OF,\n OP_PROP_IS_NOT_ONE_OF,\n OP_PROP_STARTS_WITH_ONE_OF,\n OP_PROP_DOES_NOT_START_WITH_ONE_OF,\n OP_PROP_ENDS_WITH_ONE_OF,\n OP_PROP_DOES_NOT_END_WITH_ONE_OF,\n OP_PROP_CONTAINS_ONE_OF,\n OP_PROP_DOES_NOT_CONTAIN_ONE_OF,\n OP_PROP_MATCHES,\n OP_PROP_DOES_NOT_MATCH,\n OP_HIERARCHICAL_MATCH,\n OP_IN_INT_RANGE,\n OP_PROP_GREATER_THAN,\n OP_PROP_GREATER_THAN_OR_EQUAL,\n OP_PROP_LESS_THAN,\n OP_PROP_LESS_THAN_OR_EQUAL,\n OP_PROP_BEFORE,\n OP_PROP_AFTER,\n OP_PROP_SEMVER_LESS_THAN,\n OP_PROP_SEMVER_EQUAL,\n OP_PROP_SEMVER_GREATER_THAN,\n OP_IN_SEG,\n OP_NOT_IN_SEG,\n} from \"./operators\";\nexport type { SegmentResolver } from \"./operators\";\n\n// Telemetry (for advanced usage / testing)\nexport { EvaluationSummaryCollector } from \"./telemetry/evaluationSummaries\";\nexport { ContextShapeCollector } from \"./telemetry/contextShapes\";\nexport { ExampleContextCollector } from \"./telemetry/exampleContexts\";\nexport { TelemetryReporter } from \"./telemetry/reporter\";\n\n// CLI compatibility (HTTP client, SDK-key parsing, legacy value types)\nexport { Client, getProjectEnvFromSdkKey, ConfigValueType, valueTypeStringForConfig } from \"./cli-compat\";\nexport type { ClientOptions, ProjectEnvId, ConfigValue } from \"./cli-compat\";\n","import { randomUUID } from \"crypto\";\nimport { readFileSync } from \"fs\";\n\nimport type {\n ConfigEnvelope,\n Contexts,\n ContextUploadMode,\n Evaluation,\n GetValue,\n LogLevelName,\n LogLevelNumber,\n OnNoDefault,\n QuonfigOptions,\n Value,\n} from \"./types\";\n\nimport { ConfigStore } from \"./store\";\nimport { Evaluator } from \"./evaluator\";\nimport { Resolver } from \"./resolver\";\nimport { Transport } from \"./transport\";\nimport { SSEConnection } from \"./sse\";\nimport { mergeContexts } from \"./context\";\nimport { parseLevel, shouldLog } from \"./logger\";\nimport { durationToMilliseconds } from \"./duration\";\nimport { loadEnvelopeFromDatadir } from \"./datadir\";\n\nimport { EvaluationSummaryCollector } from \"./telemetry/evaluationSummaries\";\nimport { ContextShapeCollector } from \"./telemetry/contextShapes\";\nimport { ExampleContextCollector } from \"./telemetry/exampleContexts\";\nimport { TelemetryReporter } from \"./telemetry/reporter\";\n\nconst DEFAULT_API_URLS = [\n \"https://primary.quonfig.com\",\n \"https://secondary.quonfig.com\",\n];\nconst DEFAULT_POLL_INTERVAL = 60000;\nconst DEFAULT_INIT_TIMEOUT = 10000;\nconst DEFAULT_LOG_LEVEL: LogLevelNumber = 5; // warn\n\n/**\n * BoundQuonfig is a Quonfig client bound to a specific context.\n * All get* calls automatically include the bound context.\n */\nexport class BoundQuonfig {\n private client: Quonfig;\n private boundContexts: Contexts;\n\n constructor(client: Quonfig, contexts: Contexts) {\n this.client = client;\n this.boundContexts = contexts;\n }\n\n get(key: string, contexts?: Contexts, defaultValue?: any): any {\n return this.client.get(key, mergeContexts(this.boundContexts, contexts), defaultValue);\n }\n\n getString(key: string, contexts?: Contexts): string | undefined {\n return this.client.getString(key, mergeContexts(this.boundContexts, contexts));\n }\n\n getNumber(key: string, contexts?: Contexts): number | undefined {\n return this.client.getNumber(key, mergeContexts(this.boundContexts, contexts));\n }\n\n getBool(key: string, contexts?: Contexts): boolean | undefined {\n return this.client.getBool(key, mergeContexts(this.boundContexts, contexts));\n }\n\n getStringList(key: string, contexts?: Contexts): string[] | undefined {\n return this.client.getStringList(key, mergeContexts(this.boundContexts, contexts));\n }\n\n getDuration(key: string, contexts?: Contexts): number | undefined {\n return this.client.getDuration(key, mergeContexts(this.boundContexts, contexts));\n }\n\n getJSON(key: string, contexts?: Contexts): any {\n return this.client.getJSON(key, mergeContexts(this.boundContexts, contexts));\n }\n\n isFeatureEnabled(key: string, contexts?: Contexts): boolean {\n return this.client.isFeatureEnabled(key, mergeContexts(this.boundContexts, contexts));\n }\n\n shouldLog(args: {\n loggerName: string;\n desiredLevel: string;\n defaultLevel?: string;\n contexts?: Contexts;\n }): boolean {\n return this.client.shouldLog({\n ...args,\n contexts: mergeContexts(this.boundContexts, args.contexts),\n });\n }\n\n keys(): string[] {\n return this.client.keys();\n }\n\n inContext(contexts: Contexts): BoundQuonfig {\n return new BoundQuonfig(this.client, mergeContexts(this.boundContexts, contexts));\n }\n}\n\n/**\n * Quonfig is the main SDK client.\n *\n * Usage:\n * ```typescript\n * const quonfig = new Quonfig({ sdkKey: \"your-key\" });\n * await quonfig.init();\n * const value = quonfig.get(\"my-config\");\n * ```\n */\nexport class Quonfig {\n private readonly sdkKey: string;\n private readonly apiUrls: string[];\n private readonly telemetryUrl?: string;\n private readonly enableSSE: boolean;\n private readonly enablePolling: boolean;\n private readonly pollInterval: number;\n private readonly namespace?: string;\n private readonly onNoDefault: OnNoDefault;\n private readonly globalContext?: Contexts;\n private readonly initTimeout: number;\n private readonly datadir?: string;\n private readonly datafile?: string | object;\n\n private store: ConfigStore;\n private evaluator: Evaluator;\n private resolver: Resolver;\n private transport: Transport;\n private sseConnection?: SSEConnection;\n private pollTimer?: ReturnType<typeof setTimeout>;\n private telemetryReporter?: TelemetryReporter;\n private instanceHash: string;\n private environmentId: string = \"\";\n private initialized: boolean = false;\n\n // Telemetry collectors\n private evaluationSummaries: EvaluationSummaryCollector;\n private contextShapes: ContextShapeCollector;\n private exampleContexts: ExampleContextCollector;\n\n constructor(options: QuonfigOptions) {\n this.sdkKey = options.sdkKey;\n this.apiUrls = options.apiUrls ?? (options.apiUrl ? [options.apiUrl] : DEFAULT_API_URLS);\n if (this.apiUrls.length === 0) {\n throw new Error(\"[quonfig] apiUrls must not be empty\");\n }\n this.telemetryUrl = options.telemetryUrl;\n this.enableSSE = options.enableSSE ?? true;\n this.enablePolling = options.enablePolling ?? false;\n this.pollInterval = options.pollInterval ?? DEFAULT_POLL_INTERVAL;\n this.namespace = options.namespace;\n this.onNoDefault = options.onNoDefault ?? \"error\";\n this.globalContext = options.globalContext;\n this.initTimeout = options.initTimeout ?? DEFAULT_INIT_TIMEOUT;\n this.datadir = options.datadir;\n this.datafile = options.datafile;\n this.instanceHash = randomUUID();\n\n // Initialize core components\n this.store = new ConfigStore();\n this.evaluator = new Evaluator(this.store);\n this.resolver = new Resolver(this.store, this.evaluator);\n this.transport = new Transport(this.apiUrls, this.sdkKey, this.telemetryUrl);\n\n // Initialize telemetry collectors\n const contextUploadMode: ContextUploadMode = options.contextUploadMode ?? \"periodic_example\";\n this.evaluationSummaries = new EvaluationSummaryCollector(\n options.collectEvaluationSummaries ?? true\n );\n this.contextShapes = new ContextShapeCollector(contextUploadMode);\n this.exampleContexts = new ExampleContextCollector(contextUploadMode);\n }\n\n /**\n * Initialize the SDK. Downloads configs from the API (or loads from datadir/datafile)\n * and starts background update mechanisms (SSE/polling).\n *\n * Must be called before using any get* methods.\n */\n async init(): Promise<void> {\n if (this.datadir || this.datafile) {\n this.loadLocalData();\n this.initialized = true;\n return;\n }\n\n // Fetch configs with a timeout\n const fetchPromise = this.fetchAndInstall();\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(\"Initialization timed out\")), this.initTimeout);\n });\n\n try {\n await Promise.race([fetchPromise, timeoutPromise]);\n } catch (err) {\n console.warn(\"[quonfig] Initialization failed:\", err);\n throw err;\n }\n\n this.initialized = true;\n\n // Start SSE for real-time updates\n if (this.enableSSE) {\n this.startSSE();\n }\n\n // Start polling if enabled\n if (this.enablePolling) {\n this.startPolling();\n }\n\n // Start telemetry reporter\n this.startTelemetry();\n }\n\n /**\n * Get a config value by key. Evaluates rules against the provided context.\n */\n get(key: string, contexts?: Contexts, defaultValue?: any): any {\n this.requireInitialized();\n\n const mergedContexts = mergeContexts(this.globalContext, contexts);\n const config = this.store.get(key);\n\n if (config === undefined) {\n return this.handleNoDefault(key, defaultValue);\n }\n\n // Record context for telemetry\n this.contextShapes.push(mergedContexts);\n this.exampleContexts.push(mergedContexts);\n\n // Evaluate\n const match = this.evaluator.evaluateConfig(\n config,\n this.environmentId,\n mergedContexts\n );\n\n if (!match.isMatch || match.value === undefined) {\n return this.handleNoDefault(key, defaultValue);\n }\n\n // Resolve (ENV_VAR, decryption)\n const { resolved, reportableValue } = this.resolver.resolveValue(\n match.value,\n config.key,\n config.valueType,\n this.environmentId,\n mergedContexts\n );\n\n // Unwrap to plain value\n const unwrapped = this.resolver.unwrapValue(resolved);\n\n // Record evaluation for telemetry\n const evaluation: Evaluation = {\n configId: config.id,\n configKey: config.key,\n configType: config.type,\n unwrappedValue: unwrapped as GetValue,\n reportableValue: reportableValue,\n ruleIndex: match.ruleIndex,\n weightedValueIndex: match.weightedValueIndex >= 0 ? match.weightedValueIndex : undefined,\n };\n this.evaluationSummaries.push(evaluation);\n\n return unwrapped;\n }\n\n /**\n * Get a string config value.\n */\n getString(key: string, contexts?: Contexts): string | undefined {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n return String(value);\n }\n\n /**\n * Get a number config value.\n */\n getNumber(key: string, contexts?: Contexts): number | undefined {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n return typeof value === \"number\" ? value : Number(value);\n }\n\n /**\n * Get a boolean config value.\n */\n getBool(key: string, contexts?: Contexts): boolean | undefined {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n return !!value;\n }\n\n /**\n * Get a string list config value.\n */\n getStringList(key: string, contexts?: Contexts): string[] | undefined {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n if (Array.isArray(value)) return value.map((v: any) => String(v));\n return undefined;\n }\n\n /**\n * Get a duration config value in milliseconds.\n */\n getDuration(key: string, contexts?: Contexts): number | undefined {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n // If the evaluator already unwrapped it to ms (duration type), return as-is\n if (typeof value === \"number\") return value;\n // If it's a string, parse it\n if (typeof value === \"string\") return durationToMilliseconds(value);\n return undefined;\n }\n\n /**\n * Get a JSON config value (parsed).\n */\n getJSON(key: string, contexts?: Contexts): any {\n const value = this.get(key, contexts, undefined);\n if (value === undefined) return undefined;\n // If already parsed (from unwrap), return as-is\n return value;\n }\n\n /**\n * Check if a feature flag is enabled.\n * Returns false if the key is not found or the value is not a boolean.\n */\n isFeatureEnabled(key: string, contexts?: Contexts): boolean {\n const value = this.get(key, contexts, undefined);\n if (typeof value === \"boolean\") return value;\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n return false;\n }\n\n /**\n * Check if a log message should be logged at the given level.\n */\n shouldLog(args: {\n loggerName: string;\n desiredLevel: string;\n defaultLevel?: string;\n contexts?: Contexts;\n }): boolean {\n const desiredLevelNum = parseLevel(args.desiredLevel);\n if (desiredLevelNum === undefined) {\n console.warn(`[quonfig] Invalid desiredLevel \"${args.desiredLevel}\". Returning true.`);\n return true;\n }\n\n const defaultLevelNum = parseLevel(args.defaultLevel) ?? DEFAULT_LOG_LEVEL;\n\n return shouldLog({\n loggerName: args.loggerName,\n desiredLevel: desiredLevelNum,\n defaultLevel: defaultLevelNum,\n getConfig: (logKey: string) => {\n try {\n return this.get(logKey, args.contexts, undefined);\n } catch {\n return undefined;\n }\n },\n });\n }\n\n /**\n * Get all config keys currently in the store.\n */\n keys(): string[] {\n this.requireInitialized();\n return this.store.keys();\n }\n\n /**\n * Get the raw ConfigResponse for a key (for advanced usage / CLI tooling).\n */\n rawConfig(key: string): import(\"./types\").ConfigResponse | undefined {\n this.requireInitialized();\n return this.store.get(key);\n }\n\n /**\n * Create a BoundQuonfig with the given context baked in.\n */\n inContext(contexts: Contexts): BoundQuonfig {\n return new BoundQuonfig(this, mergeContexts(this.globalContext, contexts));\n }\n\n /**\n * Close the SDK. Stops SSE, polling, and telemetry.\n */\n close(): void {\n if (this.sseConnection) {\n this.sseConnection.close();\n this.sseConnection = undefined;\n }\n\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = undefined;\n }\n\n if (this.telemetryReporter) {\n this.telemetryReporter.stop();\n this.telemetryReporter = undefined;\n }\n }\n\n // ---- Private methods ----\n\n private requireInitialized(): void {\n if (!this.initialized) {\n throw new Error(\"[quonfig] Not initialized. Call init() first.\");\n }\n }\n\n private handleNoDefault(key: string, defaultValue?: any): any {\n if (defaultValue !== undefined) {\n return defaultValue;\n }\n\n switch (this.onNoDefault) {\n case \"error\":\n throw new Error(`No value found for key \"${key}\"`);\n case \"warn\":\n console.warn(`[quonfig] No value found for key \"${key}\"`);\n return undefined;\n case \"ignore\":\n return undefined;\n }\n }\n\n private loadLocalData(): void {\n const data = this.loadLocalEnvelope();\n\n this.store.update(data);\n this.environmentId = data.meta.environment;\n }\n\n private loadLocalEnvelope(): ConfigEnvelope {\n if (this.datadir) {\n return loadEnvelopeFromDatadir(this.datadir);\n }\n\n if (typeof this.datafile === \"string\") {\n const raw = readFileSync(this.datafile, \"utf-8\");\n return JSON.parse(raw);\n }\n\n if (typeof this.datafile === \"object\") {\n return this.datafile as ConfigEnvelope;\n }\n\n throw new Error(\"Invalid local configuration: expected datadir or datafile\");\n }\n\n private async fetchAndInstall(): Promise<void> {\n const result = await this.transport.fetchConfigs();\n\n if (result.notChanged) {\n return;\n }\n\n if (result.envelope) {\n this.store.update(result.envelope);\n this.environmentId = result.envelope.meta.environment;\n }\n }\n\n private startSSE(): void {\n this.sseConnection = new SSEConnection(this.transport);\n this.sseConnection.start((envelope: ConfigEnvelope) => {\n this.store.update(envelope);\n this.environmentId = envelope.meta.environment;\n });\n }\n\n private startPolling(): void {\n const poll = (): void => {\n this.fetchAndInstall()\n .catch((err) => {\n console.warn(\"[quonfig] Polling error:\", err);\n })\n .finally(() => {\n this.pollTimer = setTimeout(poll, this.pollInterval);\n if (this.pollTimer && typeof this.pollTimer === \"object\" && \"unref\" in this.pollTimer) {\n this.pollTimer.unref();\n }\n });\n };\n\n this.pollTimer = setTimeout(poll, this.pollInterval);\n if (this.pollTimer && typeof this.pollTimer === \"object\" && \"unref\" in this.pollTimer) {\n this.pollTimer.unref();\n }\n }\n\n private startTelemetry(): void {\n const anyEnabled =\n this.evaluationSummaries.isEnabled() ||\n this.contextShapes.isEnabled() ||\n this.exampleContexts.isEnabled();\n\n if (!anyEnabled) return;\n\n this.telemetryReporter = new TelemetryReporter({\n transport: this.transport,\n instanceHash: this.instanceHash,\n evaluationSummaries: this.evaluationSummaries,\n contextShapes: this.contextShapes,\n exampleContexts: this.exampleContexts,\n });\n\n this.telemetryReporter.start();\n }\n}\n","import type { ConfigEnvelope, ConfigResponse, Value, WeightedValuesData, ProvidedData } from \"./types\";\n\n/**\n * In-memory config store.\n *\n * Stores parsed ConfigResponse objects keyed by config key.\n * The store replaces all configs atomically on each update.\n */\nexport class ConfigStore {\n private configs: Map<string, ConfigResponse> = new Map();\n private version: string = \"\";\n private environmentId: string = \"\";\n\n get(key: string): ConfigResponse | undefined {\n return this.configs.get(key);\n }\n\n keys(): string[] {\n return Array.from(this.configs.keys());\n }\n\n getEnvironmentId(): string {\n return this.environmentId;\n }\n\n getVersion(): string {\n return this.version;\n }\n\n /**\n * Replace all configs with those from the given envelope.\n * Also normalizes values that need special deserialization (weighted_values, provided).\n */\n update(envelope: ConfigEnvelope): void {\n const next = new Map<string, ConfigResponse>();\n\n for (const cfg of envelope.configs) {\n // Normalize the config's values to ensure proper typing\n normalizeConfigResponse(cfg);\n next.set(cfg.key, cfg);\n }\n\n this.configs = next;\n this.version = envelope.meta.version;\n this.environmentId = envelope.meta.environment;\n }\n\n /**\n * Load from a raw datafile (JSON object).\n */\n loadFromDatafile(data: ConfigEnvelope): void {\n this.update(data);\n }\n}\n\n/**\n * Normalize a ConfigResponse to ensure all Value objects have proper typing.\n * JSON deserialization may leave weighted_values and provided values as plain objects.\n */\nfunction normalizeConfigResponse(cfg: ConfigResponse): void {\n // The API may return null instead of an empty array for rules\n if (!cfg.default.rules) {\n cfg.default.rules = [];\n }\n for (const rule of cfg.default.rules) {\n normalizeValue(rule.value);\n for (const criterion of rule.criteria ?? []) {\n if (criterion.valueToMatch) {\n normalizeValue(criterion.valueToMatch);\n }\n }\n }\n\n if (cfg.environment) {\n if (!cfg.environment.rules) {\n cfg.environment.rules = [];\n }\n for (const rule of cfg.environment.rules) {\n normalizeValue(rule.value);\n for (const criterion of rule.criteria ?? []) {\n if (criterion.valueToMatch) {\n normalizeValue(criterion.valueToMatch);\n }\n }\n }\n }\n}\n\n/**\n * Normalize a Value - if it's type \"weighted_values\", ensure the value\n * is in the expected WeightedValuesData shape. Similarly for \"provided\".\n */\nfunction normalizeValue(v: Value): void {\n if (v.type === \"weighted_values\" && v.value && typeof v.value === \"object\") {\n // Ensure it looks like WeightedValuesData\n const wvd = v.value as WeightedValuesData;\n if (wvd.weightedValues) {\n for (const wv of wvd.weightedValues) {\n if (wv.value) {\n normalizeValue(wv.value);\n }\n }\n }\n }\n if (v.type === \"provided\" && v.value && typeof v.value === \"object\") {\n // Ensure it's ProvidedData shape\n const pd = v.value as ProvidedData;\n if (!pd.source) {\n pd.source = \"ENV_VAR\";\n }\n }\n}\n","import type { ContextValue, Contexts } from \"./types\";\n\n/**\n * Look up a property value from contexts using dotted notation.\n * \"user.email\" -> contexts[\"user\"][\"email\"]\n * If there is no dot, look up in the unnamed (\"\") context: \"domain\" -> contexts[\"\"][\"domain\"]\n */\nexport function contextLookup(\n contexts: Contexts,\n propertyName: string | undefined\n): ContextValue | undefined {\n if (propertyName === undefined) {\n return undefined;\n }\n\n const dotIndex = propertyName.indexOf(\".\");\n if (dotIndex === -1) {\n // No dot -- look up in the unnamed (\"\") context\n const ctx = contexts[\"\"];\n if (ctx === undefined) {\n return undefined;\n }\n return ctx[propertyName];\n }\n\n const contextName = propertyName.slice(0, dotIndex);\n const key = propertyName.slice(dotIndex + 1);\n\n const ctx = contexts[contextName];\n if (ctx === undefined) {\n return undefined;\n }\n\n return ctx[key];\n}\n\n/**\n * Merge multiple context sets. Later sets override earlier ones at the key level\n * within each named context.\n */\nexport function mergeContexts(...sets: (Contexts | undefined)[]): Contexts {\n const result: Contexts = {};\n\n for (const cs of sets) {\n if (cs === undefined) {\n continue;\n }\n\n for (const [name, ctx] of Object.entries(cs)) {\n if (result[name] === undefined) {\n result[name] = { ...ctx };\n } else {\n result[name] = { ...result[name], ...ctx };\n }\n }\n }\n\n return result;\n}\n\n/**\n * Get context value with support for magic properties.\n * \"prefab.current-time\" and \"quonfig.current-time\" return current UTC millis.\n */\nexport function getContextValue(\n contexts: Contexts,\n propertyName: string\n): { value: any; exists: boolean } {\n // Handle magic current-time properties\n if (\n propertyName === \"prefab.current-time\" ||\n propertyName === \"quonfig.current-time\" ||\n propertyName === \"reforge.current-time\"\n ) {\n return { value: Date.now(), exists: true };\n }\n\n const value = contextLookup(contexts, propertyName);\n return { value, exists: value !== undefined && value !== null };\n}\n","const SEMVER_PATTERN =\n /^(?<major>0|[1-9]\\d*)\\.(?<minor>0|[1-9]\\d*)\\.(?<patch>0|[1-9]\\d*)(?:-(?<prerelease>(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\n\nexport interface SemanticVersion {\n major: number;\n minor: number;\n patch: number;\n prerelease: string;\n buildMetadata: string;\n}\n\n/**\n * Parse a semantic version string. Returns undefined if invalid.\n */\nexport function parseSemver(version: string): SemanticVersion | undefined {\n if (!version) {\n return undefined;\n }\n\n const match = SEMVER_PATTERN.exec(version);\n if (!match || !match.groups) {\n return undefined;\n }\n\n const major = parseInt(match.groups[\"major\"]!, 10);\n const minor = parseInt(match.groups[\"minor\"]!, 10);\n const patch = parseInt(match.groups[\"patch\"]!, 10);\n\n if (isNaN(major) || isNaN(minor) || isNaN(patch)) {\n return undefined;\n }\n\n return {\n major,\n minor,\n patch,\n prerelease: match.groups[\"prerelease\"] ?? \"\",\n buildMetadata: match.groups[\"buildmetadata\"] ?? \"\",\n };\n}\n\nfunction isNumeric(s: string): boolean {\n return /^\\d+$/.test(s);\n}\n\nfunction comparePreReleaseIdentifiers(id1: string, id2: string): number {\n if (isNumeric(id1) && isNumeric(id2)) {\n const num1 = parseInt(id1, 10);\n const num2 = parseInt(id2, 10);\n if (num1 < num2) return -1;\n if (num1 > num2) return 1;\n return 0;\n }\n\n if (isNumeric(id1)) return -1;\n if (isNumeric(id2)) return 1;\n\n if (id1 < id2) return -1;\n if (id1 > id2) return 1;\n return 0;\n}\n\nfunction comparePreRelease(pre1: string, pre2: string): number {\n if (pre1 === \"\" && pre2 === \"\") return 0;\n // A version without prerelease has higher precedence\n if (pre1 === \"\") return 1;\n if (pre2 === \"\") return -1;\n\n const ids1 = pre1.split(\".\");\n const ids2 = pre2.split(\".\");\n const minLen = Math.min(ids1.length, ids2.length);\n\n for (let i = 0; i < minLen; i++) {\n const cmp = comparePreReleaseIdentifiers(ids1[i]!, ids2[i]!);\n if (cmp !== 0) return cmp;\n }\n\n if (ids1.length < ids2.length) return -1;\n if (ids1.length > ids2.length) return 1;\n return 0;\n}\n\n/**\n * Compare two semantic versions.\n * Returns -1 if a < b, 0 if a == b, 1 if a > b.\n */\nexport function compareSemver(a: SemanticVersion, b: SemanticVersion): number {\n if (a.major !== b.major) return a.major > b.major ? 1 : -1;\n if (a.minor !== b.minor) return a.minor > b.minor ? 1 : -1;\n if (a.patch !== b.patch) return a.patch > b.patch ? 1 : -1;\n return comparePreRelease(a.prerelease, b.prerelease);\n}\n","import type { Criterion, Value } from \"./types\";\nimport { parseSemver, compareSemver } from \"./semver\";\n\n// ---- Operator Constants ----\n\nexport const OP_NOT_SET = \"NOT_SET\";\nexport const OP_ALWAYS_TRUE = \"ALWAYS_TRUE\";\nexport const OP_PROP_IS_ONE_OF = \"PROP_IS_ONE_OF\";\nexport const OP_PROP_IS_NOT_ONE_OF = \"PROP_IS_NOT_ONE_OF\";\nexport const OP_PROP_STARTS_WITH_ONE_OF = \"PROP_STARTS_WITH_ONE_OF\";\nexport const OP_PROP_DOES_NOT_START_WITH_ONE_OF = \"PROP_DOES_NOT_START_WITH_ONE_OF\";\nexport const OP_PROP_ENDS_WITH_ONE_OF = \"PROP_ENDS_WITH_ONE_OF\";\nexport const OP_PROP_DOES_NOT_END_WITH_ONE_OF = \"PROP_DOES_NOT_END_WITH_ONE_OF\";\nexport const OP_PROP_CONTAINS_ONE_OF = \"PROP_CONTAINS_ONE_OF\";\nexport const OP_PROP_DOES_NOT_CONTAIN_ONE_OF = \"PROP_DOES_NOT_CONTAIN_ONE_OF\";\nexport const OP_PROP_MATCHES = \"PROP_MATCHES\";\nexport const OP_PROP_DOES_NOT_MATCH = \"PROP_DOES_NOT_MATCH\";\nexport const OP_HIERARCHICAL_MATCH = \"HIERARCHICAL_MATCH\";\nexport const OP_IN_INT_RANGE = \"IN_INT_RANGE\";\nexport const OP_PROP_GREATER_THAN = \"PROP_GREATER_THAN\";\nexport const OP_PROP_GREATER_THAN_OR_EQUAL = \"PROP_GREATER_THAN_OR_EQUAL\";\nexport const OP_PROP_LESS_THAN = \"PROP_LESS_THAN\";\nexport const OP_PROP_LESS_THAN_OR_EQUAL = \"PROP_LESS_THAN_OR_EQUAL\";\nexport const OP_PROP_BEFORE = \"PROP_BEFORE\";\nexport const OP_PROP_AFTER = \"PROP_AFTER\";\nexport const OP_PROP_SEMVER_LESS_THAN = \"PROP_SEMVER_LESS_THAN\";\nexport const OP_PROP_SEMVER_EQUAL = \"PROP_SEMVER_EQUAL\";\nexport const OP_PROP_SEMVER_GREATER_THAN = \"PROP_SEMVER_GREATER_THAN\";\nexport const OP_IN_SEG = \"IN_SEG\";\nexport const OP_NOT_IN_SEG = \"NOT_IN_SEG\";\n\n// ---- Segment resolver type ----\n\nexport type SegmentResolver = (segmentKey: string) => { result: boolean; found: boolean };\n\n// ---- Helper functions ----\n\nfunction toString(v: any): string {\n if (v === null || v === undefined) return \"\";\n return String(v);\n}\n\nfunction toStringSlice(v: any): string[] {\n if (v === null || v === undefined) return [];\n if (Array.isArray(v)) {\n return v.map((item) => toString(item));\n }\n return [toString(v)];\n}\n\nfunction getStringList(v: Value | undefined): string[] | undefined {\n if (v === undefined || v === null) return undefined;\n if (Array.isArray(v.value)) {\n return v.value.map((item: any) => toString(item));\n }\n return undefined;\n}\n\nfunction isString(v: any): v is string {\n return typeof v === \"string\";\n}\n\nfunction isNumber(v: any): boolean {\n return typeof v === \"number\";\n}\n\nfunction isNumericValue(v: any): boolean {\n if (typeof v === \"number\") return true;\n if (typeof v === \"string\") return !isNaN(Number(v)) && v.trim() !== \"\";\n return false;\n}\n\nfunction toFloat64(v: any): number | undefined {\n if (typeof v === \"number\") return v;\n if (typeof v === \"string\") {\n const n = Number(v);\n if (!isNaN(n)) return n;\n }\n return undefined;\n}\n\nfunction compareNumbers(a: any, b: any): number | undefined {\n const af = toFloat64(a);\n const bf = toFloat64(b);\n if (af === undefined || bf === undefined) return undefined;\n if (af < bf) return -1;\n if (af > bf) return 1;\n return 0;\n}\n\nfunction dateToMillis(val: any): number | undefined {\n if (typeof val === \"number\") return val;\n if (typeof val === \"string\") {\n // Try RFC3339 / ISO 8601\n const d = Date.parse(val);\n if (!isNaN(d)) return d;\n // Try as a plain number string\n const n = parseInt(val, 10);\n if (!isNaN(n)) return n;\n }\n return undefined;\n}\n\nfunction stringInSlice(s: string, list: string[]): boolean {\n return list.includes(s);\n}\n\nfunction startsWithAny(prefixes: string[], target: string): boolean {\n return prefixes.some((p) => target.startsWith(p));\n}\n\nfunction endsWithAny(suffixes: string[], target: string): boolean {\n return suffixes.some((s) => target.endsWith(s));\n}\n\nfunction containsAny(substrings: string[], target: string): boolean {\n return substrings.some((s) => target.includes(s));\n}\n\nfunction extractIntRange(v: Value | undefined): { start: number; end: number } {\n let start = Number.MIN_SAFE_INTEGER;\n let end = Number.MAX_SAFE_INTEGER;\n\n if (v === undefined || v === null) return { start, end };\n\n // The value should be a map with \"start\" and \"end\" from JSON\n if (typeof v.value === \"object\" && v.value !== null && !Array.isArray(v.value)) {\n if (\"start\" in v.value) {\n const s = toFloat64(v.value.start);\n if (s !== undefined) start = s;\n }\n if (\"end\" in v.value) {\n const e = toFloat64(v.value.end);\n if (e !== undefined) end = e;\n }\n }\n\n return { start, end };\n}\n\n// ---- Main evaluation function ----\n\n/**\n * Evaluate a single criterion against a context value.\n *\n * This is a faithful port of the Go SDK's EvaluateCriterion function.\n */\nexport function evaluateCriterion(\n contextValue: any,\n contextExists: boolean,\n criterion: Criterion,\n segmentResolver?: SegmentResolver\n): boolean {\n const matchValue = criterion.valueToMatch;\n\n switch (criterion.operator) {\n case OP_NOT_SET:\n return false;\n\n case OP_ALWAYS_TRUE:\n return true;\n\n case OP_PROP_IS_ONE_OF:\n case OP_PROP_IS_NOT_ONE_OF: {\n if (contextExists && matchValue !== undefined) {\n const matchStrings = getStringList(matchValue);\n if (matchStrings !== undefined) {\n const contextStrings = toStringSlice(contextValue);\n let matchFound = false;\n for (const cv of contextStrings) {\n if (stringInSlice(cv, matchStrings)) {\n matchFound = true;\n break;\n }\n }\n return matchFound === (criterion.operator === OP_PROP_IS_ONE_OF);\n }\n }\n return criterion.operator === OP_PROP_IS_NOT_ONE_OF;\n }\n\n case OP_PROP_STARTS_WITH_ONE_OF:\n case OP_PROP_DOES_NOT_START_WITH_ONE_OF: {\n if (contextExists && matchValue !== undefined) {\n const matchStrings = getStringList(matchValue);\n if (matchStrings !== undefined) {\n const cv = toString(contextValue);\n const matchFound = startsWithAny(matchStrings, cv);\n return matchFound === (criterion.operator === OP_PROP_STARTS_WITH_ONE_OF);\n }\n }\n return criterion.operator === OP_PROP_DOES_NOT_START_WITH_ONE_OF;\n }\n\n case OP_PROP_ENDS_WITH_ONE_OF:\n case OP_PROP_DOES_NOT_END_WITH_ONE_OF: {\n if (contextExists && matchValue !== undefined) {\n const matchStrings = getStringList(matchValue);\n if (matchStrings !== undefined) {\n const cv = toString(contextValue);\n const matchFound = endsWithAny(matchStrings, cv);\n return matchFound === (criterion.operator === OP_PROP_ENDS_WITH_ONE_OF);\n }\n }\n return criterion.operator === OP_PROP_DOES_NOT_END_WITH_ONE_OF;\n }\n\n case OP_PROP_CONTAINS_ONE_OF:\n case OP_PROP_DOES_NOT_CONTAIN_ONE_OF: {\n if (contextExists && matchValue !== undefined) {\n const matchStrings = getStringList(matchValue);\n if (matchStrings !== undefined) {\n const cv = toString(contextValue);\n const matchFound = containsAny(matchStrings, cv);\n return matchFound === (criterion.operator === OP_PROP_CONTAINS_ONE_OF);\n }\n }\n return criterion.operator === OP_PROP_DOES_NOT_CONTAIN_ONE_OF;\n }\n\n case OP_PROP_MATCHES:\n case OP_PROP_DOES_NOT_MATCH: {\n if (contextExists && matchValue !== undefined && isString(contextValue) && isString(matchValue.value)) {\n try {\n const re = new RegExp(matchValue.value);\n const matched = re.test(contextValue);\n return matched === (criterion.operator === OP_PROP_MATCHES);\n } catch {\n // Invalid regex\n }\n }\n return false;\n }\n\n case OP_HIERARCHICAL_MATCH: {\n if (contextExists && matchValue !== undefined) {\n const cv = toString(contextValue);\n const mv = toString(matchValue.value);\n return cv.startsWith(mv);\n }\n return false;\n }\n\n case OP_IN_INT_RANGE: {\n if (contextExists && matchValue !== undefined) {\n const { start, end } = extractIntRange(matchValue);\n const numVal = toFloat64(contextValue);\n if (numVal !== undefined) {\n return numVal >= start && numVal < end;\n }\n }\n return false;\n }\n\n case OP_PROP_GREATER_THAN:\n case OP_PROP_GREATER_THAN_OR_EQUAL:\n case OP_PROP_LESS_THAN:\n case OP_PROP_LESS_THAN_OR_EQUAL: {\n if (contextExists && matchValue !== undefined && isNumber(contextValue) && isNumericValue(matchValue.value)) {\n const cmp = compareNumbers(contextValue, matchValue.value);\n if (cmp !== undefined) {\n switch (criterion.operator) {\n case OP_PROP_GREATER_THAN:\n return cmp > 0;\n case OP_PROP_GREATER_THAN_OR_EQUAL:\n return cmp >= 0;\n case OP_PROP_LESS_THAN:\n return cmp < 0;\n case OP_PROP_LESS_THAN_OR_EQUAL:\n return cmp <= 0;\n }\n }\n }\n return false;\n }\n\n case OP_PROP_BEFORE:\n case OP_PROP_AFTER: {\n if (contextExists && matchValue !== undefined) {\n const contextMillis = dateToMillis(contextValue);\n const matchMillis = dateToMillis(matchValue.value);\n if (contextMillis !== undefined && matchMillis !== undefined) {\n if (criterion.operator === OP_PROP_BEFORE) {\n return contextMillis < matchMillis;\n }\n return contextMillis > matchMillis;\n }\n }\n return false;\n }\n\n case OP_PROP_SEMVER_LESS_THAN:\n case OP_PROP_SEMVER_EQUAL:\n case OP_PROP_SEMVER_GREATER_THAN: {\n if (contextExists && matchValue !== undefined && isString(contextValue) && isString(matchValue.value)) {\n const svContext = parseSemver(contextValue);\n const svMatch = parseSemver(matchValue.value);\n if (svContext !== undefined && svMatch !== undefined) {\n const cmp = compareSemver(svContext, svMatch);\n switch (criterion.operator) {\n case OP_PROP_SEMVER_LESS_THAN:\n return cmp < 0;\n case OP_PROP_SEMVER_EQUAL:\n return cmp === 0;\n case OP_PROP_SEMVER_GREATER_THAN:\n return cmp > 0;\n }\n }\n }\n return false;\n }\n\n case OP_IN_SEG:\n case OP_NOT_IN_SEG: {\n if (matchValue !== undefined && segmentResolver !== undefined) {\n const segmentKey = toString(matchValue.value);\n const { result, found } = segmentResolver(segmentKey);\n if (!found) {\n return criterion.operator === OP_NOT_IN_SEG;\n }\n return result === (criterion.operator === OP_IN_SEG);\n }\n return criterion.operator === OP_NOT_IN_SEG;\n }\n\n default:\n return false;\n }\n}\n","import murmurhash from \"murmurhash\";\n\n/**\n * Hash a string to a float64 in [0, 1) using Murmur3.\n * This matches the Go SDK's HashZeroToOne implementation.\n */\nexport function hashZeroToOne(value: string): number {\n const hash = murmurhash.v3(value);\n // MaxUint32 = 4294967295\n return hash / 4294967295;\n}\n","import type { Contexts, Value, WeightedValuesData } from \"./types\";\nimport { hashZeroToOne } from \"./hashing\";\nimport { contextLookup } from \"./context\";\n\n/**\n * WeightedValueResolver resolves weighted value distributions to a single value.\n *\n * This is a faithful port of the Go SDK's WeightedValueResolver.\n */\nexport class WeightedValueResolver {\n /**\n * Resolve picks a value from the weighted distribution.\n *\n * If hashByPropertyName is set and the context has a value for that property,\n * the selection is deterministic via Murmur3 hash. Otherwise, it falls back\n * to Math.random().\n *\n * Returns the selected value and its index, or [undefined, -1] if no values.\n */\n resolve(\n wv: WeightedValuesData,\n configKey: string,\n contexts: Contexts\n ): { value: Value | undefined; index: number } {\n const fraction = this.getUserFraction(wv, configKey, contexts);\n\n let totalWeight = 0;\n for (const entry of wv.weightedValues) {\n totalWeight += entry.weight;\n }\n\n const threshold = fraction * totalWeight;\n\n let runningSum = 0;\n for (let i = 0; i < wv.weightedValues.length; i++) {\n runningSum += wv.weightedValues[i]!.weight;\n if (runningSum >= threshold) {\n return { value: { ...wv.weightedValues[i]!.value }, index: i };\n }\n }\n\n // Fallback: return the first value (should not normally be reached)\n if (wv.weightedValues.length > 0) {\n return { value: { ...wv.weightedValues[0]!.value }, index: 0 };\n }\n return { value: undefined, index: -1 };\n }\n\n private getUserFraction(\n wv: WeightedValuesData,\n configKey: string,\n contexts: Contexts\n ): number {\n if (wv.hashByPropertyName) {\n const value = contextLookup(contexts, wv.hashByPropertyName);\n if (value !== undefined && value !== null) {\n const valueToHash = `${configKey}${value}`;\n return hashZeroToOne(valueToHash);\n }\n }\n return Math.random();\n }\n}\n","import type {\n ConfigResponse,\n Contexts,\n Criterion,\n EvalMatch,\n Rule,\n Value,\n} from \"./types\";\nimport { getContextValue } from \"./context\";\nimport { evaluateCriterion } from \"./operators\";\nimport type { SegmentResolver } from \"./operators\";\nimport { WeightedValueResolver } from \"./weighted\";\nimport type { ConfigStore } from \"./store\";\n\n/**\n * Evaluator is the main evaluation engine. It evaluates configs against contexts,\n * resolving rules, operators, segments, and weighted values.\n *\n * This is a faithful port of the Go SDK's evalcore.Evaluator.\n */\nexport class Evaluator {\n private configStore: ConfigStore;\n private weighted: WeightedValueResolver;\n\n constructor(configStore: ConfigStore) {\n this.configStore = configStore;\n this.weighted = new WeightedValueResolver();\n }\n\n /**\n * Evaluate a config for the given environment and context.\n *\n * Evaluation flow:\n * 1. Find the environment block matching envID (if any)\n * 2. Iterate its rules top-to-bottom; first match wins\n * 3. If no env-specific match, fall back to default.rules\n * 4. For each rule, all criteria must match (AND logic)\n * 5. If matched value is weighted_values, resolve through WeightedValueResolver\n */\n evaluateConfig(\n cfg: ConfigResponse,\n envID: string,\n contexts: Contexts\n ): EvalMatch {\n // Try environment-specific rules first\n if (envID && cfg.environment && cfg.environment.id === envID) {\n const match = this.evaluateRules(cfg, cfg.environment.rules ?? [], contexts, 0);\n if (match !== undefined) {\n return match;\n }\n }\n\n // Fall back to default rules\n const match = this.evaluateRules(cfg, cfg.default.rules ?? [], contexts, 0);\n if (match !== undefined) {\n return match;\n }\n\n return { isMatch: false, ruleIndex: -1, weightedValueIndex: -1 };\n }\n\n private evaluateRules(\n cfg: ConfigResponse,\n rules: Rule[],\n contexts: Contexts,\n ruleIndexOffset: number\n ): EvalMatch | undefined {\n for (let i = 0; i < rules.length; i++) {\n const rule = rules[i]!;\n if (this.evaluateAllCriteria(cfg, rule.criteria, contexts)) {\n const value = { ...rule.value };\n const match: EvalMatch = {\n isMatch: true,\n value,\n ruleIndex: ruleIndexOffset + i,\n weightedValueIndex: -1,\n };\n\n // Resolve weighted values\n if (value.type === \"weighted_values\" && value.value) {\n const wvData = value.value;\n if (wvData && wvData.weightedValues) {\n const resolved = this.weighted.resolve(wvData, cfg.key, contexts);\n if (resolved.value !== undefined) {\n match.value = resolved.value;\n match.weightedValueIndex = resolved.index;\n }\n }\n }\n\n return match;\n }\n }\n return undefined;\n }\n\n private evaluateAllCriteria(\n cfg: ConfigResponse,\n criteria: Criterion[],\n contexts: Contexts\n ): boolean {\n for (const criterion of criteria) {\n if (!this.evaluateSingleCriterion(cfg, criterion, contexts)) {\n return false;\n }\n }\n return true;\n }\n\n private evaluateSingleCriterion(\n cfg: ConfigResponse,\n criterion: Criterion,\n contexts: Contexts\n ): boolean {\n const propertyName = criterion.propertyName ?? \"\";\n const { value: contextValue, exists: contextExists } = getContextValue(\n contexts,\n propertyName\n );\n\n // Build a segment resolver that recursively evaluates segment configs\n const segmentResolver: SegmentResolver = (segmentKey: string) => {\n const segConfig = this.configStore.get(segmentKey);\n if (segConfig === undefined) {\n return { result: false, found: false };\n }\n // Evaluate the segment config (segments have no environment, use default rules)\n const segMatch = this.evaluateConfig(segConfig, \"\", contexts);\n if (!segMatch.isMatch || segMatch.value === undefined) {\n return { result: false, found: false };\n }\n return { result: !!segMatch.value.value, found: true };\n };\n\n return evaluateCriterion(contextValue, contextExists, criterion, segmentResolver);\n }\n}\n","import { randomBytes, createCipheriv, createDecipheriv } from \"crypto\";\nimport type { CipherGCMTypes } from \"crypto\";\n\nconst CIPHER_TYPE: CipherGCMTypes = \"aes-256-gcm\";\nconst SEPARATOR = \"--\";\nconst KEY_LENGTH = 32; // 32 bytes for aes-256-gcm\n\n/**\n * Generate a new random hex-encoded 32-byte key for AES-256-GCM encryption.\n */\nexport function generateNewHexKey(): string {\n return randomBytes(KEY_LENGTH).toString(\"hex\");\n}\n\n/**\n * Encrypt a string using AES-256-GCM.\n *\n * Returns a string in format: \"DATA--IV--AUTH_TAG\" where each part is hex-encoded.\n */\nexport function encrypt(clearText: string, keyStringHex: string): string {\n if (keyStringHex.length !== KEY_LENGTH * 2) {\n throw new Error(\n `Invalid key length. Key must be a 64 character hex string (representing a 32-byte key). You provided ${keyStringHex.length} characters.`\n );\n }\n\n const key = Buffer.from(keyStringHex, \"hex\");\n const iv = randomBytes(12);\n const cipher = createCipheriv(CIPHER_TYPE, key, iv);\n let encrypted = cipher.update(clearText, \"utf8\", \"hex\");\n encrypted += cipher.final(\"hex\");\n const tag = cipher.getAuthTag().toString(\"hex\");\n return [encrypted, iv.toString(\"hex\"), tag].join(SEPARATOR);\n}\n\n/**\n * Decrypt an AES-256-GCM encrypted value.\n *\n * The encrypted string must be in format: \"DATA--IV--AUTH_TAG\" where each part is hex-encoded.\n */\nexport function decrypt(encryptedString: string, keyStringHex: string): string {\n if (keyStringHex.length !== 64) {\n throw new Error(\n \"Invalid key length. Key must be a 64-character hex string.\"\n );\n }\n\n const key = Buffer.from(keyStringHex, \"hex\");\n const parts = encryptedString.split(SEPARATOR);\n\n if (parts.length !== 3) {\n throw new Error(\n \"Invalid encrypted string. Must contain encrypted data, IV, and auth tag.\"\n );\n }\n\n const encryptedDataPart = parts[0]!;\n const ivPart = parts[1]!;\n const authTagPart = parts[2]!;\n\n if (encryptedDataPart === \"\") {\n return \"\";\n }\n\n const encryptedData = Buffer.from(encryptedDataPart, \"hex\");\n const iv = Buffer.from(ivPart, \"hex\");\n const authTag = Buffer.from(authTagPart, \"hex\");\n\n const decipher = createDecipheriv(CIPHER_TYPE, key, iv);\n decipher.setAuthTag(authTag);\n\n let decrypted = decipher.update(encryptedData);\n decrypted = Buffer.concat([decrypted, decipher.final()]);\n return decrypted.toString(\"utf8\");\n}\n","const PATTERN =\n /P(?:(?<days>\\d+(?:\\.\\d+)?)D)?(?:T(?:(?<hours>\\d+(?:\\.\\d+)?)H)?(?:(?<minutes>\\d+(?:\\.\\d+)?)M)?(?:(?<seconds>\\d+(?:\\.\\d+)?)S)?)?/;\n\nconst MINUTES_IN_SECONDS = 60;\nconst HOURS_IN_SECONDS = 60 * MINUTES_IN_SECONDS;\nconst DAYS_IN_SECONDS = 24 * HOURS_IN_SECONDS;\n\n/**\n * Parse an ISO 8601 duration string and return the number of milliseconds.\n *\n * Supports formats like: PT0.2S, PT90S, PT1.5M, PT0.5H, P1DT6H2M1.5S\n */\nexport function durationToMilliseconds(duration: string): number {\n const match = PATTERN.exec(duration);\n if (match === null) {\n return 0;\n }\n\n const days = parseFloat(match.groups?.[\"days\"] ?? \"0\");\n const hours = parseFloat(match.groups?.[\"hours\"] ?? \"0\");\n const minutes = parseFloat(match.groups?.[\"minutes\"] ?? \"0\");\n const seconds = parseFloat(match.groups?.[\"seconds\"] ?? \"0\");\n\n return (\n (days * DAYS_IN_SECONDS +\n hours * HOURS_IN_SECONDS +\n minutes * MINUTES_IN_SECONDS +\n seconds) *\n 1000\n );\n}\n","import type { ConfigResponse, Contexts, GetValue, Value, ValueType } from \"./types\";\nimport type { ConfigStore } from \"./store\";\nimport type { Evaluator } from \"./evaluator\";\nimport { decrypt } from \"./encryption\";\nimport { durationToMilliseconds } from \"./duration\";\nimport { createHash } from \"crypto\";\n\nconst TRUE_VALUES = new Set([\"true\", \"1\", \"t\", \"yes\"]);\n\nconst CONFIDENTIAL_PREFIX = \"*****\";\n\n/**\n * Make a confidential hash for reporting (MD5 last 5 chars).\n */\nfunction makeConfidential(secret: string): string {\n const md5 = createHash(\"md5\").update(secret).digest(\"hex\");\n return `${CONFIDENTIAL_PREFIX}${md5.slice(-5)}`;\n}\n\n/**\n * Resolver handles post-evaluation value resolution:\n * - ENV_VAR provided values\n * - Decryption of confidential values\n * - Type coercion\n * - Duration parsing\n * - JSON parsing\n */\nexport class Resolver {\n private store: ConfigStore;\n private evaluator: Evaluator;\n\n constructor(store: ConfigStore, evaluator: Evaluator) {\n this.store = store;\n this.evaluator = evaluator;\n }\n\n /**\n * Resolve a matched value. Handles:\n * - provided values (ENV_VAR lookup)\n * - decryption of confidential values\n */\n resolveValue(\n val: Value,\n configKey: string,\n valueType: ValueType,\n envID: string,\n contexts: Contexts\n ): { resolved: Value; reportableValue?: GetValue } {\n // Handle provided values (ENV_VAR)\n if (val.type === \"provided\") {\n const provided = val.value;\n if (provided && provided.source === \"ENV_VAR\" && provided.lookup) {\n const envValue = process.env[provided.lookup];\n if (envValue === undefined) {\n throw new Error(\n `Environment variable \"${provided.lookup}\" not set for config \"${configKey}\"`\n );\n }\n\n const coerced = coerceValue(envValue, valueType);\n return {\n resolved: {\n type: valueTypeForCoerced(valueType),\n value: coerced,\n },\n };\n }\n return { resolved: val };\n }\n\n // Handle decryption\n if (val.confidential && val.decryptWith) {\n const keyCfg = this.store.get(val.decryptWith);\n if (keyCfg === undefined) {\n throw new Error(`Decryption key config \"${val.decryptWith}\" not found`);\n }\n\n const keyMatch = this.evaluator.evaluateConfig(keyCfg, envID, contexts);\n if (!keyMatch.isMatch || keyMatch.value === undefined) {\n throw new Error(`Decryption key config \"${val.decryptWith}\" did not match`);\n }\n\n // Resolve the key value recursively (it could itself be a provided ENV_VAR)\n const { resolved: resolvedKey } = this.resolveValue(\n keyMatch.value,\n keyCfg.key,\n keyCfg.valueType,\n envID,\n contexts\n );\n\n const secretKey = String(resolvedKey.value);\n if (!secretKey) {\n throw new Error(`Decryption key from \"${val.decryptWith}\" is empty`);\n }\n\n const decrypted = decrypt(String(val.value), secretKey);\n return {\n resolved: {\n type: \"string\",\n value: decrypted,\n confidential: true,\n },\n reportableValue: makeConfidential(String(val.value)),\n };\n }\n\n // Check if value is confidential (but not encrypted)\n if (val.confidential) {\n return {\n resolved: val,\n reportableValue: makeConfidential(String(val.value)),\n };\n }\n\n return { resolved: val };\n }\n\n /**\n * Unwrap a resolved value to a plain JS value.\n */\n unwrapValue(val: Value): GetValue {\n switch (val.type) {\n case \"bool\":\n return !!val.value;\n case \"int\":\n return typeof val.value === \"number\" ? val.value : parseInt(String(val.value), 10);\n case \"double\":\n return typeof val.value === \"number\" ? val.value : parseFloat(String(val.value));\n case \"string\":\n return String(val.value ?? \"\");\n case \"json\":\n if (typeof val.value === \"string\") {\n try {\n return JSON.parse(val.value);\n } catch {\n return val.value;\n }\n }\n return val.value;\n case \"string_list\":\n if (Array.isArray(val.value)) {\n return val.value.map((v: any) => String(v));\n }\n return [];\n case \"log_level\":\n return typeof val.value === \"number\" ? val.value : String(val.value ?? \"\");\n case \"duration\":\n return durationToMilliseconds(String(val.value ?? \"\"));\n default:\n return val.value;\n }\n }\n}\n\nfunction coerceValue(value: string, valueType: ValueType): any {\n switch (valueType) {\n case \"string\":\n return value;\n case \"int\": {\n const n = parseInt(value, 10);\n if (isNaN(n)) throw new Error(`Cannot convert \"${value}\" to int`);\n return n;\n }\n case \"double\": {\n const n = parseFloat(value);\n if (isNaN(n)) throw new Error(`Cannot convert \"${value}\" to double`);\n return n;\n }\n case \"bool\":\n return TRUE_VALUES.has(value.toLowerCase());\n case \"string_list\":\n return value.split(/\\s*,\\s*/);\n case \"duration\":\n return value;\n default:\n return value;\n }\n}\n\nfunction valueTypeForCoerced(valueType: ValueType): ValueType {\n switch (valueType) {\n case \"int\":\n return \"int\";\n case \"double\":\n return \"double\";\n case \"bool\":\n return \"bool\";\n case \"string_list\":\n return \"string_list\";\n default:\n return \"string\";\n }\n}\n","import type { ConfigEnvelope } from \"./types\";\n\nconst SDK_VERSION = \"0.1.0\";\n\nexport interface FetchResult {\n envelope?: ConfigEnvelope;\n notChanged: boolean;\n}\n\n/**\n * HTTP transport for fetching configs from the Quonfig API.\n *\n * Supports ETag-based caching to avoid re-downloading unchanged configs.\n * Accepts an ordered list of base URLs and tries each in turn (primary/secondary failover).\n */\nexport const DEFAULT_TELEMETRY_URL = \"https://telemetry.quonfig.com\";\n\nexport class Transport {\n private baseUrls: string[];\n private activeBaseUrl: string;\n private telemetryBaseUrl: string;\n private sdkKey: string;\n private etag: string = \"\";\n\n constructor(baseUrls: string[], sdkKey: string, telemetryBaseUrl?: string) {\n this.baseUrls = baseUrls.map((u) => u.replace(/\\/$/, \"\"));\n this.activeBaseUrl = this.baseUrls[0];\n // Priority: QUONFIG_TELEMETRY_URL env var > constructor option > default\n const envUrl = process.env.QUONFIG_TELEMETRY_URL;\n const url = envUrl || telemetryBaseUrl || DEFAULT_TELEMETRY_URL;\n this.telemetryBaseUrl = url.replace(/\\/$/, \"\");\n this.sdkKey = sdkKey;\n }\n\n /**\n * Build the Basic auth header value.\n * Uses username \"1\" like the Go SDK: base64(\"1:{sdkKey}\")\n */\n private getAuthHeader(): string {\n return \"Basic \" + Buffer.from(`1:${this.sdkKey}`).toString(\"base64\");\n }\n\n /**\n * Common headers for all requests.\n */\n private getHeaders(extra?: Record<string, string>): Record<string, string> {\n return {\n Authorization: this.getAuthHeader(),\n \"X-Quonfig-SDK-Version\": `node-${SDK_VERSION}`,\n Accept: \"application/json\",\n ...extra,\n };\n }\n\n /**\n * Fetch configs from GET /api/v2/configs with ETag caching.\n *\n * Tries each base URL in order. Returns the first successful result.\n * Returns `{ notChanged: true }` if the server responds with 304.\n */\n async fetchConfigs(): Promise<FetchResult> {\n let lastError: Error | undefined;\n\n for (const baseUrl of this.baseUrls) {\n try {\n const headers = this.getHeaders();\n if (this.etag) {\n headers[\"If-None-Match\"] = this.etag;\n }\n\n const response = await fetch(`${baseUrl}/api/v2/configs`, {\n method: \"GET\",\n headers,\n });\n\n if (response.status === 304) {\n this.activeBaseUrl = baseUrl;\n return { notChanged: true };\n }\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new Error(`Unexpected status ${response.status} from ${baseUrl}: ${body}`);\n }\n\n const etag = response.headers.get(\"ETag\");\n if (etag) {\n this.etag = etag;\n }\n\n this.activeBaseUrl = baseUrl;\n const envelope = (await response.json()) as ConfigEnvelope;\n return { envelope, notChanged: false };\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n }\n }\n\n throw lastError ?? new Error(\"All API URLs failed\");\n }\n\n /**\n * Post telemetry data to the telemetry endpoint.\n */\n async postTelemetry(data: any): Promise<void> {\n const headers = this.getHeaders({\n \"Content-Type\": \"application/json\",\n });\n\n const response = await fetch(`${this.telemetryBaseUrl}/api/v1/telemetry/`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(data),\n });\n\n if (!response.ok) {\n // Telemetry failures are non-fatal; just log\n const body = await response.text().catch(() => \"\");\n console.warn(`[quonfig] Telemetry POST failed: ${response.status} ${body}`);\n }\n }\n\n /**\n * Get the SSE URL for config streaming.\n * Uses whichever base URL last succeeded for fetchConfigs.\n */\n getSSEUrl(): string {\n return `${this.activeBaseUrl}/api/v2/sse/config`;\n }\n\n /**\n * Get auth headers for SSE connection.\n */\n getSSEHeaders(): Record<string, string> {\n return this.getHeaders({\n Accept: \"text/event-stream\",\n });\n }\n}\n","import type { ConfigEnvelope } from \"./types\";\nimport type { Transport } from \"./transport\";\n\n/**\n * SSE connection for receiving real-time config updates.\n *\n * Uses the `eventsource` npm package for Server-Sent Events.\n */\nexport class SSEConnection {\n private transport: Transport;\n private eventSource: any = null;\n\n constructor(transport: Transport) {\n this.transport = transport;\n }\n\n /**\n * Start listening for SSE events.\n *\n * The onUpdate callback receives the new config envelope on each event.\n */\n start(onUpdate: (envelope: ConfigEnvelope) => void): void {\n // Dynamic import of eventsource to avoid issues when it's not installed\n this.connectSSE(onUpdate).catch((err) => {\n console.warn(\"[quonfig] SSE connection failed:\", err);\n });\n }\n\n private async connectSSE(onUpdate: (envelope: ConfigEnvelope) => void): Promise<void> {\n try {\n // Use dynamic import for eventsource\n const EventSourceModule = await import(\"eventsource\");\n const EventSource = EventSourceModule.default || EventSourceModule;\n\n const url = this.transport.getSSEUrl();\n const headers = this.transport.getSSEHeaders();\n\n this.eventSource = new EventSource(url, { headers });\n\n this.eventSource.onmessage = (event: any) => {\n try {\n const envelope: ConfigEnvelope = JSON.parse(event.data);\n onUpdate(envelope);\n } catch (err) {\n console.warn(\"[quonfig] SSE message parse error:\", err);\n }\n };\n\n this.eventSource.onerror = (err: any) => {\n console.warn(\"[quonfig] SSE error:\", err);\n // EventSource will auto-reconnect\n };\n } catch (err) {\n console.warn(\"[quonfig] Failed to initialize SSE:\", err);\n }\n }\n\n /**\n * Close the SSE connection.\n */\n close(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n }\n}\n","import type { Contexts, GetValue, LogLevelName, LogLevelNumber } from \"./types\";\n\nexport const LOG_LEVEL_PREFIX = \"log-level.\";\n\nconst VALID_LOG_LEVEL_NAMES: readonly LogLevelName[] = [\n \"trace\",\n \"debug\",\n \"info\",\n \"warn\",\n \"error\",\n \"fatal\",\n] as const;\n\nconst WORD_LEVEL_LOOKUP: Record<LogLevelName, LogLevelNumber> = {\n trace: 1,\n debug: 2,\n info: 3,\n warn: 5,\n error: 6,\n fatal: 9,\n};\n\nconst NUMBER_LEVEL_LOOKUP: Record<LogLevelNumber, LogLevelName> = {\n 1: \"trace\",\n 2: \"debug\",\n 3: \"info\",\n 5: \"warn\",\n 6: \"error\",\n 9: \"fatal\",\n};\n\n/**\n * Convert a log level name to its numeric value.\n */\nexport function wordLevelToNumber(level: LogLevelName): LogLevelNumber | undefined {\n return WORD_LEVEL_LOOKUP[level];\n}\n\n/**\n * Parse a log level (string name or number) to a numeric value.\n */\nexport function parseLevel(level: string | number | undefined): LogLevelNumber | undefined {\n if (typeof level === \"number\") {\n return level as LogLevelNumber;\n }\n if (typeof level === \"string\") {\n // Try as a log level name\n const lower = level.toLowerCase() as LogLevelName;\n if (WORD_LEVEL_LOOKUP[lower] !== undefined) {\n return WORD_LEVEL_LOOKUP[lower];\n }\n // Try as a number string (e.g., from config values)\n const n = parseInt(level, 10);\n if (!isNaN(n) && NUMBER_LEVEL_LOOKUP[n as LogLevelNumber] !== undefined) {\n return n as LogLevelNumber;\n }\n }\n return undefined;\n}\n\n/**\n * Check if a log message at desiredLevel should be logged, given the logger hierarchy.\n *\n * Walks up the logger name hierarchy (e.g., \"log-level.a.b.c\" -> \"log-level.a.b\" -> \"log-level.a\")\n * looking for a matching config. If no config is found, uses defaultLevel.\n */\nexport function shouldLog(args: {\n loggerName: string;\n desiredLevel: LogLevelNumber;\n defaultLevel: LogLevelNumber;\n getConfig: (key: string) => GetValue;\n}): boolean {\n const { loggerName, desiredLevel, defaultLevel, getConfig } = args;\n\n let loggerNameWithPrefix = LOG_LEVEL_PREFIX + loggerName;\n\n while (loggerNameWithPrefix.includes(\".\")) {\n const resolvedLevel = getConfig(loggerNameWithPrefix);\n\n if (resolvedLevel !== undefined) {\n return Number(resolvedLevel) <= desiredLevel;\n }\n\n loggerNameWithPrefix = loggerNameWithPrefix.slice(\n 0,\n loggerNameWithPrefix.lastIndexOf(\".\")\n );\n }\n\n return defaultLevel <= desiredLevel;\n}\n","import { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\n\nimport type { ConfigEnvelope, ConfigResponse, QuonfigDatadirEnvironments, WorkspaceConfigDocument } from \"./types\";\n\nconst CONFIG_SUBDIRS = [\"configs\", \"feature-flags\", \"segments\", \"schemas\", \"log-levels\"] as const;\n\nexport function loadEnvelopeFromDatadir(datadir: string): ConfigEnvelope {\n const environmentId = loadEnvironmentId(join(datadir, \"environments.json\"));\n const configs: ConfigResponse[] = [];\n\n for (const subdir of CONFIG_SUBDIRS) {\n const dir = join(datadir, subdir);\n if (!existsSync(dir)) {\n continue;\n }\n\n const filenames = readdirSync(dir)\n .filter((filename) => filename.endsWith(\".json\"))\n .sort((a, b) => a.localeCompare(b));\n\n for (const filename of filenames) {\n const raw = JSON.parse(readFileSync(join(dir, filename), \"utf-8\")) as WorkspaceConfigDocument;\n configs.push(toConfigResponse(raw, environmentId));\n }\n }\n\n return {\n configs,\n meta: {\n version: `datadir:${datadir}`,\n environment: environmentId,\n },\n };\n}\n\nfunction loadEnvironmentId(environmentsPath: string): string {\n if (!existsSync(environmentsPath)) {\n throw new Error(`[quonfig] Datadir is missing environments.json: ${environmentsPath}`);\n }\n\n const environments = JSON.parse(readFileSync(environmentsPath, \"utf-8\")) as\n | QuonfigDatadirEnvironments\n | { environments?: QuonfigDatadirEnvironments };\n\n const candidates = normalizeEnvironmentCandidates(\n isWrappedEnvironmentList(environments) ? environments.environments : environments\n );\n\n if (candidates.length === 0) {\n return \"\";\n }\n\n return candidates[0];\n}\n\nfunction isWrappedEnvironmentList(\n value: QuonfigDatadirEnvironments | { environments?: QuonfigDatadirEnvironments }\n): value is { environments?: QuonfigDatadirEnvironments } {\n return Boolean(\n value &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n \"environments\" in value\n );\n}\n\nfunction normalizeEnvironmentCandidates(environments: QuonfigDatadirEnvironments | undefined): string[] {\n if (!environments) {\n return [];\n }\n\n if (Array.isArray(environments)) {\n return environments\n .map((entry) => {\n if (typeof entry === \"string\") {\n return entry;\n }\n if (entry && typeof entry === \"object\") {\n return entry.id ?? entry.name;\n }\n return undefined;\n })\n .filter((entry): entry is string => typeof entry === \"string\" && entry.length > 0);\n }\n\n if (environments && typeof environments === \"object\") {\n const values = Object.values(environments)\n .map((value) => (typeof value === \"string\" && value.length > 0 ? value : undefined))\n .filter((value): value is string => typeof value === \"string\");\n\n if (values.length > 0) {\n return values;\n }\n\n return Object.keys(environments).filter((key) => key.length > 0);\n }\n\n return [];\n}\n\nfunction toConfigResponse(raw: WorkspaceConfigDocument, environmentId: string): ConfigResponse {\n const environment = raw.environments?.find((candidate) => candidate.id === environmentId);\n\n return {\n id: raw.id ?? \"\",\n key: raw.key,\n type: raw.type,\n valueType: raw.valueType,\n sendToClientSdk: raw.sendToClientSdk ?? false,\n default: raw.default ?? { rules: [] },\n environment,\n };\n}\n","import type { Evaluation, EvaluationSummary, TelemetryEvent } from \"../types\";\n\n/**\n * Collects evaluation summaries for telemetry reporting.\n *\n * Each evaluation is aggregated by (configKey, configType) and\n * counted by (configId, ruleIndex, value, weightedValueIndex).\n */\nexport class EvaluationSummaryCollector {\n private enabled: boolean;\n private data: Map<string, Map<string, number>> = new Map();\n private startAt: number | undefined;\n private maxDataSize: number;\n\n constructor(enabled: boolean, maxDataSize: number = 10000) {\n this.enabled = enabled;\n this.maxDataSize = maxDataSize;\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n push(evaluation: Evaluation): void {\n if (!this.enabled) return;\n if (this.data.size >= this.maxDataSize) return;\n if (evaluation.unwrappedValue === undefined) return;\n if (evaluation.configType === \"log_level\") return;\n\n this.startAt = this.startAt ?? Date.now();\n\n const key = JSON.stringify([evaluation.configKey, evaluation.configType]);\n const counter = JSON.stringify([\n evaluation.configId,\n evaluation.ruleIndex,\n typeof evaluation.unwrappedValue,\n evaluation.reportableValue ?? evaluation.unwrappedValue,\n evaluation.weightedValueIndex,\n ]);\n\n let countersForKey = this.data.get(key);\n if (countersForKey === undefined) {\n countersForKey = new Map();\n this.data.set(key, countersForKey);\n }\n\n const currentCount = countersForKey.get(counter) ?? 0;\n countersForKey.set(counter, currentCount + 1);\n }\n\n /**\n * Drain collected summaries into a TelemetryEvent, or return undefined if empty.\n */\n drain(): TelemetryEvent | undefined {\n if (this.data.size === 0) return undefined;\n\n const summaries: EvaluationSummary[] = [];\n\n this.data.forEach((rawCounters, keyJSON) => {\n const [configKey, configType] = JSON.parse(keyJSON);\n\n const counters: any[] = [];\n rawCounters.forEach((count, counterJSON) => {\n const [configId, ruleIndex, valueType, value, weightedValueIndex] =\n JSON.parse(counterJSON);\n\n const counter: any = {\n configId,\n conditionalValueIndex: ruleIndex,\n configRowIndex: 0,\n selectedValue: { [valueType]: value },\n count,\n };\n\n if (weightedValueIndex !== undefined && weightedValueIndex >= 0) {\n counter.weightedValueIndex = weightedValueIndex;\n }\n\n counters.push(counter);\n });\n\n summaries.push({\n key: configKey,\n type: configType,\n counters,\n });\n });\n\n const event: TelemetryEvent = {\n summaries: {\n start: this.startAt ?? Date.now(),\n end: Date.now(),\n summaries,\n },\n };\n\n // Clear data after drain\n this.data.clear();\n this.startAt = undefined;\n\n return event;\n }\n}\n","import type { ContextShape, Contexts, ContextUploadMode, TelemetryEvent } from \"../types\";\n\n/**\n * Collects context shapes (field names + types) for telemetry reporting.\n */\nexport class ContextShapeCollector {\n private enabled: boolean;\n private data: Map<string, Record<string, number>> = new Map();\n private maxDataSize: number;\n\n constructor(contextUploadMode: ContextUploadMode, maxDataSize: number = 10000) {\n this.enabled = contextUploadMode !== \"none\";\n this.maxDataSize = maxDataSize;\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n push(contexts: Contexts): void {\n if (!this.enabled) return;\n\n for (const [name, ctx] of Object.entries(contexts)) {\n for (const [key, value] of Object.entries(ctx)) {\n let shape = this.data.get(name);\n\n if (shape === undefined && this.data.size >= this.maxDataSize) {\n continue;\n }\n\n shape = shape ?? {};\n\n if (shape[key] === undefined) {\n shape[key] = fieldTypeForValue(value);\n this.data.set(name, shape);\n }\n }\n }\n }\n\n /**\n * Drain collected shapes into a TelemetryEvent, or return undefined if empty.\n */\n drain(): TelemetryEvent | undefined {\n if (this.data.size === 0) return undefined;\n\n const shapes: ContextShape[] = [];\n this.data.forEach((shape, name) => {\n shapes.push({ name, fieldTypes: shape });\n });\n\n // Clear data after drain\n this.data.clear();\n\n return {\n contextShapes: { shapes },\n };\n }\n}\n\n/**\n * Determine the field type number for a context value.\n * Maps to the same type numbers as the prefab SDK:\n * 1 = int, 2 = string, 4 = double, 5 = bool, 10 = string_list\n */\nexport function fieldTypeForValue(value: unknown): number {\n if (Number.isInteger(value)) return 1;\n if (typeof value === \"number\") return 4;\n if (typeof value === \"boolean\") return 5;\n if (Array.isArray(value)) return 10;\n return 2; // string\n}\n","import type { Contexts, ContextUploadMode, ExampleContextEntry, TelemetryEvent } from \"../types\";\n\n/**\n * Collects example contexts for telemetry reporting.\n * Only collects when contextUploadMode is \"periodic_example\".\n */\nexport class ExampleContextCollector {\n private enabled: boolean;\n private data: Array<[number, Contexts]> = [];\n private seen: Map<string, number> = new Map();\n private maxDataSize: number;\n private rateLimitMs: number;\n\n constructor(\n contextUploadMode: ContextUploadMode,\n maxDataSize: number = 10000,\n rateLimitMs: number = 60 * 60 * 1000 // 1 hour\n ) {\n this.enabled = contextUploadMode === \"periodic_example\";\n this.maxDataSize = maxDataSize;\n this.rateLimitMs = rateLimitMs;\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n push(contexts: Contexts): void {\n if (!this.enabled) return;\n if (this.data.length >= this.maxDataSize) return;\n\n const key = this.groupedKey(contexts);\n if (key.length === 0) return;\n\n // Rate limit: skip if seen recently\n const lastSeen = this.seen.get(key);\n if (lastSeen !== undefined && Date.now() - lastSeen < this.rateLimitMs) {\n return;\n }\n\n this.data.push([Date.now(), contexts]);\n this.seen.set(key, Date.now());\n }\n\n /**\n * Drain collected examples into a TelemetryEvent, or return undefined if empty.\n */\n drain(): TelemetryEvent | undefined {\n if (this.data.length === 0) return undefined;\n\n const examples: ExampleContextEntry[] = this.data.map(([timestamp, contexts]) => {\n const contextsList = Object.entries(contexts).map(([type, ctx]) => {\n const values: Record<string, any> = {};\n for (const [key, value] of Object.entries(ctx)) {\n values[key] = value;\n }\n return { type, values };\n });\n\n return {\n timestamp,\n contextSet: { contexts: contextsList },\n };\n });\n\n // Clear data after drain\n this.data.length = 0;\n this.pruneCache();\n\n return {\n exampleContexts: { examples },\n };\n }\n\n private groupedKey(contexts: Contexts): string {\n return Object.values(contexts)\n .map((ctx) => {\n const key = ctx[\"key\"] ?? ctx[\"trackingId\"];\n return typeof key === \"string\" ? key : JSON.stringify(key);\n })\n .filter((str) => str !== undefined && str !== null && String(str).length > 0)\n .sort()\n .join(\"|\");\n }\n\n private pruneCache(): void {\n const now = Date.now();\n for (const [key, timestamp] of this.seen.entries()) {\n if (now - timestamp > this.rateLimitMs) {\n this.seen.delete(key);\n }\n }\n }\n}\n","import type { TelemetryEvent, TelemetryPayload } from \"../types\";\nimport type { Transport } from \"../transport\";\nimport type { EvaluationSummaryCollector } from \"./evaluationSummaries\";\nimport type { ContextShapeCollector } from \"./contextShapes\";\nimport type { ExampleContextCollector } from \"./exampleContexts\";\n\n/**\n * TelemetryReporter periodically drains collected telemetry data and sends it\n * to the Quonfig telemetry endpoint.\n */\nexport class TelemetryReporter {\n private transport: Transport;\n private instanceHash: string;\n private evaluationSummaries: EvaluationSummaryCollector;\n private contextShapes: ContextShapeCollector;\n private exampleContexts: ExampleContextCollector;\n private timer: ReturnType<typeof setTimeout> | undefined;\n private initialDelay: number;\n private maxDelay: number;\n private currentDelay: number;\n private stopped: boolean = false;\n\n constructor(args: {\n transport: Transport;\n instanceHash: string;\n evaluationSummaries: EvaluationSummaryCollector;\n contextShapes: ContextShapeCollector;\n exampleContexts: ExampleContextCollector;\n initialDelay?: number;\n maxDelay?: number;\n }) {\n this.transport = args.transport;\n this.instanceHash = args.instanceHash;\n this.evaluationSummaries = args.evaluationSummaries;\n this.contextShapes = args.contextShapes;\n this.exampleContexts = args.exampleContexts;\n this.initialDelay = args.initialDelay ?? 8000;\n this.maxDelay = args.maxDelay ?? 600000;\n this.currentDelay = this.initialDelay;\n }\n\n /**\n * Start the periodic telemetry reporting loop.\n */\n start(): void {\n if (this.stopped) return;\n this.scheduleNext();\n }\n\n /**\n * Stop telemetry reporting.\n */\n stop(): void {\n this.stopped = true;\n if (this.timer !== undefined) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n }\n\n private scheduleNext(): void {\n if (this.stopped) return;\n\n this.timer = setTimeout(async () => {\n try {\n await this.sync();\n // Success — reset to base interval\n this.currentDelay = this.initialDelay;\n } catch (err) {\n console.warn(\"[quonfig] Telemetry sync error:\", err);\n // Exponential backoff with cap on failure\n this.currentDelay = Math.min(this.currentDelay * 1.5, this.maxDelay);\n } finally {\n this.scheduleNext();\n }\n }, this.currentDelay);\n\n // Allow the timer to not prevent process exit\n if (this.timer && typeof this.timer === \"object\" && \"unref\" in this.timer) {\n this.timer.unref();\n }\n }\n\n private async sync(): Promise<void> {\n const events: TelemetryEvent[] = [];\n\n // Drain evaluation summaries\n const summaryEvent = this.evaluationSummaries.drain();\n if (summaryEvent) events.push(summaryEvent);\n\n // Drain context shapes\n const shapesEvent = this.contextShapes.drain();\n if (shapesEvent) events.push(shapesEvent);\n\n // Drain example contexts\n const examplesEvent = this.exampleContexts.drain();\n if (examplesEvent) events.push(examplesEvent);\n\n if (events.length === 0) return;\n\n const payload: TelemetryPayload = {\n instanceHash: this.instanceHash,\n events,\n };\n\n await this.transport.postTelemetry(payload);\n }\n}\n","// ---- Value Types ----\n\nexport type ValueType =\n | \"bool\"\n | \"int\"\n | \"double\"\n | \"string\"\n | \"json\"\n | \"string_list\"\n | \"log_level\"\n | \"weighted_values\"\n | \"schema\"\n | \"provided\"\n | \"duration\";\n\n// ---- Config Types ----\n\nexport type ConfigTypeString =\n | \"feature_flag\"\n | \"config\"\n | \"segment\"\n | \"log_level\"\n | \"schema\";\n\n// ---- Provided Data ----\n\nexport interface ProvidedData {\n source: string;\n lookup: string;\n}\n\n// ---- Weighted Values ----\n\nexport interface WeightedValue {\n weight: number;\n value: Value;\n}\n\nexport interface WeightedValuesData {\n weightedValues: WeightedValue[];\n hashByPropertyName?: string;\n}\n\n// ---- Schema ----\n\nexport interface SchemaData {\n schemaType: string;\n schema: string;\n}\n\n// ---- Value ----\n\nexport interface Value {\n type: ValueType;\n value: any;\n confidential?: boolean;\n decryptWith?: string;\n}\n\n// ---- Criterion ----\n\nexport interface Criterion {\n propertyName?: string;\n operator: string;\n valueToMatch?: Value;\n}\n\n// ---- Rule ----\n\nexport interface Rule {\n criteria: Criterion[];\n value: Value;\n}\n\n// ---- RuleSet ----\n\nexport interface RuleSet {\n rules: Rule[];\n}\n\n// ---- Environment ----\n\nexport interface Environment {\n id: string;\n rules: Rule[];\n}\n\n// ---- ConfigResponse ----\n\nexport interface ConfigResponse {\n id: string;\n key: string;\n type: ConfigTypeString;\n valueType: ValueType;\n sendToClientSdk: boolean;\n default: RuleSet;\n environment?: Environment;\n}\n\n// ---- ConfigEnvelope ----\n\nexport interface Meta {\n version: string;\n environment: string;\n workspaceId?: string;\n}\n\nexport interface ConfigEnvelope {\n configs: ConfigResponse[];\n meta: Meta;\n}\n\nexport interface WorkspaceEnvironment {\n id: string;\n rules: Rule[];\n}\n\nexport interface WorkspaceConfigDocument {\n id?: string;\n key: string;\n type: ConfigTypeString;\n valueType: ValueType;\n sendToClientSdk?: boolean;\n default?: RuleSet;\n environments?: WorkspaceEnvironment[];\n}\n\nexport type QuonfigDatadirEnvironments =\n | Record<string, string>\n | Array<string | { id?: string; name?: string }>;\n\n// ---- Context ----\n\nexport type ContextValue = string | number | boolean | string[] | null | undefined;\n\nexport type Contexts = { [contextName: string]: { [key: string]: ContextValue } };\n\n// ---- GetValue ----\n\nexport type GetValue = string | number | boolean | string[] | undefined;\n\n// ---- On no default behavior ----\n\nexport type OnNoDefault = \"error\" | \"warn\" | \"ignore\";\n\n// ---- Context upload mode ----\n\nexport type ContextUploadMode = \"none\" | \"shapes_only\" | \"periodic_example\";\n\n// ---- Options ----\n\nexport interface QuonfigOptions {\n sdkKey: string;\n /** @deprecated Use apiUrls instead. If provided, used as a single-element URL list. */\n apiUrl?: string;\n /** Ordered list of API base URLs to try. Defaults to [\"https://primary.quonfig.com\", \"https://secondary.quonfig.com\"]. */\n apiUrls?: string[];\n /** Base URL for the dedicated telemetry service. Defaults to https://telemetry.quonfig.com. Overridden by QUONFIG_TELEMETRY_URL env var. */\n telemetryUrl?: string;\n enableSSE?: boolean;\n enablePolling?: boolean;\n pollInterval?: number;\n namespace?: string;\n globalContext?: Contexts;\n onNoDefault?: OnNoDefault;\n collectEvaluationSummaries?: boolean;\n collectLoggerCounts?: boolean;\n contextUploadMode?: ContextUploadMode;\n initTimeout?: number;\n datadir?: string;\n datafile?: string | object;\n}\n\n// ---- Evaluation Result ----\n\nexport interface EvalMatch {\n isMatch: boolean;\n value?: Value;\n ruleIndex: number;\n weightedValueIndex: number;\n}\n\n// ---- Log Level ----\n\nexport type LogLevelName = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\nexport type LogLevelNumber = 1 | 2 | 3 | 5 | 6 | 9;\n\n// ---- Telemetry Event Types ----\n\nexport interface EvaluationCounter {\n configId: string;\n conditionalValueIndex: number;\n configRowIndex: number;\n selectedValue: any;\n count: number;\n weightedValueIndex?: number;\n}\n\nexport interface EvaluationSummary {\n key: string;\n type: string;\n counters: EvaluationCounter[];\n}\n\nexport interface ContextShape {\n name: string;\n fieldTypes: { [key: string]: number };\n}\n\nexport interface ExampleContextEntry {\n timestamp: number;\n contextSet: {\n contexts: Array<{\n type: string;\n values: { [key: string]: any };\n }>;\n };\n}\n\nexport interface TelemetryEvent {\n summaries?: {\n start: number;\n end: number;\n summaries: EvaluationSummary[];\n };\n contextShapes?: {\n shapes: ContextShape[];\n };\n exampleContexts?: {\n examples: ExampleContextEntry[];\n };\n}\n\nexport interface TelemetryPayload {\n instanceHash: string;\n events: TelemetryEvent[];\n}\n\n// ---- Internal Evaluation ----\n\nexport interface Evaluation {\n configId: string;\n configKey: string;\n configType: ConfigTypeString;\n unwrappedValue: GetValue;\n reportableValue?: GetValue;\n ruleIndex: number;\n weightedValueIndex?: number;\n}\n\n// ---- Enum-like constants for CLI compatibility ----\n\n// Runtime object for ConfigType enum access (e.g., ConfigType.FeatureFlag)\nexport const ConfigType = {\n FeatureFlag: \"feature_flag\" as ConfigTypeString,\n Config: \"config\" as ConfigTypeString,\n Segment: \"segment\" as ConfigTypeString,\n LogLevel: \"log_level\" as ConfigTypeString,\n Schema: \"schema\" as ConfigTypeString,\n} as const;\n\nexport const ProvidedSource = {\n EnvVar: \"ENV_VAR\",\n} as const;\n\n// ---- Typed Config interfaces (augmented by CLI codegen) ----\n\n// These are placeholder interfaces that the CLI's `gen` command\n// augments via TypeScript module augmentation.\nexport interface NodeServerConfigurationRaw {}\nexport interface NodeServerConfigurationAccessor {}\nexport type TypedNodeServerConfigurationRaw = NodeServerConfigurationRaw;\nexport type TypedNodeServerConfigurationAccessor = NodeServerConfigurationAccessor;\n","/**\n * CLI-compatibility types and utilities.\n *\n * These are needed by @quonfig/cli but are NOT part of the core SDK.\n * They provide the HTTP API client, SDK-key parsing, and legacy\n * config-value types that the CLI's CRUD commands depend on.\n */\n\nimport type { ConfigResponse, ValueType } from \"./types\";\n\n// ---- HTTP API Client ----\n\nexport interface ClientOptions {\n jwt?: string;\n sdkKey?: string;\n apiUrl: string;\n clientIdentifier: string;\n log?: (category: string | unknown, message?: unknown) => void;\n}\n\n/**\n * Minimal HTTP client for the Quonfig REST API.\n * Used by the CLI for CRUD operations (create, set-default, download, etc.).\n */\nexport class Client {\n private jwt?: string;\n private sdkKey?: string;\n private apiUrl: string;\n private clientIdentifier: string;\n private log: (category: string | unknown, message?: unknown) => void;\n\n constructor(options: ClientOptions) {\n this.jwt = options.jwt;\n this.sdkKey = options.sdkKey;\n this.apiUrl = options.apiUrl.replace(/\\/$/, \"\");\n this.clientIdentifier = options.clientIdentifier;\n this.log = options.log ?? (() => {});\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"X-Client-Version\": this.clientIdentifier,\n };\n\n if (this.jwt) {\n h[\"Authorization\"] = `Bearer ${this.jwt}`;\n } else if (this.sdkKey) {\n h[\"Authorization\"] = `Basic ${Buffer.from(this.sdkKey).toString(\"base64\")}`;\n }\n\n return h;\n }\n\n async get(path: string): Promise<Response> {\n const url = `${this.apiUrl}${path}`;\n this.log(\"ApiClient\", `GET ${url}`);\n return fetch(url, { method: \"GET\", headers: this.headers() });\n }\n\n async post(path: string, payload: unknown): Promise<Response> {\n const url = `${this.apiUrl}${path}`;\n const isORPC = path.startsWith(\"/api/v1/\");\n this.log(\"ApiClient\", `POST ${url}`);\n // oRPC endpoints use a wire format: request wrapped as { json: <payload> }\n const body = isORPC\n ? JSON.stringify({ json: payload })\n : JSON.stringify(payload);\n const raw = await fetch(url, {\n method: \"POST\",\n headers: this.headers(),\n body,\n });\n if (!isORPC) return raw;\n // Unwrap oRPC response envelope: { json: <result> } → <result>\n const text = await raw.text();\n let unwrapped = text;\n try {\n const parsed = JSON.parse(text);\n if (parsed && typeof parsed === \"object\" && \"json\" in parsed) {\n unwrapped = JSON.stringify(parsed.json);\n }\n } catch {\n // not JSON, pass through\n }\n return new Response(unwrapped, {\n status: raw.status,\n statusText: raw.statusText,\n headers: raw.headers,\n });\n }\n\n async put(path: string, payload: unknown): Promise<Response> {\n const url = `${this.apiUrl}${path}`;\n this.log(\"ApiClient\", `PUT ${url}`);\n return fetch(url, {\n method: \"PUT\",\n headers: this.headers(),\n body: JSON.stringify(payload),\n });\n }\n\n}\n\n// ---- SDK Key Parsing ----\n\nexport interface ProjectEnvId {\n id: string;\n projectId: number;\n}\n\n/**\n * Parse a Prefab/Quonfig SDK key to extract the project-environment ID.\n * SDK keys are typically in the format: `<projectId>-<envId>-<secret>`\n */\nexport function getProjectEnvFromSdkKey(sdkKey: string): ProjectEnvId {\n const parts = sdkKey.split(\"-\");\n\n if (parts.length < 2) {\n throw new Error(`Invalid SDK key format: cannot extract projectEnvId`);\n }\n\n return {\n id: parts.slice(0, 2).join(\"-\"),\n projectId: Number.parseInt(parts[0], 10) || 0,\n };\n}\n\n// ---- Legacy ConfigValue / ConfigValueType ----\n\n/**\n * ConfigValueType enum, matching the legacy quonfig-common types.\n * Used by the CLI's coerce and config-value-dto utilities.\n */\nexport enum ConfigValueType {\n NotSetValue = 0,\n Int = 1,\n String = 2,\n Bytes = 3,\n Double = 4,\n Bool = 5,\n // 6 was WeightedValues in Prefab\n // 7 was LimitDefinition in Prefab\n LimitDefinition = 7,\n LogLevel = 8,\n StringList = 9,\n IntRange = 10,\n Duration = 11,\n Json = 12,\n}\n\n/**\n * ConfigValue represents a typed value in the legacy format.\n * Used by the CLI for constructing API request payloads.\n */\nexport interface ConfigValue {\n int?: bigint | number;\n string?: string;\n bytes?: Uint8Array;\n double?: number;\n bool?: boolean;\n logLevel?: string;\n stringList?: { values: string[] };\n intRange?: { start?: number; end?: number };\n duration?: { definition?: string; millis?: number };\n json?: { json: string };\n provided?: { source: string; lookup: string };\n confidential?: boolean;\n decryptWith?: string;\n}\n\n// ---- valueTypeStringForConfig ----\n\n/**\n * Extract the value-type string for a ConfigResponse (e.g., \"bool\", \"string\", \"int\").\n * Used by the CLI's `serve` command to format evaluation responses.\n */\nexport function valueTypeStringForConfig(\n config: ConfigResponse\n): ValueType | undefined {\n return config.valueType;\n}\n"],"mappings":"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","names":["import_crypto","import_fs","ctx","murmurhash","match","import_crypto","ConfigValueType"]}
|