@openfeature/server-sdk 1.19.0 → 1.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/provider/provider.ts", "../../src/provider/no-op-provider.ts", "../../src/provider/in-memory-provider/in-memory-provider.ts", "../../src/provider/in-memory-provider/variant-not-found-error.ts", "../../src/open-feature.ts", "../../src/client/internal/open-feature-client.ts", "../../src/events/open-feature-event-emitter.ts", "../../src/events/events.ts", "../../src/transaction-context/no-op-transaction-context-propagator.ts", "../../src/transaction-context/async-local-storage-transaction-context-propagator.ts", "../../src/index.ts"],
4
- "sourcesContent": ["import type {\n CommonProvider,\n EvaluationContext,\n JsonValue,\n Logger,\n ResolutionDetails} from '@openfeature/core';\nimport {\n ServerProviderStatus,\n} from '@openfeature/core';\nimport type { Hook } from '../hooks';\n\nexport { ServerProviderStatus as ProviderStatus };\n\n/**\n * Interface that providers must implement to resolve flag values for their particular\n * backend or vendor.\n *\n * Implementation for resolving all the required flag types must be defined.\n */\nexport interface Provider extends CommonProvider<ServerProviderStatus> {\n /**\n * A provider hook exposes a mechanism for provider authors to register hooks\n * to tap into various stages of the flag evaluation lifecycle. These hooks can\n * be used to perform side effects and mutate the context for purposes of the\n * provider. Provider hooks are not configured or controlled by the application author.\n */\n readonly hooks?: Hook[];\n\n /**\n * Resolve a boolean flag and its evaluation details.\n */\n resolveBooleanEvaluation(\n flagKey: string,\n defaultValue: boolean,\n context: EvaluationContext,\n logger: Logger,\n ): Promise<ResolutionDetails<boolean>>;\n\n /**\n * Resolve a string flag and its evaluation details.\n */\n resolveStringEvaluation(\n flagKey: string,\n defaultValue: string,\n context: EvaluationContext,\n logger: Logger,\n ): Promise<ResolutionDetails<string>>;\n\n /**\n * Resolve a numeric flag and its evaluation details.\n */\n resolveNumberEvaluation(\n flagKey: string,\n defaultValue: number,\n context: EvaluationContext,\n logger: Logger,\n ): Promise<ResolutionDetails<number>>;\n\n /**\n * Resolve and parse an object flag and its evaluation details.\n */\n resolveObjectEvaluation<T extends JsonValue>(\n flagKey: string,\n defaultValue: T,\n context: EvaluationContext,\n logger: Logger,\n ): Promise<ResolutionDetails<T>>;\n}\n", "import type { JsonValue, ResolutionDetails } from '@openfeature/core';\nimport type { Provider } from './provider';\n\nconst REASON_NO_OP = 'No-op';\n\n/**\n * The No-op provider is set by default, and simply always returns the default value.\n */\nclass NoopFeatureProvider implements Provider {\n readonly metadata = {\n name: 'No-op Provider',\n } as const;\n\n resolveBooleanEvaluation(_: string, defaultValue: boolean): Promise<ResolutionDetails<boolean>> {\n return this.noOp(defaultValue);\n }\n\n resolveStringEvaluation(_: string, defaultValue: string): Promise<ResolutionDetails<string>> {\n return this.noOp(defaultValue);\n }\n\n resolveNumberEvaluation(_: string, defaultValue: number): Promise<ResolutionDetails<number>> {\n return this.noOp(defaultValue);\n }\n\n resolveObjectEvaluation<T extends JsonValue>(_: string, defaultValue: T): Promise<ResolutionDetails<T>> {\n return this.noOp<T>(defaultValue);\n }\n\n private noOp<T>(defaultValue: T) {\n return Promise.resolve({\n value: defaultValue,\n reason: REASON_NO_OP,\n });\n }\n}\n\nexport const NOOP_PROVIDER = new NoopFeatureProvider();\n", "import type {\n EvaluationContext,\n FlagValueType,\n JsonValue,\n Logger,\n ResolutionDetails} from '@openfeature/core';\nimport {\n FlagNotFoundError,\n GeneralError,\n OpenFeatureError,\n StandardResolutionReasons,\n TypeMismatchError\n} from '@openfeature/core';\nimport type { Provider } from '../provider';\nimport type { Flag, FlagConfiguration } from './flag-configuration';\nimport { VariantFoundError } from './variant-not-found-error';\nimport { OpenFeatureEventEmitter, ProviderEvents } from '../..';\n\n/**\n * A simple OpenFeature provider intended for demos and as a test stub.\n */\nexport class InMemoryProvider implements Provider {\n public readonly events = new OpenFeatureEventEmitter();\n public readonly runsOn = 'server';\n readonly metadata = {\n name: 'in-memory',\n } as const;\n private _flagConfiguration: FlagConfiguration;\n\n constructor(flagConfiguration: FlagConfiguration = {}) {\n this._flagConfiguration = { ...flagConfiguration };\n }\n\n /**\n * Overwrites the configured flags.\n * @param { FlagConfiguration } flagConfiguration new flag configuration\n */\n putConfiguration(flagConfiguration: FlagConfiguration) {\n const flagsChanged = Object.entries(flagConfiguration)\n .filter(([key, value]) => this._flagConfiguration[key] !== value)\n .map(([key]) => key);\n\n this._flagConfiguration = { ...flagConfiguration };\n this.events.emit(ProviderEvents.ConfigurationChanged, { flagsChanged });\n }\n\n resolveBooleanEvaluation(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<boolean>> {\n return this.resolveFlagWithReason<boolean>(flagKey, defaultValue, context, logger);\n }\n\n resolveNumberEvaluation(\n flagKey: string,\n defaultValue: number,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<number>> {\n return this.resolveFlagWithReason<number>(flagKey, defaultValue, context, logger);\n }\n\n async resolveStringEvaluation(\n flagKey: string,\n defaultValue: string,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<string>> {\n return this.resolveFlagWithReason<string>(flagKey, defaultValue, context, logger);\n }\n\n async resolveObjectEvaluation<T extends JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<T>> {\n return this.resolveFlagWithReason<T>(flagKey, defaultValue, context, logger);\n }\n\n private async resolveFlagWithReason<T extends JsonValue | FlagValueType>(\n flagKey: string,\n defaultValue: T,\n ctx?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<T>> {\n try {\n const resolutionResult = this.lookupFlagValue(flagKey, defaultValue, ctx, logger);\n\n if (typeof resolutionResult?.value != typeof defaultValue) {\n throw new TypeMismatchError();\n }\n\n return resolutionResult;\n } catch (error: unknown) {\n if (!(error instanceof OpenFeatureError)) {\n throw new GeneralError((error as Error)?.message || 'unknown error'); \n }\n throw error;\n }\n }\n\n private lookupFlagValue<T extends JsonValue | FlagValueType>(\n flagKey: string,\n defaultValue: T,\n ctx?: EvaluationContext,\n logger?: Logger,\n ): ResolutionDetails<T> {\n if (!(flagKey in this._flagConfiguration)) {\n const message = `no flag found with key ${flagKey}`;\n logger?.debug(message);\n throw new FlagNotFoundError(message);\n }\n const flagSpec: Flag = this._flagConfiguration[flagKey];\n\n if (flagSpec.disabled) {\n return { value: defaultValue, reason: StandardResolutionReasons.DISABLED };\n }\n\n const isContextEval = ctx && flagSpec?.contextEvaluator;\n const variant = isContextEval ? flagSpec.contextEvaluator?.(ctx) : flagSpec.defaultVariant;\n\n const value = variant && flagSpec?.variants[variant];\n\n if (value === undefined) {\n const message = `no value associated with variant ${variant}`;\n logger?.error(message);\n throw new VariantFoundError(message);\n }\n\n return {\n value: value as T,\n ...(variant && { variant }),\n reason: isContextEval ? StandardResolutionReasons.TARGETING_MATCH : StandardResolutionReasons.STATIC,\n };\n }\n}\n", "import { ErrorCode, OpenFeatureError } from '@openfeature/core';\n\n/**\n * A custom error for the in-memory provider.\n * Indicates the resolved or default variant doesn't exist.\n */\nexport class VariantFoundError extends OpenFeatureError {\n code: ErrorCode;\n constructor(message?: string) {\n super(message);\n Object.setPrototypeOf(this, VariantFoundError.prototype);\n this.name = 'VariantFoundError';\n this.code = ErrorCode.GENERAL;\n }\n}\n", "import type {\n EvaluationContext,\n ManageContext,\n ServerProviderStatus} from '@openfeature/core';\nimport {\n OpenFeatureCommonAPI,\n ProviderWrapper,\n objectOrUndefined,\n stringOrUndefined,\n} from '@openfeature/core';\nimport type { Client } from './client';\nimport { OpenFeatureClient } from './client/internal/open-feature-client';\nimport { OpenFeatureEventEmitter } from './events';\nimport type { Hook } from './hooks';\nimport type { Provider} from './provider';\nimport { NOOP_PROVIDER, ProviderStatus } from './provider';\nimport type {\n ManageTransactionContextPropagator,\n TransactionContext,\n TransactionContextPropagator} from './transaction-context';\nimport {\n NOOP_TRANSACTION_CONTEXT_PROPAGATOR\n} from './transaction-context';\n\n// use a symbol as a key for the global singleton\nconst GLOBAL_OPENFEATURE_API_KEY = Symbol.for('@openfeature/js-sdk/api');\n\ntype OpenFeatureGlobal = {\n [GLOBAL_OPENFEATURE_API_KEY]?: OpenFeatureAPI;\n};\nconst _globalThis = globalThis as OpenFeatureGlobal;\n\nexport class OpenFeatureAPI\n extends OpenFeatureCommonAPI<ServerProviderStatus, Provider, Hook>\n implements\n ManageContext<OpenFeatureAPI>,\n ManageTransactionContextPropagator<OpenFeatureCommonAPI<ServerProviderStatus, Provider>>\n{\n protected _statusEnumType: typeof ProviderStatus = ProviderStatus;\n protected _apiEmitter = new OpenFeatureEventEmitter();\n protected _defaultProvider: ProviderWrapper<Provider, ServerProviderStatus> = new ProviderWrapper(\n NOOP_PROVIDER,\n ProviderStatus.NOT_READY,\n this._statusEnumType,\n );\n protected _domainScopedProviders: Map<string, ProviderWrapper<Provider, ServerProviderStatus>> = new Map();\n protected _createEventEmitter = () => new OpenFeatureEventEmitter();\n\n private _transactionContextPropagator: TransactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;\n\n private constructor() {\n super('server');\n }\n\n /**\n * Gets a singleton instance of the OpenFeature API.\n * @ignore\n * @returns {OpenFeatureAPI} OpenFeature API\n */\n static getInstance(): OpenFeatureAPI {\n const globalApi = _globalThis[GLOBAL_OPENFEATURE_API_KEY];\n if (globalApi) {\n return globalApi;\n }\n\n const instance = new OpenFeatureAPI();\n _globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;\n return instance;\n }\n\n private getProviderStatus(domain?: string): ProviderStatus {\n if (!domain) {\n return this._defaultProvider.status;\n }\n\n return this._domainScopedProviders.get(domain)?.status ?? this._defaultProvider.status;\n }\n\n /**\n * Sets the default provider for flag evaluations and returns a promise that resolves when the provider is ready.\n * This provider will be used by domainless clients and clients associated with domains to which no provider is bound.\n * Setting a provider supersedes the current provider used in new and existing unbound clients.\n * @param {Provider} provider The provider responsible for flag evaluations.\n * @returns {Promise<void>}\n * @throws {Error} If the provider throws an exception during initialization.\n */\n setProviderAndWait(provider: Provider): Promise<void>;\n /**\n * Sets the provider that OpenFeature will use for flag evaluations on clients bound to the same domain.\n * A promise is returned that resolves when the provider is ready.\n * Setting a provider supersedes the current provider used in new and existing clients bound to the same domain.\n * @param {string} domain The name to identify the client\n * @param {Provider} provider The provider responsible for flag evaluations.\n * @returns {Promise<void>}\n * @throws {Error} If the provider throws an exception during initialization.\n */\n setProviderAndWait(domain: string, provider: Provider): Promise<void>;\n async setProviderAndWait(domainOrProvider?: string | Provider, providerOrUndefined?: Provider): Promise<void> {\n const domain = stringOrUndefined(domainOrProvider);\n const provider = domain\n ? objectOrUndefined<Provider>(providerOrUndefined)\n : objectOrUndefined<Provider>(domainOrProvider);\n\n await this.setAwaitableProvider(domain, provider);\n }\n\n /**\n * Sets the default provider for flag evaluations.\n * This provider will be used by domainless clients and clients associated with domains to which no provider is bound.\n * Setting a provider supersedes the current provider used in new and existing unbound clients.\n * @param {Provider} provider The provider responsible for flag evaluations.\n * @returns {this} OpenFeature API\n */\n setProvider(provider: Provider): this;\n /**\n * Sets the provider for flag evaluations of providers with the given name.\n * Setting a provider supersedes the current provider used in new and existing clients bound to the same domain.\n * @param {string} domain The name to identify the client\n * @param {Provider} provider The provider responsible for flag evaluations.\n * @returns {this} OpenFeature API\n */\n setProvider(domain: string, provider: Provider): this;\n setProvider(clientOrProvider?: string | Provider, providerOrUndefined?: Provider): this {\n const domain = stringOrUndefined(clientOrProvider);\n const provider = domain\n ? objectOrUndefined<Provider>(providerOrUndefined)\n : objectOrUndefined<Provider>(clientOrProvider);\n\n const maybePromise = this.setAwaitableProvider(domain, provider);\n\n // The setProvider method doesn't return a promise so we need to catch and\n // log any errors that occur during provider initialization to avoid having\n // an unhandled promise rejection.\n Promise.resolve(maybePromise).catch((err) => {\n this._logger.error('Error during provider initialization:', err);\n });\n\n return this;\n }\n\n /**\n * Get the default provider.\n *\n * Note that it isn't recommended to interact with the provider directly, but rather through\n * an OpenFeature client.\n * @returns {Provider} Default Provider\n */\n getProvider(): Provider;\n /**\n * Get the provider bound to the specified domain.\n *\n * Note that it isn't recommended to interact with the provider directly, but rather through\n * an OpenFeature client.\n * @param {string} domain An identifier which logically binds clients with providers\n * @returns {Provider} Domain-scoped provider\n */\n getProvider(domain?: string): Provider;\n getProvider(domain?: string): Provider {\n return this.getProviderForClient(domain);\n }\n\n setContext(context: EvaluationContext): this {\n this._context = context;\n return this;\n }\n\n getContext(): EvaluationContext {\n return this._context;\n }\n\n /**\n * A factory function for creating new domainless OpenFeature clients.\n * Clients can contain their own state (e.g. logger, hook, context).\n * Multiple clients can be used to segment feature flag configuration.\n *\n * All domainless or unbound clients use the default provider set via {@link this.setProvider setProvider}.\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(context?: EvaluationContext): Client;\n /**\n * A factory function for creating new domain scoped OpenFeature clients.\n * Clients can contain their own state (e.g. logger, hook, context).\n * Multiple clients can be used to segment feature flag configuration.\n *\n * If there is already a provider bound to this domain via {@link this.setProvider setProvider}, this provider will be used.\n * Otherwise, the default provider is used until a provider is assigned to that domain.\n * @param {string} domain An identifier which logically binds clients with providers\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(domain: string, context?: EvaluationContext): Client;\n /**\n * A factory function for creating new domain scoped OpenFeature clients.\n * Clients can contain their own state (e.g. logger, hook, context).\n * Multiple clients can be used to segment feature flag configuration.\n *\n * If there is already a provider bound to this domain via {@link this.setProvider setProvider}, this provider will be used.\n * Otherwise, the default provider is used until a provider is assigned to that domain.\n * @param {string} domain An identifier which logically binds clients with providers\n * @param {string} version The version of the client (only used for metadata)\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(domain: string, version: string, context?: EvaluationContext): Client;\n getClient(\n domainOrContext?: string | EvaluationContext,\n versionOrContext?: string | EvaluationContext,\n contextOrUndefined?: EvaluationContext,\n ): Client {\n const domain = stringOrUndefined(domainOrContext);\n const version = stringOrUndefined(versionOrContext);\n const context =\n objectOrUndefined<EvaluationContext>(domainOrContext) ??\n objectOrUndefined<EvaluationContext>(versionOrContext) ??\n objectOrUndefined<EvaluationContext>(contextOrUndefined);\n\n return new OpenFeatureClient(\n () => this.getProviderForClient(domain),\n () => this.getProviderStatus(domain),\n () => this.buildAndCacheEventEmitterForClient(domain),\n () => this.getContext(),\n () => this.getHooks(),\n () => this.getTransactionContext(),\n () => this._logger,\n { domain, version },\n context,\n );\n }\n\n /**\n * Clears all registered providers and resets the default provider.\n * @returns {Promise<void>}\n */\n clearProviders(): Promise<void> {\n return super.clearProvidersAndSetDefault(NOOP_PROVIDER);\n }\n\n setTransactionContextPropagator(\n transactionContextPropagator: TransactionContextPropagator,\n ): OpenFeatureCommonAPI<ServerProviderStatus, Provider> {\n const baseMessage = 'Invalid TransactionContextPropagator, will not be set: ';\n if (typeof transactionContextPropagator?.getTransactionContext !== 'function') {\n this._logger.error(`${baseMessage}: getTransactionContext is not a function.`);\n } else if (typeof transactionContextPropagator?.setTransactionContext !== 'function') {\n this._logger.error(`${baseMessage}: setTransactionContext is not a function.`);\n } else {\n this._transactionContextPropagator = transactionContextPropagator;\n }\n return this;\n }\n\n setTransactionContext<TArgs extends unknown[], R>(\n transactionContext: TransactionContext,\n callback: (...args: TArgs) => R,\n ...args: TArgs\n ): void {\n this._transactionContextPropagator.setTransactionContext(transactionContext, callback, ...args);\n }\n\n getTransactionContext(): TransactionContext {\n try {\n return this._transactionContextPropagator.getTransactionContext();\n } catch (err: unknown) {\n const error = err as Error | undefined;\n this._logger.error(`Error getting transaction context: ${error?.message}, returning empty context.`);\n this._logger.error(error?.stack);\n return {};\n }\n }\n}\n\n/**\n * A singleton instance of the OpenFeature API.\n * @returns {OpenFeatureAPI} OpenFeature API\n */\nexport const OpenFeature = OpenFeatureAPI.getInstance();\n", "import type {\n ClientMetadata,\n EvaluationContext,\n EvaluationDetails,\n EventHandler,\n FlagValue,\n FlagValueType,\n HookContext,\n JsonValue,\n Logger,\n TrackingEventDetails,\n OpenFeatureError,\n FlagMetadata,\n ResolutionDetails,\n EventOptions,\n} from '@openfeature/core';\nimport {\n ErrorCode,\n ProviderFatalError,\n ProviderNotReadyError,\n SafeLogger,\n StandardResolutionReasons,\n instantiateErrorByErrorCode,\n statusMatchesEvent,\n MapHookData,\n} from '@openfeature/core';\nimport type { FlagEvaluationOptions } from '../../evaluation';\nimport type { ProviderEvents } from '../../events';\nimport type { InternalEventEmitter } from '../../events/internal/internal-event-emitter';\nimport type { Hook } from '../../hooks';\nimport type { Provider } from '../../provider';\nimport { ProviderStatus } from '../../provider';\nimport type { Client } from './../client';\n\ntype OpenFeatureClientOptions = {\n /**\n * @deprecated Use `domain` instead.\n */\n name?: string;\n domain?: string;\n version?: string;\n};\n\n/**\n * This implementation of the {@link Client} is meant to only be instantiated by the SDK.\n * It should not be used outside the SDK and so should not be exported.\n * @internal\n */\nexport class OpenFeatureClient implements Client {\n private _context: EvaluationContext;\n private _hooks: Hook[] = [];\n private _clientLogger?: Logger;\n\n constructor(\n // we always want the client to use the current provider,\n // so pass a function to always access the currently registered one.\n private readonly providerAccessor: () => Provider,\n private readonly providerStatusAccessor: () => ProviderStatus,\n private readonly emitterAccessor: () => InternalEventEmitter,\n private readonly apiContextAccessor: () => EvaluationContext,\n private readonly apiHooksAccessor: () => Hook[],\n private readonly transactionContextAccessor: () => EvaluationContext,\n private readonly globalLogger: () => Logger,\n private readonly options: OpenFeatureClientOptions,\n context: EvaluationContext = {},\n ) {\n this._context = context;\n }\n\n get metadata(): ClientMetadata {\n return {\n // Use domain if name is not provided\n name: this.options.domain ?? this.options.name,\n domain: this.options.domain ?? this.options.name,\n version: this.options.version,\n providerMetadata: this.providerAccessor().metadata,\n };\n }\n\n get providerStatus(): ProviderStatus {\n return this.providerStatusAccessor();\n }\n\n addHandler(eventType: ProviderEvents, handler: EventHandler, options?: EventOptions): void {\n this.emitterAccessor().addHandler(eventType, handler);\n const shouldRunNow = statusMatchesEvent(eventType, this._providerStatus);\n\n if (shouldRunNow) {\n // run immediately, we're in the matching state\n try {\n handler({\n clientName: this.metadata.name,\n domain: this.metadata.domain,\n providerName: this._provider.metadata.name,\n });\n } catch (err) {\n this._logger?.error('Error running event handler:', err);\n }\n }\n\n if (options?.signal && typeof options.signal.addEventListener === 'function') {\n options.signal.addEventListener('abort', () => {\n this.removeHandler(eventType, handler);\n });\n }\n }\n\n removeHandler(eventType: ProviderEvents, handler: EventHandler) {\n this.emitterAccessor().removeHandler(eventType, handler);\n }\n\n getHandlers(eventType: ProviderEvents) {\n return this.emitterAccessor().getHandlers(eventType);\n }\n\n setLogger(logger: Logger): OpenFeatureClient {\n this._clientLogger = new SafeLogger(logger);\n return this;\n }\n\n setContext(context: EvaluationContext): OpenFeatureClient {\n this._context = context;\n return this;\n }\n\n getContext(): EvaluationContext {\n return this._context;\n }\n\n addHooks(...hooks: Hook[]): OpenFeatureClient {\n this._hooks = [...this._hooks, ...hooks];\n return this;\n }\n\n getHooks(): Hook[] {\n return this._hooks;\n }\n\n clearHooks(): OpenFeatureClient {\n this._hooks = [];\n return this;\n }\n\n async getBooleanValue(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<boolean> {\n return (await this.getBooleanDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getBooleanDetails(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<boolean>> {\n return this.evaluate<boolean>(\n flagKey,\n this._provider.resolveBooleanEvaluation,\n defaultValue,\n 'boolean',\n context,\n options,\n );\n }\n\n async getStringValue<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getStringDetails<T>(flagKey, defaultValue, context, options)).value;\n }\n\n getStringDetails<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(\n flagKey,\n // this isolates providers from our restricted string generic argument.\n this._provider.resolveStringEvaluation as () => Promise<EvaluationDetails<T>>,\n defaultValue,\n 'string',\n context,\n options,\n );\n }\n\n async getNumberValue<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getNumberDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getNumberDetails<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(\n flagKey,\n // this isolates providers from our restricted number generic argument.\n this._provider.resolveNumberEvaluation as () => Promise<EvaluationDetails<T>>,\n defaultValue,\n 'number',\n context,\n options,\n );\n }\n\n async getObjectValue<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getObjectDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getObjectDetails<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(flagKey, this._provider.resolveObjectEvaluation, defaultValue, 'object', context, options);\n }\n\n track(occurrenceKey: string, context: EvaluationContext = {}, occurrenceDetails: TrackingEventDetails = {}): void {\n try {\n this.shortCircuitIfNotReady();\n\n if (typeof this._provider.track === 'function') {\n // freeze the merged context\n const frozenContext = Object.freeze(this.mergeContexts(context));\n return this._provider.track?.(occurrenceKey, frozenContext, occurrenceDetails);\n } else {\n this._logger.debug('Provider does not support the track function; will no-op.');\n }\n } catch (err) {\n this._logger.debug('Error recording tracking event.', err);\n }\n }\n\n private async evaluate<T extends FlagValue>(\n flagKey: string,\n resolver: (\n flagKey: string,\n defaultValue: T,\n context: EvaluationContext,\n logger: Logger,\n ) => Promise<ResolutionDetails<T>>,\n defaultValue: T,\n flagType: FlagValueType,\n invocationContext: EvaluationContext = {},\n options: FlagEvaluationOptions = {},\n ): Promise<EvaluationDetails<T>> {\n // merge global, client, and evaluation context\n\n const allHooks = [\n ...this.apiHooksAccessor(),\n ...this.getHooks(),\n ...(options.hooks || []),\n ...(this._provider.hooks || []),\n ];\n const allHooksReversed = [...allHooks].reverse();\n\n const mergedContext = this.mergeContexts(invocationContext);\n\n // Create hook context instances for each hook (stable object references for the entire evaluation)\n // This ensures hooks can use WeakMaps with hookContext as keys across lifecycle methods\n // NOTE: Uses the reversed order to reduce the number of times we have to calculate the index.\n const hookContexts = allHooksReversed.map<HookContext>(() =>\n Object.freeze({\n flagKey,\n defaultValue,\n flagValueType: flagType,\n clientMetadata: this.metadata,\n providerMetadata: this._provider.metadata,\n context: mergedContext,\n logger: this._logger,\n hookData: new MapHookData(),\n }),\n );\n\n let evaluationDetails: EvaluationDetails<T>;\n\n try {\n const frozenContext = await this.beforeHooks(allHooks, hookContexts, mergedContext, options);\n\n this.shortCircuitIfNotReady();\n\n // run the referenced resolver, binding the provider.\n const resolution = await resolver.call(this._provider, flagKey, defaultValue, frozenContext, this._logger);\n\n const resolutionDetails = {\n ...resolution,\n flagMetadata: Object.freeze(resolution.flagMetadata ?? {}),\n flagKey,\n };\n\n if (resolutionDetails.errorCode) {\n const err = instantiateErrorByErrorCode(resolutionDetails.errorCode, resolutionDetails.errorMessage);\n await this.errorHooks(allHooksReversed, hookContexts, err, options);\n evaluationDetails = this.getErrorEvaluationDetails(flagKey, defaultValue, err, resolutionDetails.flagMetadata);\n } else {\n await this.afterHooks(allHooksReversed, hookContexts, resolutionDetails, options);\n evaluationDetails = resolutionDetails;\n }\n } catch (err: unknown) {\n await this.errorHooks(allHooksReversed, hookContexts, err, options);\n evaluationDetails = this.getErrorEvaluationDetails(flagKey, defaultValue, err);\n }\n\n await this.finallyHooks(allHooksReversed, hookContexts, evaluationDetails, options);\n return evaluationDetails;\n }\n\n private async beforeHooks(\n hooks: Hook[],\n hookContexts: HookContext[],\n mergedContext: EvaluationContext,\n options: FlagEvaluationOptions,\n ) {\n let accumulatedContext = mergedContext;\n\n for (const [index, hook] of hooks.entries()) {\n const hookContextIndex = hooks.length - 1 - index; // reverse index for before hooks\n const hookContext = hookContexts[hookContextIndex];\n\n // Update the context on the stable hook context object\n Object.assign(hookContext.context, accumulatedContext);\n\n const hookResult = await hook?.before?.(hookContext, Object.freeze(options.hookHints));\n if (hookResult) {\n accumulatedContext = {\n ...accumulatedContext,\n ...hookResult,\n };\n\n for (let i = 0; i < hooks.length; i++) {\n Object.assign(hookContexts[hookContextIndex].context, accumulatedContext);\n }\n }\n }\n\n // after before hooks, freeze the EvaluationContext.\n return Object.freeze(accumulatedContext);\n }\n\n private async afterHooks(\n hooks: Hook[],\n hookContexts: HookContext[],\n evaluationDetails: EvaluationDetails<FlagValue>,\n options: FlagEvaluationOptions,\n ) {\n // run \"after\" hooks sequentially\n for (const [index, hook] of hooks.entries()) {\n const hookContext = hookContexts[index];\n await hook?.after?.(hookContext, evaluationDetails, options.hookHints);\n }\n }\n\n private async errorHooks(hooks: Hook[], hookContexts: HookContext[], err: unknown, options: FlagEvaluationOptions) {\n // run \"error\" hooks sequentially\n for (const [index, hook] of hooks.entries()) {\n try {\n const hookContext = hookContexts[index];\n await hook?.error?.(hookContext, err, options.hookHints);\n } catch (err) {\n this._logger.error(`Unhandled error during 'error' hook: ${err}`);\n if (err instanceof Error) {\n this._logger.error(err.stack);\n }\n this._logger.error((err as Error)?.stack);\n }\n }\n }\n\n private async finallyHooks(\n hooks: Hook[],\n hookContexts: HookContext[],\n evaluationDetails: EvaluationDetails<FlagValue>,\n options: FlagEvaluationOptions,\n ) {\n // run \"finally\" hooks sequentially\n for (const [index, hook] of hooks.entries()) {\n try {\n const hookContext = hookContexts[index];\n await hook?.finally?.(hookContext, evaluationDetails, options.hookHints);\n } catch (err) {\n this._logger.error(`Unhandled error during 'finally' hook: ${err}`);\n if (err instanceof Error) {\n this._logger.error(err.stack);\n }\n this._logger.error((err as Error)?.stack);\n }\n }\n }\n\n private get _provider(): Provider {\n return this.providerAccessor();\n }\n\n private get _providerStatus(): ProviderStatus {\n return this.providerStatusAccessor();\n }\n\n private get _logger() {\n return this._clientLogger || this.globalLogger();\n }\n\n private mergeContexts(invocationContext: EvaluationContext) {\n // merge global and client contexts\n return {\n ...this.apiContextAccessor(),\n ...this.transactionContextAccessor(),\n ...this._context,\n ...invocationContext,\n };\n }\n\n private shortCircuitIfNotReady() {\n // short circuit evaluation entirely if provider is in a bad state\n if (this.providerStatus === ProviderStatus.NOT_READY) {\n throw new ProviderNotReadyError('provider has not yet initialized');\n } else if (this.providerStatus === ProviderStatus.FATAL) {\n throw new ProviderFatalError('provider is in an irrecoverable error state');\n }\n }\n\n private getErrorEvaluationDetails<T extends FlagValue>(\n flagKey: string,\n defaultValue: T,\n err: unknown,\n flagMetadata: FlagMetadata = {},\n ): EvaluationDetails<T> {\n const errorMessage: string = (err as Error)?.message;\n const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;\n\n return {\n errorCode,\n errorMessage,\n value: defaultValue,\n reason: StandardResolutionReasons.ERROR,\n flagMetadata: Object.freeze(flagMetadata),\n flagKey,\n };\n }\n}\n", "import { GenericEventEmitter } from '@openfeature/core';\nimport { EventEmitter } from 'node:events';\nimport type { ProviderEvents } from './events';\n\n/**\n * The OpenFeatureEventEmitter can be used by provider developers to emit\n * events at various parts of the provider lifecycle.\n * \n * NOTE: Ready and error events are automatically emitted by the SDK based on\n * the result of the initialize method.\n */\nexport class OpenFeatureEventEmitter extends GenericEventEmitter<ProviderEvents> {\n protected readonly eventEmitter = new EventEmitter({ captureRejections: true });\n\n constructor() {\n super();\n this.eventEmitter.on('error', (err) => {\n this._logger?.error('Error running event handler:', err);\n });\n }\n};", "import { ServerProviderEvents } from '@openfeature/core';\n\nexport { ServerProviderEvents as ProviderEvents };", "import type { EvaluationContext } from '@openfeature/core';\nimport type { TransactionContext, TransactionContextPropagator } from './transaction-context';\n\nclass NoopTransactionContextPropagator implements TransactionContextPropagator {\n getTransactionContext(): EvaluationContext {\n return {};\n }\n\n setTransactionContext<TArgs extends unknown[], R>(\n _: TransactionContext,\n callback: (...args: TArgs) => R,\n ...args: TArgs\n ): void {\n callback(...args);\n }\n}\n\nexport const NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();\n", "import type { EvaluationContext } from '@openfeature/core';\nimport type { TransactionContext, TransactionContextPropagator } from './transaction-context';\nimport { AsyncLocalStorage } from 'async_hooks';\n\nexport class AsyncLocalStorageTransactionContextPropagator implements TransactionContextPropagator {\n private asyncLocalStorage = new AsyncLocalStorage<EvaluationContext>();\n\n getTransactionContext(): EvaluationContext {\n return this.asyncLocalStorage.getStore() ?? {};\n }\n\n setTransactionContext<TArgs extends unknown[], R>(\n transactionContext: TransactionContext,\n callback: (...args: TArgs) => R,\n ...args: TArgs\n ): void {\n this.asyncLocalStorage.run(transactionContext, callback, ...args);\n }\n}\n", "export * from './client';\nexport * from './provider';\nexport * from './evaluation';\nexport * from './open-feature';\nexport * from './transaction-context';\nexport * from './events';\nexport * from './hooks';\nexport * from './tracking';\nexport * from '@openfeature/core';\n"],
5
- "mappings": "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",
6
- "names": ["OpenFeatureError", "OpenFeatureError", "ErrorCode", "StandardResolutionReasons", "err", "ErrorCode", "StandardResolutionReasons"]
3
+ "sources": ["../../src/provider/provider.ts", "../../src/provider/no-op-provider.ts", "../../src/provider/in-memory-provider/in-memory-provider.ts", "../../src/provider/in-memory-provider/variant-not-found-error.ts", "../../src/provider/multi-provider/multi-provider.ts", "../../src/events/open-feature-event-emitter.ts", "../../src/provider/multi-provider/errors.ts", "../../src/provider/multi-provider/hook-executor.ts", "../../src/events/events.ts", "../../src/provider/multi-provider/status-tracker.ts", "../../src/provider/multi-provider/strategies/base-evaluation-strategy.ts", "../../src/provider/multi-provider/strategies/first-match-strategy.ts", "../../src/provider/multi-provider/strategies/first-successful-strategy.ts", "../../src/provider/multi-provider/strategies/comparison-strategy.ts", "../../src/open-feature.ts", "../../src/client/internal/open-feature-client.ts", "../../src/transaction-context/no-op-transaction-context-propagator.ts", "../../src/transaction-context/async-local-storage-transaction-context-propagator.ts", "../../src/index.ts"],
4
+ "sourcesContent": ["import type {\n CommonProvider,\n EvaluationContext,\n JsonValue,\n Logger,\n ResolutionDetails} from '@openfeature/core';\nimport {\n ServerProviderStatus,\n} from '@openfeature/core';\nimport type { Hook } from '../hooks';\n\nexport { ServerProviderStatus as ProviderStatus };\n\n/**\n * Interface that providers must implement to resolve flag values for their particular\n * backend or vendor.\n *\n * Implementation for resolving all the required flag types must be defined.\n */\nexport interface Provider extends CommonProvider<ServerProviderStatus> {\n /**\n * A provider hook exposes a mechanism for provider authors to register hooks\n * to tap into various stages of the flag evaluation lifecycle. These hooks can\n * be used to perform side effects and mutate the context for purposes of the\n * provider. Provider hooks are not configured or controlled by the application author.\n */\n readonly hooks?: Hook[];\n\n /**\n * Resolve a boolean flag and its evaluation details.\n */\n resolveBooleanEvaluation(\n flagKey: string,\n defaultValue: boolean,\n context: EvaluationContext,\n logger: Logger,\n ): Promise<ResolutionDetails<boolean>>;\n\n /**\n * Resolve a string flag and its evaluation details.\n */\n resolveStringEvaluation(\n flagKey: string,\n defaultValue: string,\n context: EvaluationContext,\n logger: Logger,\n ): Promise<ResolutionDetails<string>>;\n\n /**\n * Resolve a numeric flag and its evaluation details.\n */\n resolveNumberEvaluation(\n flagKey: string,\n defaultValue: number,\n context: EvaluationContext,\n logger: Logger,\n ): Promise<ResolutionDetails<number>>;\n\n /**\n * Resolve and parse an object flag and its evaluation details.\n */\n resolveObjectEvaluation<T extends JsonValue>(\n flagKey: string,\n defaultValue: T,\n context: EvaluationContext,\n logger: Logger,\n ): Promise<ResolutionDetails<T>>;\n}\n", "import type { JsonValue, ResolutionDetails } from '@openfeature/core';\nimport type { Provider } from './provider';\n\nconst REASON_NO_OP = 'No-op';\n\n/**\n * The No-op provider is set by default, and simply always returns the default value.\n */\nclass NoopFeatureProvider implements Provider {\n readonly metadata = {\n name: 'No-op Provider',\n } as const;\n\n resolveBooleanEvaluation(_: string, defaultValue: boolean): Promise<ResolutionDetails<boolean>> {\n return this.noOp(defaultValue);\n }\n\n resolveStringEvaluation(_: string, defaultValue: string): Promise<ResolutionDetails<string>> {\n return this.noOp(defaultValue);\n }\n\n resolveNumberEvaluation(_: string, defaultValue: number): Promise<ResolutionDetails<number>> {\n return this.noOp(defaultValue);\n }\n\n resolveObjectEvaluation<T extends JsonValue>(_: string, defaultValue: T): Promise<ResolutionDetails<T>> {\n return this.noOp<T>(defaultValue);\n }\n\n private noOp<T>(defaultValue: T) {\n return Promise.resolve({\n value: defaultValue,\n reason: REASON_NO_OP,\n });\n }\n}\n\nexport const NOOP_PROVIDER = new NoopFeatureProvider();\n", "import type {\n EvaluationContext,\n FlagValueType,\n JsonValue,\n Logger,\n ResolutionDetails} from '@openfeature/core';\nimport {\n FlagNotFoundError,\n GeneralError,\n OpenFeatureError,\n StandardResolutionReasons,\n TypeMismatchError\n} from '@openfeature/core';\nimport type { Provider } from '../provider';\nimport type { Flag, FlagConfiguration } from './flag-configuration';\nimport { VariantFoundError } from './variant-not-found-error';\nimport { OpenFeatureEventEmitter, ProviderEvents } from '../..';\n\n/**\n * A simple OpenFeature provider intended for demos and as a test stub.\n */\nexport class InMemoryProvider implements Provider {\n public readonly events = new OpenFeatureEventEmitter();\n public readonly runsOn = 'server';\n readonly metadata = {\n name: 'in-memory',\n } as const;\n private _flagConfiguration: FlagConfiguration;\n\n constructor(flagConfiguration: FlagConfiguration = {}) {\n this._flagConfiguration = { ...flagConfiguration };\n }\n\n /**\n * Overwrites the configured flags.\n * @param { FlagConfiguration } flagConfiguration new flag configuration\n */\n putConfiguration(flagConfiguration: FlagConfiguration) {\n const flagsChanged = Object.entries(flagConfiguration)\n .filter(([key, value]) => this._flagConfiguration[key] !== value)\n .map(([key]) => key);\n\n this._flagConfiguration = { ...flagConfiguration };\n this.events.emit(ProviderEvents.ConfigurationChanged, { flagsChanged });\n }\n\n resolveBooleanEvaluation(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<boolean>> {\n return this.resolveFlagWithReason<boolean>(flagKey, defaultValue, context, logger);\n }\n\n resolveNumberEvaluation(\n flagKey: string,\n defaultValue: number,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<number>> {\n return this.resolveFlagWithReason<number>(flagKey, defaultValue, context, logger);\n }\n\n async resolveStringEvaluation(\n flagKey: string,\n defaultValue: string,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<string>> {\n return this.resolveFlagWithReason<string>(flagKey, defaultValue, context, logger);\n }\n\n async resolveObjectEvaluation<T extends JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<T>> {\n return this.resolveFlagWithReason<T>(flagKey, defaultValue, context, logger);\n }\n\n private async resolveFlagWithReason<T extends JsonValue | FlagValueType>(\n flagKey: string,\n defaultValue: T,\n ctx?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<T>> {\n try {\n const resolutionResult = this.lookupFlagValue(flagKey, defaultValue, ctx, logger);\n\n if (typeof resolutionResult?.value != typeof defaultValue) {\n throw new TypeMismatchError();\n }\n\n return resolutionResult;\n } catch (error: unknown) {\n if (!(error instanceof OpenFeatureError)) {\n throw new GeneralError((error as Error)?.message || 'unknown error'); \n }\n throw error;\n }\n }\n\n private lookupFlagValue<T extends JsonValue | FlagValueType>(\n flagKey: string,\n defaultValue: T,\n ctx?: EvaluationContext,\n logger?: Logger,\n ): ResolutionDetails<T> {\n if (!(flagKey in this._flagConfiguration)) {\n const message = `no flag found with key ${flagKey}`;\n logger?.debug(message);\n throw new FlagNotFoundError(message);\n }\n const flagSpec: Flag = this._flagConfiguration[flagKey];\n\n if (flagSpec.disabled) {\n return { value: defaultValue, reason: StandardResolutionReasons.DISABLED };\n }\n\n const isContextEval = ctx && flagSpec?.contextEvaluator;\n const variant = isContextEval ? flagSpec.contextEvaluator?.(ctx) : flagSpec.defaultVariant;\n\n const value = variant && flagSpec?.variants[variant];\n\n if (value === undefined) {\n const message = `no value associated with variant ${variant}`;\n logger?.error(message);\n throw new VariantFoundError(message);\n }\n\n return {\n value: value as T,\n ...(variant && { variant }),\n reason: isContextEval ? StandardResolutionReasons.TARGETING_MATCH : StandardResolutionReasons.STATIC,\n };\n }\n}\n", "import { ErrorCode, OpenFeatureError } from '@openfeature/core';\n\n/**\n * A custom error for the in-memory provider.\n * Indicates the resolved or default variant doesn't exist.\n */\nexport class VariantFoundError extends OpenFeatureError {\n code: ErrorCode;\n constructor(message?: string) {\n super(message);\n Object.setPrototypeOf(this, VariantFoundError.prototype);\n this.name = 'VariantFoundError';\n this.code = ErrorCode.GENERAL;\n }\n}\n", "import type {\n BeforeHookContext,\n EvaluationContext,\n EvaluationDetails,\n FlagMetadata,\n FlagValue,\n FlagValueType,\n HookContext,\n HookHints,\n JsonValue,\n Logger,\n OpenFeatureError,\n ProviderMetadata,\n ResolutionDetails,\n TrackingEventDetails,\n} from '@openfeature/core';\nimport { DefaultLogger, ErrorCode, GeneralError, StandardResolutionReasons } from '@openfeature/core';\nimport type { Provider } from '../provider';\nimport type { Hook } from '../../hooks';\nimport { OpenFeatureEventEmitter } from '../../events/open-feature-event-emitter';\nimport { constructAggregateError, throwAggregateErrorFromPromiseResults } from './errors';\nimport { HookExecutor } from './hook-executor';\nimport { StatusTracker } from './status-tracker';\nimport type { BaseEvaluationStrategy, ProviderResolutionResult } from './strategies';\nimport { FirstMatchStrategy } from './strategies';\nimport type { ProviderEntryInput, RegisteredProvider } from './types';\n\nexport class MultiProvider implements Provider {\n readonly runsOn = 'server';\n\n public readonly events = new OpenFeatureEventEmitter();\n\n private hookContexts: WeakMap<EvaluationContext, HookContext> = new WeakMap<EvaluationContext, HookContext>();\n private hookHints: WeakMap<EvaluationContext, HookHints> = new WeakMap<EvaluationContext, HookHints>();\n\n metadata: ProviderMetadata;\n\n providerEntries: RegisteredProvider[] = [];\n private providerEntriesByName: Record<string, RegisteredProvider> = {};\n\n private hookExecutor: HookExecutor;\n private statusTracker = new StatusTracker(this.events);\n\n constructor(\n readonly constructorProviders: ProviderEntryInput[],\n private readonly evaluationStrategy: BaseEvaluationStrategy = new FirstMatchStrategy(),\n private readonly logger: Logger = new DefaultLogger(),\n ) {\n this.hookExecutor = new HookExecutor(this.logger);\n\n this.registerProviders(constructorProviders);\n\n const aggregateMetadata = Object.keys(this.providerEntriesByName).reduce((acc, name) => {\n return { ...acc, [name]: this.providerEntriesByName[name].provider.metadata };\n }, {});\n\n this.metadata = {\n ...aggregateMetadata,\n name: MultiProvider.name,\n };\n }\n\n private registerProviders(constructorProviders: ProviderEntryInput[]) {\n const providersByName: Record<string, Provider[]> = {};\n\n for (const constructorProvider of constructorProviders) {\n const providerName = constructorProvider.provider.metadata.name;\n const candidateName = constructorProvider.name ?? providerName;\n\n if (constructorProvider.name && providersByName[constructorProvider.name]) {\n throw new Error('Provider names must be unique');\n }\n\n providersByName[candidateName] ??= [];\n providersByName[candidateName].push(constructorProvider.provider);\n }\n\n for (const name of Object.keys(providersByName)) {\n const useIndexedNames = providersByName[name].length > 1;\n for (let i = 0; i < providersByName[name].length; i++) {\n const indexedName = useIndexedNames ? `${name}-${i + 1}` : name;\n this.providerEntriesByName[indexedName] = { provider: providersByName[name][i], name: indexedName };\n this.providerEntries.push(this.providerEntriesByName[indexedName]);\n this.statusTracker.wrapEventHandler(this.providerEntriesByName[indexedName]);\n }\n }\n\n // just make sure we don't accidentally modify these later\n Object.freeze(this.providerEntries);\n Object.freeze(this.providerEntriesByName);\n }\n\n async initialize(context?: EvaluationContext): Promise<void> {\n const result = await Promise.allSettled(\n this.providerEntries.map((provider) => provider.provider.initialize?.(context)),\n );\n throwAggregateErrorFromPromiseResults(result, this.providerEntries);\n }\n\n async onClose(): Promise<void> {\n const result = await Promise.allSettled(this.providerEntries.map((provider) => provider.provider.onClose?.()));\n throwAggregateErrorFromPromiseResults(result, this.providerEntries);\n }\n\n resolveBooleanEvaluation(\n flagKey: string,\n defaultValue: boolean,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<boolean>> {\n return this.flagResolutionProxy<boolean>(flagKey, 'boolean', defaultValue, context);\n }\n\n resolveStringEvaluation(\n flagKey: string,\n defaultValue: string,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<string>> {\n return this.flagResolutionProxy(flagKey, 'string', defaultValue, context);\n }\n\n resolveNumberEvaluation(\n flagKey: string,\n defaultValue: number,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<number>> {\n return this.flagResolutionProxy(flagKey, 'number', defaultValue, context);\n }\n\n resolveObjectEvaluation<U extends JsonValue>(\n flagKey: string,\n defaultValue: U,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<U>> {\n return this.flagResolutionProxy(flagKey, 'object', defaultValue, context);\n }\n\n private async flagResolutionProxy<T extends boolean | string | number | JsonValue>(\n flagKey: string,\n flagType: FlagValueType,\n defaultValue: T,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<T>> {\n const hookContext = this.hookContexts.get(context);\n const hookHints = this.hookHints.get(context);\n\n if (!hookContext || !hookHints) {\n throw new GeneralError('Hook context not available for evaluation');\n }\n\n const tasks: Promise<[boolean, ProviderResolutionResult<T> | null]>[] = [];\n\n for (const providerEntry of this.providerEntries) {\n const task = this.evaluateProviderEntry(\n flagKey,\n flagType,\n defaultValue,\n providerEntry,\n hookContext,\n hookHints,\n context,\n );\n\n tasks.push(task);\n\n if (this.evaluationStrategy.runMode === 'sequential') {\n const [shouldEvaluateNext] = await task;\n if (!shouldEvaluateNext) {\n break;\n }\n }\n }\n\n const results = await Promise.all(tasks);\n const resolutions = results\n .map(([, resolution]) => resolution)\n .filter((r): r is ProviderResolutionResult<T> => Boolean(r));\n\n const finalResult = this.evaluationStrategy.determineFinalResult({ flagKey, flagType }, context, resolutions);\n\n if (finalResult.errors?.length) {\n throw constructAggregateError(finalResult.errors);\n }\n\n if (!finalResult.details) {\n throw new GeneralError('No result was returned from any provider');\n }\n\n return finalResult.details;\n }\n\n private async evaluateProviderEntry<T extends boolean | string | number | JsonValue>(\n flagKey: string,\n flagType: FlagValueType,\n defaultValue: T,\n providerEntry: RegisteredProvider,\n hookContext: HookContext,\n hookHints: HookHints,\n context: EvaluationContext,\n ): Promise<[boolean, ProviderResolutionResult<T> | null]> {\n let evaluationResult: ResolutionDetails<T> | undefined = undefined;\n const provider = providerEntry.provider;\n const strategyContext = {\n flagKey,\n flagType,\n provider,\n providerName: providerEntry.name,\n providerStatus: this.statusTracker.providerStatus(providerEntry.name),\n };\n\n if (!this.evaluationStrategy.shouldEvaluateThisProvider(strategyContext, context)) {\n return [true, null];\n }\n\n let resolution: ProviderResolutionResult<T>;\n\n try {\n evaluationResult = await this.evaluateProviderAndHooks(flagKey, defaultValue, provider, hookContext, hookHints);\n resolution = {\n details: evaluationResult,\n provider: provider,\n providerName: providerEntry.name,\n };\n } catch (error: unknown) {\n resolution = {\n thrownError: error,\n provider: provider,\n providerName: providerEntry.name,\n };\n }\n\n return [\n this.evaluationStrategy.runMode === 'sequential'\n ? this.evaluationStrategy.shouldEvaluateNextProvider(strategyContext, context, resolution)\n : true,\n resolution,\n ];\n }\n\n private async evaluateProviderAndHooks<T extends boolean | string | number | JsonValue>(\n flagKey: string,\n defaultValue: T,\n provider: Provider,\n hookContext: HookContext,\n hookHints: HookHints,\n ) {\n let providerContext: EvaluationContext | undefined = undefined;\n let evaluationDetails: EvaluationDetails<T>;\n\n // create a copy of the shared hook context because we're going to mutate the evaluation context\n const hookContextCopy = { ...hookContext, context: { ...hookContext.context } };\n\n try {\n // return the modified provider context and mutate the hook context to contain it\n providerContext = await this.hookExecutor.beforeHooks(provider.hooks, hookContextCopy, hookHints);\n\n const resolutionDetails = (await this.callProviderResolve(\n provider,\n flagKey,\n defaultValue,\n providerContext || {},\n )) as ResolutionDetails<T>;\n\n evaluationDetails = {\n ...resolutionDetails,\n flagMetadata: Object.freeze(resolutionDetails.flagMetadata ?? {}),\n flagKey,\n };\n\n await this.hookExecutor.afterHooks(provider.hooks, hookContextCopy, evaluationDetails, hookHints);\n } catch (error: unknown) {\n await this.hookExecutor.errorHooks(provider.hooks, hookContextCopy, error, hookHints);\n evaluationDetails = this.getErrorEvaluationDetails(flagKey, defaultValue, error);\n }\n await this.hookExecutor.finallyHooks(provider.hooks, hookContextCopy, evaluationDetails, hookHints);\n return evaluationDetails;\n }\n\n private async callProviderResolve<T extends boolean | string | number | JsonValue>(\n provider: Provider,\n flagKey: string,\n defaultValue: T,\n context: EvaluationContext,\n ) {\n switch (typeof defaultValue) {\n case 'string':\n return await provider.resolveStringEvaluation(flagKey, defaultValue, context, this.logger);\n case 'number':\n return await provider.resolveNumberEvaluation(flagKey, defaultValue, context, this.logger);\n case 'object':\n return await provider.resolveObjectEvaluation(flagKey, defaultValue, context, this.logger);\n case 'boolean':\n return await provider.resolveBooleanEvaluation(flagKey, defaultValue, context, this.logger);\n default:\n throw new GeneralError('Invalid flag evaluation type');\n }\n }\n\n public get hooks(): Hook[] {\n return [\n {\n before: async (hookContext: BeforeHookContext, hints: HookHints): Promise<EvaluationContext> => {\n this.hookContexts.set(hookContext.context, hookContext);\n this.hookHints.set(hookContext.context, hints ?? {});\n return hookContext.context;\n },\n },\n ];\n }\n\n track(trackingEventName: string, context: EvaluationContext, trackingEventDetails: TrackingEventDetails): void {\n for (const providerEntry of this.providerEntries) {\n if (!providerEntry.provider.track) {\n continue;\n }\n\n const strategyContext = {\n provider: providerEntry.provider,\n providerName: providerEntry.name,\n providerStatus: this.statusTracker.providerStatus(providerEntry.name),\n };\n\n if (\n this.evaluationStrategy.shouldTrackWithThisProvider(\n strategyContext,\n context,\n trackingEventName,\n trackingEventDetails,\n )\n ) {\n try {\n providerEntry.provider.track?.(trackingEventName, context, trackingEventDetails);\n } catch (error) {\n // Log error but don't throw - tracking shouldn't break application flow\n this.logger.error(\n `Error tracking event \"${trackingEventName}\" with provider \"${providerEntry.name}\":`,\n error,\n );\n }\n }\n }\n }\n\n private getErrorEvaluationDetails<T extends FlagValue>(\n flagKey: string,\n defaultValue: T,\n err: unknown,\n flagMetadata: FlagMetadata = {},\n ): EvaluationDetails<T> {\n const errorMessage: string = (err as Error)?.message;\n const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;\n\n return {\n errorCode,\n errorMessage,\n value: defaultValue,\n reason: StandardResolutionReasons.ERROR,\n flagMetadata: Object.freeze(flagMetadata),\n flagKey,\n };\n }\n}\n", "import { GenericEventEmitter } from '@openfeature/core';\nimport { EventEmitter } from 'node:events';\nimport type { ProviderEvents } from './events';\n\n/**\n * The OpenFeatureEventEmitter can be used by provider developers to emit\n * events at various parts of the provider lifecycle.\n * \n * NOTE: Ready and error events are automatically emitted by the SDK based on\n * the result of the initialize method.\n */\nexport class OpenFeatureEventEmitter extends GenericEventEmitter<ProviderEvents> {\n protected readonly eventEmitter = new EventEmitter({ captureRejections: true });\n\n constructor() {\n super();\n this.eventEmitter.on('error', (err) => {\n this._logger?.error('Error running event handler:', err);\n });\n }\n};", "import type { ErrorCode } from '@openfeature/core';\nimport { GeneralError, OpenFeatureError } from '@openfeature/core';\nimport type { RegisteredProvider } from './types';\n\nexport class ErrorWithCode extends OpenFeatureError {\n constructor(\n public code: ErrorCode,\n message: string,\n ) {\n super(message);\n }\n}\n\nexport class AggregateError extends GeneralError {\n constructor(\n message: string,\n public originalErrors: { source: string; error: unknown }[],\n ) {\n super(message);\n }\n}\n\nexport const constructAggregateError = (providerErrors: { error: unknown; providerName: string }[]) => {\n const errorsWithSource = providerErrors\n .map(({ providerName, error }) => {\n return { source: providerName, error };\n })\n .flat();\n\n // log first error in the message for convenience, but include all errors in the error object for completeness\n return new AggregateError(\n `Provider errors occurred: ${errorsWithSource[0].source}: ${errorsWithSource[0].error}`,\n errorsWithSource,\n );\n};\n\nexport const throwAggregateErrorFromPromiseResults = (\n result: PromiseSettledResult<unknown>[],\n providerEntries: RegisteredProvider[],\n) => {\n const errors = result\n .map((r, i) => {\n if (r.status === 'rejected') {\n return { error: r.reason, providerName: providerEntries[i].name };\n }\n return null;\n })\n .filter((val): val is { error: unknown; providerName: string } => Boolean(val));\n\n if (errors.length) {\n throw constructAggregateError(errors);\n }\n};\n", "import type { EvaluationDetails, FlagValue, HookContext, HookHints, Logger } from '@openfeature/core';\nimport type { Hook } from '../../hooks';\n\n/**\n * Utility for executing a set of hooks of each type. Implementation is largely copied from the main OpenFeature SDK.\n */\nexport class HookExecutor {\n constructor(private logger: Logger) {}\n\n async beforeHooks(hooks: Hook[] | undefined, hookContext: HookContext, hints: HookHints) {\n for (const hook of hooks ?? []) {\n // freeze the hookContext\n Object.freeze(hookContext);\n\n Object.assign(hookContext.context, {\n ...(await hook?.before?.(hookContext, Object.freeze(hints))),\n });\n }\n\n // after before hooks, freeze the EvaluationContext.\n return Object.freeze(hookContext.context);\n }\n\n async afterHooks(\n hooks: Hook[] | undefined,\n hookContext: HookContext,\n evaluationDetails: EvaluationDetails<FlagValue>,\n hints: HookHints,\n ) {\n // run \"after\" hooks sequentially\n for (const hook of hooks ?? []) {\n await hook?.after?.(hookContext, evaluationDetails, hints);\n }\n }\n\n async errorHooks(hooks: Hook[] | undefined, hookContext: HookContext, err: unknown, hints: HookHints) {\n // run \"error\" hooks sequentially\n for (const hook of hooks ?? []) {\n try {\n await hook?.error?.(hookContext, err, hints);\n } catch (err) {\n this.logger.error(`Unhandled error during 'error' hook: ${err}`);\n if (err instanceof Error) {\n this.logger.error(err.stack);\n }\n this.logger.error((err as Error)?.stack);\n }\n }\n }\n\n async finallyHooks(\n hooks: Hook[] | undefined,\n hookContext: HookContext,\n evaluationDetails: EvaluationDetails<FlagValue>,\n hints: HookHints,\n ) {\n // run \"finally\" hooks sequentially\n for (const hook of hooks ?? []) {\n try {\n await hook?.finally?.(hookContext, evaluationDetails, hints);\n } catch (err) {\n this.logger.error(`Unhandled error during 'finally' hook: ${err}`);\n if (err instanceof Error) {\n this.logger.error(err.stack);\n }\n this.logger.error((err as Error)?.stack);\n }\n }\n }\n}\n", "import { ServerProviderEvents } from '@openfeature/core';\n\nexport { ServerProviderEvents as ProviderEvents };", "import type { EventDetails } from '@openfeature/core';\nimport type { OpenFeatureEventEmitter } from '../../events';\nimport { ProviderEvents } from '../../events';\nimport { ProviderStatus } from '../provider';\nimport type { RegisteredProvider } from './types';\n\n/**\n * Tracks each individual provider's status by listening to emitted events\n * Maintains an overall \"status\" for the multi provider which represents the \"most critical\" status out of all providers\n */\nexport class StatusTracker {\n private readonly providerStatuses: Record<string, ProviderStatus> = {};\n\n constructor(private events: OpenFeatureEventEmitter) {}\n\n wrapEventHandler(providerEntry: RegisteredProvider) {\n const provider = providerEntry.provider;\n provider.events?.addHandler(ProviderEvents.Error, (details?: EventDetails) => {\n this.changeProviderStatus(providerEntry.name, ProviderStatus.ERROR, details);\n });\n\n provider.events?.addHandler(ProviderEvents.Stale, (details?: EventDetails) => {\n this.changeProviderStatus(providerEntry.name, ProviderStatus.STALE, details);\n });\n\n provider.events?.addHandler(ProviderEvents.ConfigurationChanged, (details?: EventDetails) => {\n this.events.emit(ProviderEvents.ConfigurationChanged, details);\n });\n\n provider.events?.addHandler(ProviderEvents.Ready, (details?: EventDetails) => {\n this.changeProviderStatus(providerEntry.name, ProviderStatus.READY, details);\n });\n }\n\n providerStatus(name: string) {\n return this.providerStatuses[name];\n }\n\n private getStatusFromProviderStatuses() {\n const statuses = Object.values(this.providerStatuses);\n if (statuses.includes(ProviderStatus.FATAL)) {\n return ProviderStatus.FATAL;\n } else if (statuses.includes(ProviderStatus.NOT_READY)) {\n return ProviderStatus.NOT_READY;\n } else if (statuses.includes(ProviderStatus.ERROR)) {\n return ProviderStatus.ERROR;\n } else if (statuses.includes(ProviderStatus.STALE)) {\n return ProviderStatus.STALE;\n }\n return ProviderStatus.READY;\n }\n\n private changeProviderStatus(name: string, status: ProviderStatus, details?: EventDetails) {\n const currentStatus = this.getStatusFromProviderStatuses();\n this.providerStatuses[name] = status;\n const newStatus = this.getStatusFromProviderStatuses();\n if (currentStatus !== newStatus) {\n if (newStatus === ProviderStatus.FATAL || newStatus === ProviderStatus.ERROR) {\n this.events.emit(ProviderEvents.Error, details);\n } else if (newStatus === ProviderStatus.STALE) {\n this.events.emit(ProviderEvents.Stale, details);\n } else if (newStatus === ProviderStatus.READY) {\n this.events.emit(ProviderEvents.Ready, details);\n }\n }\n }\n}\n", "import type {\n ErrorCode,\n EvaluationContext,\n FlagValue,\n FlagValueType,\n OpenFeatureError,\n ResolutionDetails,\n TrackingEventDetails,\n} from '@openfeature/core';\nimport type { Provider } from '../../provider';\nimport { ProviderStatus } from '../../provider';\nimport { ErrorWithCode } from '../errors';\n\nexport type StrategyEvaluationContext = {\n flagKey: string;\n flagType: FlagValueType;\n};\nexport type StrategyProviderContext = {\n provider: Provider;\n providerName: string;\n providerStatus: ProviderStatus;\n};\nexport type StrategyPerProviderContext = StrategyEvaluationContext & StrategyProviderContext;\n\ntype ProviderResolutionResultBase = {\n provider: Provider;\n providerName: string;\n};\n\nexport type ProviderResolutionSuccessResult<T extends FlagValue> = ProviderResolutionResultBase & {\n details: ResolutionDetails<T>;\n};\n\nexport type ProviderResolutionErrorResult = ProviderResolutionResultBase & {\n thrownError: unknown;\n};\n\nexport type ProviderResolutionResult<T extends FlagValue> =\n | ProviderResolutionSuccessResult<T>\n | ProviderResolutionErrorResult;\n\nexport type FinalResult<T extends FlagValue> = {\n details?: ResolutionDetails<T>;\n provider?: Provider;\n providerName?: string;\n errors?: {\n providerName: string;\n error: unknown;\n }[];\n};\n\n/**\n * Base strategy to inherit from. Not directly usable, as strategies must implement the \"determineResult\" method\n * Contains default implementations for `shouldEvaluateThisProvider` and `shouldEvaluateNextProvider`\n */\nexport abstract class BaseEvaluationStrategy {\n public runMode: 'parallel' | 'sequential' = 'sequential';\n\n shouldEvaluateThisProvider(strategyContext: StrategyPerProviderContext, _evalContext?: EvaluationContext): boolean {\n if (\n strategyContext.providerStatus === ProviderStatus.NOT_READY ||\n strategyContext.providerStatus === ProviderStatus.FATAL\n ) {\n return false;\n }\n return true;\n }\n\n shouldEvaluateNextProvider<T extends FlagValue>(\n _strategyContext?: StrategyPerProviderContext,\n _context?: EvaluationContext,\n _result?: ProviderResolutionResult<T>,\n ): boolean {\n return true;\n }\n\n shouldTrackWithThisProvider(\n strategyContext: StrategyProviderContext,\n _context?: EvaluationContext,\n _trackingEventName?: string,\n _trackingEventDetails?: TrackingEventDetails,\n ): boolean {\n if (\n strategyContext.providerStatus === ProviderStatus.NOT_READY ||\n strategyContext.providerStatus === ProviderStatus.FATAL\n ) {\n return false;\n }\n return true;\n }\n\n abstract determineFinalResult<T extends FlagValue>(\n strategyContext: StrategyEvaluationContext,\n context: EvaluationContext,\n resolutions: ProviderResolutionResult<T>[],\n ): FinalResult<T>;\n\n protected hasError(resolution: ProviderResolutionResult<FlagValue>): resolution is\n | ProviderResolutionErrorResult\n | (ProviderResolutionSuccessResult<FlagValue> & {\n details: ResolutionDetails<FlagValue> & { errorCode: ErrorCode };\n }) {\n return 'thrownError' in resolution || !!resolution.details.errorCode;\n }\n\n protected hasErrorWithCode(resolution: ProviderResolutionResult<FlagValue>, code: ErrorCode): boolean {\n return 'thrownError' in resolution\n ? (resolution.thrownError as OpenFeatureError)?.code === code\n : resolution.details.errorCode === code;\n }\n\n protected collectProviderErrors<T extends FlagValue>(resolutions: ProviderResolutionResult<T>[]): FinalResult<T> {\n const errors: FinalResult<FlagValue>['errors'] = [];\n for (const resolution of resolutions) {\n if ('thrownError' in resolution) {\n errors.push({ providerName: resolution.providerName, error: resolution.thrownError });\n } else if (resolution.details.errorCode) {\n errors.push({\n providerName: resolution.providerName,\n error: new ErrorWithCode(resolution.details.errorCode, resolution.details.errorMessage ?? 'unknown error'),\n });\n }\n }\n return { errors };\n }\n\n protected resolutionToFinalResult<T extends FlagValue>(resolution: ProviderResolutionSuccessResult<T>) {\n return { details: resolution.details, provider: resolution.provider, providerName: resolution.providerName };\n }\n}\n", "import type { FinalResult, ProviderResolutionResult, StrategyPerProviderContext } from './base-evaluation-strategy';\nimport { BaseEvaluationStrategy } from './base-evaluation-strategy';\nimport type { EvaluationContext, FlagValue } from '@openfeature/core';\nimport { ErrorCode } from '@openfeature/core';\n\n/**\n * Return the first result that did not indicate \"flag not found\".\n * If any provider in the course of evaluation returns or throws an error, throw that error\n */\nexport class FirstMatchStrategy extends BaseEvaluationStrategy {\n override shouldEvaluateNextProvider<T extends FlagValue>(\n strategyContext: StrategyPerProviderContext,\n context: EvaluationContext,\n result: ProviderResolutionResult<T>,\n ): boolean {\n if (this.hasErrorWithCode(result, ErrorCode.FLAG_NOT_FOUND)) {\n return true;\n }\n if (this.hasError(result)) {\n return false;\n }\n return false;\n }\n\n override determineFinalResult<T extends FlagValue>(\n strategyContext: StrategyPerProviderContext,\n context: EvaluationContext,\n resolutions: ProviderResolutionResult<T>[],\n ): FinalResult<T> {\n const finalResolution = resolutions[resolutions.length - 1];\n if (this.hasError(finalResolution)) {\n return this.collectProviderErrors(resolutions);\n }\n return this.resolutionToFinalResult(finalResolution);\n }\n}\n", "import type { FinalResult, ProviderResolutionResult, StrategyPerProviderContext } from './base-evaluation-strategy';\nimport { BaseEvaluationStrategy } from './base-evaluation-strategy';\nimport type { EvaluationContext, FlagValue } from '@openfeature/core';\n\n/**\n * Return the first result that did NOT result in an error\n * If any provider in the course of evaluation returns or throws an error, ignore it as long as there is a successful result\n * If there is no successful result, throw all errors\n */\nexport class FirstSuccessfulStrategy extends BaseEvaluationStrategy {\n override shouldEvaluateNextProvider<T extends FlagValue>(\n strategyContext: StrategyPerProviderContext,\n context: EvaluationContext,\n result: ProviderResolutionResult<T>,\n ): boolean {\n // evaluate next only if there was an error\n return this.hasError(result);\n }\n\n override determineFinalResult<T extends FlagValue>(\n strategyContext: StrategyPerProviderContext,\n context: EvaluationContext,\n resolutions: ProviderResolutionResult<T>[],\n ): FinalResult<T> {\n const finalResolution = resolutions[resolutions.length - 1];\n if (this.hasError(finalResolution)) {\n return this.collectProviderErrors(resolutions);\n }\n return this.resolutionToFinalResult(finalResolution);\n }\n}\n", "import type {\n FinalResult,\n ProviderResolutionResult,\n ProviderResolutionSuccessResult,\n StrategyPerProviderContext,\n} from './base-evaluation-strategy';\nimport { BaseEvaluationStrategy } from './base-evaluation-strategy';\nimport type { EvaluationContext, FlagValue } from '@openfeature/core';\nimport type { Provider } from '../../provider';\nimport { GeneralError } from '@openfeature/core';\n\n/**\n * Evaluate all providers in parallel and compare the results.\n * If the values agree, return the value\n * If the values disagree, return the value from the configured \"fallback provider\" and execute the \"onMismatch\"\n * callback if defined\n */\nexport class ComparisonStrategy extends BaseEvaluationStrategy {\n override runMode = 'parallel' as const;\n\n constructor(\n private fallbackProvider: Provider,\n private onMismatch?: (resolutions: ProviderResolutionResult<FlagValue>[]) => void,\n ) {\n super();\n }\n\n override determineFinalResult<T extends FlagValue>(\n strategyContext: StrategyPerProviderContext,\n context: EvaluationContext,\n resolutions: ProviderResolutionResult<T>[],\n ): FinalResult<T> {\n let value: T | undefined;\n let fallbackResolution: ProviderResolutionSuccessResult<T> | undefined;\n let finalResolution: ProviderResolutionSuccessResult<T> | undefined;\n let mismatch = false;\n for (const [i, resolution] of resolutions.entries()) {\n if (this.hasError(resolution)) {\n return this.collectProviderErrors(resolutions);\n }\n if (resolution.provider === this.fallbackProvider) {\n fallbackResolution = resolution;\n }\n if (i === 0) {\n finalResolution = resolution;\n }\n if (typeof value !== 'undefined' && value !== resolution.details.value) {\n mismatch = true;\n } else {\n value = resolution.details.value;\n }\n }\n\n if (!fallbackResolution) {\n throw new GeneralError('Fallback provider not found in resolution results');\n }\n\n if (!finalResolution) {\n throw new GeneralError('Final resolution not found in resolution results');\n }\n\n if (mismatch) {\n this.onMismatch?.(resolutions);\n return {\n details: fallbackResolution.details,\n provider: fallbackResolution.provider,\n };\n }\n\n return this.resolutionToFinalResult(finalResolution);\n }\n}\n", "import type {\n EvaluationContext,\n ManageContext,\n ServerProviderStatus} from '@openfeature/core';\nimport {\n OpenFeatureCommonAPI,\n ProviderWrapper,\n objectOrUndefined,\n stringOrUndefined,\n} from '@openfeature/core';\nimport type { Client } from './client';\nimport { OpenFeatureClient } from './client/internal/open-feature-client';\nimport { OpenFeatureEventEmitter } from './events';\nimport type { Hook } from './hooks';\nimport type { Provider} from './provider';\nimport { NOOP_PROVIDER, ProviderStatus } from './provider';\nimport type {\n ManageTransactionContextPropagator,\n TransactionContext,\n TransactionContextPropagator} from './transaction-context';\nimport {\n NOOP_TRANSACTION_CONTEXT_PROPAGATOR\n} from './transaction-context';\n\n// use a symbol as a key for the global singleton\nconst GLOBAL_OPENFEATURE_API_KEY = Symbol.for('@openfeature/js-sdk/api');\n\ntype OpenFeatureGlobal = {\n [GLOBAL_OPENFEATURE_API_KEY]?: OpenFeatureAPI;\n};\nconst _globalThis = globalThis as OpenFeatureGlobal;\n\nexport class OpenFeatureAPI\n extends OpenFeatureCommonAPI<ServerProviderStatus, Provider, Hook>\n implements\n ManageContext<OpenFeatureAPI>,\n ManageTransactionContextPropagator<OpenFeatureCommonAPI<ServerProviderStatus, Provider>>\n{\n protected _statusEnumType: typeof ProviderStatus = ProviderStatus;\n protected _apiEmitter = new OpenFeatureEventEmitter();\n protected _defaultProvider: ProviderWrapper<Provider, ServerProviderStatus> = new ProviderWrapper(\n NOOP_PROVIDER,\n ProviderStatus.NOT_READY,\n this._statusEnumType,\n );\n protected _domainScopedProviders: Map<string, ProviderWrapper<Provider, ServerProviderStatus>> = new Map();\n protected _createEventEmitter = () => new OpenFeatureEventEmitter();\n\n private _transactionContextPropagator: TransactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;\n\n private constructor() {\n super('server');\n }\n\n /**\n * Gets a singleton instance of the OpenFeature API.\n * @ignore\n * @returns {OpenFeatureAPI} OpenFeature API\n */\n static getInstance(): OpenFeatureAPI {\n const globalApi = _globalThis[GLOBAL_OPENFEATURE_API_KEY];\n if (globalApi) {\n return globalApi;\n }\n\n const instance = new OpenFeatureAPI();\n _globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;\n return instance;\n }\n\n private getProviderStatus(domain?: string): ProviderStatus {\n if (!domain) {\n return this._defaultProvider.status;\n }\n\n return this._domainScopedProviders.get(domain)?.status ?? this._defaultProvider.status;\n }\n\n /**\n * Sets the default provider for flag evaluations and returns a promise that resolves when the provider is ready.\n * This provider will be used by domainless clients and clients associated with domains to which no provider is bound.\n * Setting a provider supersedes the current provider used in new and existing unbound clients.\n * @param {Provider} provider The provider responsible for flag evaluations.\n * @returns {Promise<void>}\n * @throws {Error} If the provider throws an exception during initialization.\n */\n setProviderAndWait(provider: Provider): Promise<void>;\n /**\n * Sets the provider that OpenFeature will use for flag evaluations on clients bound to the same domain.\n * A promise is returned that resolves when the provider is ready.\n * Setting a provider supersedes the current provider used in new and existing clients bound to the same domain.\n * @param {string} domain The name to identify the client\n * @param {Provider} provider The provider responsible for flag evaluations.\n * @returns {Promise<void>}\n * @throws {Error} If the provider throws an exception during initialization.\n */\n setProviderAndWait(domain: string, provider: Provider): Promise<void>;\n async setProviderAndWait(domainOrProvider?: string | Provider, providerOrUndefined?: Provider): Promise<void> {\n const domain = stringOrUndefined(domainOrProvider);\n const provider = domain\n ? objectOrUndefined<Provider>(providerOrUndefined)\n : objectOrUndefined<Provider>(domainOrProvider);\n\n await this.setAwaitableProvider(domain, provider);\n }\n\n /**\n * Sets the default provider for flag evaluations.\n * This provider will be used by domainless clients and clients associated with domains to which no provider is bound.\n * Setting a provider supersedes the current provider used in new and existing unbound clients.\n * @param {Provider} provider The provider responsible for flag evaluations.\n * @returns {this} OpenFeature API\n */\n setProvider(provider: Provider): this;\n /**\n * Sets the provider for flag evaluations of providers with the given name.\n * Setting a provider supersedes the current provider used in new and existing clients bound to the same domain.\n * @param {string} domain The name to identify the client\n * @param {Provider} provider The provider responsible for flag evaluations.\n * @returns {this} OpenFeature API\n */\n setProvider(domain: string, provider: Provider): this;\n setProvider(clientOrProvider?: string | Provider, providerOrUndefined?: Provider): this {\n const domain = stringOrUndefined(clientOrProvider);\n const provider = domain\n ? objectOrUndefined<Provider>(providerOrUndefined)\n : objectOrUndefined<Provider>(clientOrProvider);\n\n const maybePromise = this.setAwaitableProvider(domain, provider);\n\n // The setProvider method doesn't return a promise so we need to catch and\n // log any errors that occur during provider initialization to avoid having\n // an unhandled promise rejection.\n Promise.resolve(maybePromise).catch((err) => {\n this._logger.error('Error during provider initialization:', err);\n });\n\n return this;\n }\n\n /**\n * Get the default provider.\n *\n * Note that it isn't recommended to interact with the provider directly, but rather through\n * an OpenFeature client.\n * @returns {Provider} Default Provider\n */\n getProvider(): Provider;\n /**\n * Get the provider bound to the specified domain.\n *\n * Note that it isn't recommended to interact with the provider directly, but rather through\n * an OpenFeature client.\n * @param {string} domain An identifier which logically binds clients with providers\n * @returns {Provider} Domain-scoped provider\n */\n getProvider(domain?: string): Provider;\n getProvider(domain?: string): Provider {\n return this.getProviderForClient(domain);\n }\n\n setContext(context: EvaluationContext): this {\n this._context = context;\n return this;\n }\n\n getContext(): EvaluationContext {\n return this._context;\n }\n\n /**\n * A factory function for creating new domainless OpenFeature clients.\n * Clients can contain their own state (e.g. logger, hook, context).\n * Multiple clients can be used to segment feature flag configuration.\n *\n * All domainless or unbound clients use the default provider set via {@link this.setProvider setProvider}.\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(context?: EvaluationContext): Client;\n /**\n * A factory function for creating new domain scoped OpenFeature clients.\n * Clients can contain their own state (e.g. logger, hook, context).\n * Multiple clients can be used to segment feature flag configuration.\n *\n * If there is already a provider bound to this domain via {@link this.setProvider setProvider}, this provider will be used.\n * Otherwise, the default provider is used until a provider is assigned to that domain.\n * @param {string} domain An identifier which logically binds clients with providers\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(domain: string, context?: EvaluationContext): Client;\n /**\n * A factory function for creating new domain scoped OpenFeature clients.\n * Clients can contain their own state (e.g. logger, hook, context).\n * Multiple clients can be used to segment feature flag configuration.\n *\n * If there is already a provider bound to this domain via {@link this.setProvider setProvider}, this provider will be used.\n * Otherwise, the default provider is used until a provider is assigned to that domain.\n * @param {string} domain An identifier which logically binds clients with providers\n * @param {string} version The version of the client (only used for metadata)\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(domain: string, version: string, context?: EvaluationContext): Client;\n getClient(\n domainOrContext?: string | EvaluationContext,\n versionOrContext?: string | EvaluationContext,\n contextOrUndefined?: EvaluationContext,\n ): Client {\n const domain = stringOrUndefined(domainOrContext);\n const version = stringOrUndefined(versionOrContext);\n const context =\n objectOrUndefined<EvaluationContext>(domainOrContext) ??\n objectOrUndefined<EvaluationContext>(versionOrContext) ??\n objectOrUndefined<EvaluationContext>(contextOrUndefined);\n\n return new OpenFeatureClient(\n () => this.getProviderForClient(domain),\n () => this.getProviderStatus(domain),\n () => this.buildAndCacheEventEmitterForClient(domain),\n () => this.getContext(),\n () => this.getHooks(),\n () => this.getTransactionContext(),\n () => this._logger,\n { domain, version },\n context,\n );\n }\n\n /**\n * Clears all registered providers and resets the default provider.\n * @returns {Promise<void>}\n */\n clearProviders(): Promise<void> {\n return super.clearProvidersAndSetDefault(NOOP_PROVIDER);\n }\n\n setTransactionContextPropagator(\n transactionContextPropagator: TransactionContextPropagator,\n ): OpenFeatureCommonAPI<ServerProviderStatus, Provider> {\n const baseMessage = 'Invalid TransactionContextPropagator, will not be set: ';\n if (typeof transactionContextPropagator?.getTransactionContext !== 'function') {\n this._logger.error(`${baseMessage}: getTransactionContext is not a function.`);\n } else if (typeof transactionContextPropagator?.setTransactionContext !== 'function') {\n this._logger.error(`${baseMessage}: setTransactionContext is not a function.`);\n } else {\n this._transactionContextPropagator = transactionContextPropagator;\n }\n return this;\n }\n\n setTransactionContext<TArgs extends unknown[], R>(\n transactionContext: TransactionContext,\n callback: (...args: TArgs) => R,\n ...args: TArgs\n ): void {\n this._transactionContextPropagator.setTransactionContext(transactionContext, callback, ...args);\n }\n\n getTransactionContext(): TransactionContext {\n try {\n return this._transactionContextPropagator.getTransactionContext();\n } catch (err: unknown) {\n const error = err as Error | undefined;\n this._logger.error(`Error getting transaction context: ${error?.message}, returning empty context.`);\n this._logger.error(error?.stack);\n return {};\n }\n }\n}\n\n/**\n * A singleton instance of the OpenFeature API.\n * @returns {OpenFeatureAPI} OpenFeature API\n */\nexport const OpenFeature = OpenFeatureAPI.getInstance();\n", "import type {\n ClientMetadata,\n EvaluationContext,\n EvaluationDetails,\n EventHandler,\n FlagValue,\n FlagValueType,\n HookContext,\n JsonValue,\n Logger,\n TrackingEventDetails,\n OpenFeatureError,\n FlagMetadata,\n ResolutionDetails,\n EventOptions,\n} from '@openfeature/core';\nimport {\n ErrorCode,\n ProviderFatalError,\n ProviderNotReadyError,\n SafeLogger,\n StandardResolutionReasons,\n instantiateErrorByErrorCode,\n statusMatchesEvent,\n MapHookData,\n} from '@openfeature/core';\nimport type { FlagEvaluationOptions } from '../../evaluation';\nimport type { ProviderEvents } from '../../events';\nimport type { InternalEventEmitter } from '../../events/internal/internal-event-emitter';\nimport type { Hook } from '../../hooks';\nimport type { Provider } from '../../provider';\nimport { ProviderStatus } from '../../provider';\nimport type { Client } from './../client';\n\ntype OpenFeatureClientOptions = {\n /**\n * @deprecated Use `domain` instead.\n */\n name?: string;\n domain?: string;\n version?: string;\n};\n\n/**\n * This implementation of the {@link Client} is meant to only be instantiated by the SDK.\n * It should not be used outside the SDK and so should not be exported.\n * @internal\n */\nexport class OpenFeatureClient implements Client {\n private _context: EvaluationContext;\n private _hooks: Hook[] = [];\n private _clientLogger?: Logger;\n\n constructor(\n // we always want the client to use the current provider,\n // so pass a function to always access the currently registered one.\n private readonly providerAccessor: () => Provider,\n private readonly providerStatusAccessor: () => ProviderStatus,\n private readonly emitterAccessor: () => InternalEventEmitter,\n private readonly apiContextAccessor: () => EvaluationContext,\n private readonly apiHooksAccessor: () => Hook[],\n private readonly transactionContextAccessor: () => EvaluationContext,\n private readonly globalLogger: () => Logger,\n private readonly options: OpenFeatureClientOptions,\n context: EvaluationContext = {},\n ) {\n this._context = context;\n }\n\n get metadata(): ClientMetadata {\n return {\n // Use domain if name is not provided\n name: this.options.domain ?? this.options.name,\n domain: this.options.domain ?? this.options.name,\n version: this.options.version,\n providerMetadata: this.providerAccessor().metadata,\n };\n }\n\n get providerStatus(): ProviderStatus {\n return this.providerStatusAccessor();\n }\n\n addHandler(eventType: ProviderEvents, handler: EventHandler, options?: EventOptions): void {\n this.emitterAccessor().addHandler(eventType, handler);\n const shouldRunNow = statusMatchesEvent(eventType, this._providerStatus);\n\n if (shouldRunNow) {\n // run immediately, we're in the matching state\n try {\n handler({\n clientName: this.metadata.name,\n domain: this.metadata.domain,\n providerName: this._provider.metadata.name,\n });\n } catch (err) {\n this._logger?.error('Error running event handler:', err);\n }\n }\n\n if (options?.signal && typeof options.signal.addEventListener === 'function') {\n options.signal.addEventListener('abort', () => {\n this.removeHandler(eventType, handler);\n });\n }\n }\n\n removeHandler(eventType: ProviderEvents, handler: EventHandler) {\n this.emitterAccessor().removeHandler(eventType, handler);\n }\n\n getHandlers(eventType: ProviderEvents) {\n return this.emitterAccessor().getHandlers(eventType);\n }\n\n setLogger(logger: Logger): OpenFeatureClient {\n this._clientLogger = new SafeLogger(logger);\n return this;\n }\n\n setContext(context: EvaluationContext): OpenFeatureClient {\n this._context = context;\n return this;\n }\n\n getContext(): EvaluationContext {\n return this._context;\n }\n\n addHooks(...hooks: Hook[]): OpenFeatureClient {\n this._hooks = [...this._hooks, ...hooks];\n return this;\n }\n\n getHooks(): Hook[] {\n return this._hooks;\n }\n\n clearHooks(): OpenFeatureClient {\n this._hooks = [];\n return this;\n }\n\n async getBooleanValue(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<boolean> {\n return (await this.getBooleanDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getBooleanDetails(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<boolean>> {\n return this.evaluate<boolean>(\n flagKey,\n this._provider.resolveBooleanEvaluation,\n defaultValue,\n 'boolean',\n context,\n options,\n );\n }\n\n async getStringValue<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getStringDetails<T>(flagKey, defaultValue, context, options)).value;\n }\n\n getStringDetails<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(\n flagKey,\n // this isolates providers from our restricted string generic argument.\n this._provider.resolveStringEvaluation as () => Promise<EvaluationDetails<T>>,\n defaultValue,\n 'string',\n context,\n options,\n );\n }\n\n async getNumberValue<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getNumberDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getNumberDetails<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(\n flagKey,\n // this isolates providers from our restricted number generic argument.\n this._provider.resolveNumberEvaluation as () => Promise<EvaluationDetails<T>>,\n defaultValue,\n 'number',\n context,\n options,\n );\n }\n\n async getObjectValue<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getObjectDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getObjectDetails<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(flagKey, this._provider.resolveObjectEvaluation, defaultValue, 'object', context, options);\n }\n\n track(occurrenceKey: string, context: EvaluationContext = {}, occurrenceDetails: TrackingEventDetails = {}): void {\n try {\n this.shortCircuitIfNotReady();\n\n if (typeof this._provider.track === 'function') {\n // freeze the merged context\n const frozenContext = Object.freeze(this.mergeContexts(context));\n return this._provider.track?.(occurrenceKey, frozenContext, occurrenceDetails);\n } else {\n this._logger.debug('Provider does not support the track function; will no-op.');\n }\n } catch (err) {\n this._logger.debug('Error recording tracking event.', err);\n }\n }\n\n private async evaluate<T extends FlagValue>(\n flagKey: string,\n resolver: (\n flagKey: string,\n defaultValue: T,\n context: EvaluationContext,\n logger: Logger,\n ) => Promise<ResolutionDetails<T>>,\n defaultValue: T,\n flagType: FlagValueType,\n invocationContext: EvaluationContext = {},\n options: FlagEvaluationOptions = {},\n ): Promise<EvaluationDetails<T>> {\n // merge global, client, and evaluation context\n\n const allHooks = [\n ...this.apiHooksAccessor(),\n ...this.getHooks(),\n ...(options.hooks || []),\n ...(this._provider.hooks || []),\n ];\n const allHooksReversed = [...allHooks].reverse();\n\n const mergedContext = this.mergeContexts(invocationContext);\n\n // Create hook context instances for each hook (stable object references for the entire evaluation)\n // This ensures hooks can use WeakMaps with hookContext as keys across lifecycle methods\n // NOTE: Uses the reversed order to reduce the number of times we have to calculate the index.\n const hookContexts = allHooksReversed.map<HookContext>(() =>\n Object.freeze({\n flagKey,\n defaultValue,\n flagValueType: flagType,\n clientMetadata: this.metadata,\n providerMetadata: this._provider.metadata,\n context: mergedContext,\n logger: this._logger,\n hookData: new MapHookData(),\n }),\n );\n\n let evaluationDetails: EvaluationDetails<T>;\n\n try {\n const frozenContext = await this.beforeHooks(allHooks, hookContexts, mergedContext, options);\n\n this.shortCircuitIfNotReady();\n\n // run the referenced resolver, binding the provider.\n const resolution = await resolver.call(this._provider, flagKey, defaultValue, frozenContext, this._logger);\n\n const resolutionDetails = {\n ...resolution,\n flagMetadata: Object.freeze(resolution.flagMetadata ?? {}),\n flagKey,\n };\n\n if (resolutionDetails.errorCode) {\n const err = instantiateErrorByErrorCode(resolutionDetails.errorCode, resolutionDetails.errorMessage);\n await this.errorHooks(allHooksReversed, hookContexts, err, options);\n evaluationDetails = this.getErrorEvaluationDetails(flagKey, defaultValue, err, resolutionDetails.flagMetadata);\n } else {\n await this.afterHooks(allHooksReversed, hookContexts, resolutionDetails, options);\n evaluationDetails = resolutionDetails;\n }\n } catch (err: unknown) {\n await this.errorHooks(allHooksReversed, hookContexts, err, options);\n evaluationDetails = this.getErrorEvaluationDetails(flagKey, defaultValue, err);\n }\n\n await this.finallyHooks(allHooksReversed, hookContexts, evaluationDetails, options);\n return evaluationDetails;\n }\n\n private async beforeHooks(\n hooks: Hook[],\n hookContexts: HookContext[],\n mergedContext: EvaluationContext,\n options: FlagEvaluationOptions,\n ) {\n const accumulatedContext = mergedContext;\n\n for (const [index, hook] of hooks.entries()) {\n const hookContextIndex = hooks.length - 1 - index; // reverse index for before hooks\n const hookContext = hookContexts[hookContextIndex];\n\n // Update the context on the stable hook context object\n Object.assign(hookContext.context, accumulatedContext);\n\n const hookResult = await hook?.before?.(hookContext, Object.freeze(options.hookHints));\n if (hookResult) {\n Object.assign(accumulatedContext, hookResult);\n\n for (let i = 0; i < hooks.length; i++) {\n Object.assign(hookContexts[hookContextIndex].context, accumulatedContext);\n }\n }\n }\n\n // after before hooks, freeze the EvaluationContext.\n return Object.freeze(accumulatedContext);\n }\n\n private async afterHooks(\n hooks: Hook[],\n hookContexts: HookContext[],\n evaluationDetails: EvaluationDetails<FlagValue>,\n options: FlagEvaluationOptions,\n ) {\n // run \"after\" hooks sequentially\n for (const [index, hook] of hooks.entries()) {\n const hookContext = hookContexts[index];\n await hook?.after?.(hookContext, evaluationDetails, options.hookHints);\n }\n }\n\n private async errorHooks(hooks: Hook[], hookContexts: HookContext[], err: unknown, options: FlagEvaluationOptions) {\n // run \"error\" hooks sequentially\n for (const [index, hook] of hooks.entries()) {\n try {\n const hookContext = hookContexts[index];\n await hook?.error?.(hookContext, err, options.hookHints);\n } catch (err) {\n this._logger.error(`Unhandled error during 'error' hook: ${err}`);\n if (err instanceof Error) {\n this._logger.error(err.stack);\n }\n this._logger.error((err as Error)?.stack);\n }\n }\n }\n\n private async finallyHooks(\n hooks: Hook[],\n hookContexts: HookContext[],\n evaluationDetails: EvaluationDetails<FlagValue>,\n options: FlagEvaluationOptions,\n ) {\n // run \"finally\" hooks sequentially\n for (const [index, hook] of hooks.entries()) {\n try {\n const hookContext = hookContexts[index];\n await hook?.finally?.(hookContext, evaluationDetails, options.hookHints);\n } catch (err) {\n this._logger.error(`Unhandled error during 'finally' hook: ${err}`);\n if (err instanceof Error) {\n this._logger.error(err.stack);\n }\n this._logger.error((err as Error)?.stack);\n }\n }\n }\n\n private get _provider(): Provider {\n return this.providerAccessor();\n }\n\n private get _providerStatus(): ProviderStatus {\n return this.providerStatusAccessor();\n }\n\n private get _logger() {\n return this._clientLogger || this.globalLogger();\n }\n\n private mergeContexts(invocationContext: EvaluationContext) {\n // merge global and client contexts\n return {\n ...this.apiContextAccessor(),\n ...this.transactionContextAccessor(),\n ...this._context,\n ...invocationContext,\n };\n }\n\n private shortCircuitIfNotReady() {\n // short circuit evaluation entirely if provider is in a bad state\n if (this.providerStatus === ProviderStatus.NOT_READY) {\n throw new ProviderNotReadyError('provider has not yet initialized');\n } else if (this.providerStatus === ProviderStatus.FATAL) {\n throw new ProviderFatalError('provider is in an irrecoverable error state');\n }\n }\n\n private getErrorEvaluationDetails<T extends FlagValue>(\n flagKey: string,\n defaultValue: T,\n err: unknown,\n flagMetadata: FlagMetadata = {},\n ): EvaluationDetails<T> {\n const errorMessage: string = (err as Error)?.message;\n const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;\n\n return {\n errorCode,\n errorMessage,\n value: defaultValue,\n reason: StandardResolutionReasons.ERROR,\n flagMetadata: Object.freeze(flagMetadata),\n flagKey,\n };\n }\n}\n", "import type { EvaluationContext } from '@openfeature/core';\nimport type { TransactionContext, TransactionContextPropagator } from './transaction-context';\n\nclass NoopTransactionContextPropagator implements TransactionContextPropagator {\n getTransactionContext(): EvaluationContext {\n return {};\n }\n\n setTransactionContext<TArgs extends unknown[], R>(\n _: TransactionContext,\n callback: (...args: TArgs) => R,\n ...args: TArgs\n ): void {\n callback(...args);\n }\n}\n\nexport const NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();\n", "import type { EvaluationContext } from '@openfeature/core';\nimport type { TransactionContext, TransactionContextPropagator } from './transaction-context';\nimport { AsyncLocalStorage } from 'async_hooks';\n\nexport class AsyncLocalStorageTransactionContextPropagator implements TransactionContextPropagator {\n private asyncLocalStorage = new AsyncLocalStorage<EvaluationContext>();\n\n getTransactionContext(): EvaluationContext {\n return this.asyncLocalStorage.getStore() ?? {};\n }\n\n setTransactionContext<TArgs extends unknown[], R>(\n transactionContext: TransactionContext,\n callback: (...args: TArgs) => R,\n ...args: TArgs\n ): void {\n this.asyncLocalStorage.run(transactionContext, callback, ...args);\n }\n}\n", "export * from './client';\nexport * from './provider';\nexport * from './evaluation';\nexport * from './open-feature';\nexport * from './transaction-context';\nexport * from './events';\nexport * from './hooks';\nexport * from './tracking';\nexport * from '@openfeature/core';\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA;AAAA,EACE;AAAA,OACK;;;ACLP,IAAM,eAAe;AAKrB,IAAM,sBAAN,MAA8C;AAAA,EAA9C;AACE,SAAS,WAAW;AAAA,MAClB,MAAM;AAAA,IACR;AAAA;AAAA,EAEA,yBAAyB,GAAW,cAA4D;AAC9F,WAAO,KAAK,KAAK,YAAY;AAAA,EAC/B;AAAA,EAEA,wBAAwB,GAAW,cAA0D;AAC3F,WAAO,KAAK,KAAK,YAAY;AAAA,EAC/B;AAAA,EAEA,wBAAwB,GAAW,cAA0D;AAC3F,WAAO,KAAK,KAAK,YAAY;AAAA,EAC/B;AAAA,EAEA,wBAA6C,GAAW,cAAgD;AACtG,WAAO,KAAK,KAAQ,YAAY;AAAA,EAClC;AAAA,EAEQ,KAAQ,cAAiB;AAC/B,WAAO,QAAQ,QAAQ;AAAA,MACrB,OAAO;AAAA,MACP,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;AAEO,IAAM,gBAAgB,IAAI,oBAAoB;;;AC/BrD;AAAA,EACE;AAAA,EACA;AAAA,EACA,oBAAAA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACZP,SAAS,WAAW,wBAAwB;AAMrC,IAAM,oBAAN,MAAM,2BAA0B,iBAAiB;AAAA,EAEtD,YAAY,SAAkB;AAC5B,UAAM,OAAO;AACb,WAAO,eAAe,MAAM,mBAAkB,SAAS;AACvD,SAAK,OAAO;AACZ,SAAK,OAAO,UAAU;AAAA,EACxB;AACF;;;ADOO,IAAM,mBAAN,MAA2C;AAAA,EAQhD,YAAY,oBAAuC,CAAC,GAAG;AAPvD,SAAgB,SAAS,IAAI,wBAAwB;AACrD,SAAgB,SAAS;AACzB,SAAS,WAAW;AAAA,MAClB,MAAM;AAAA,IACR;AAIE,SAAK,qBAAqB,mBAAK;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAiB,mBAAsC;AACrD,UAAM,eAAe,OAAO,QAAQ,iBAAiB,EAClD,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM,KAAK,mBAAmB,GAAG,MAAM,KAAK,EAC/D,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG;AAErB,SAAK,qBAAqB,mBAAK;AAC/B,SAAK,OAAO,KAAK,qBAAe,sBAAsB,EAAE,aAAa,CAAC;AAAA,EACxE;AAAA,EAEA,yBACE,SACA,cACA,SACA,QACqC;AACrC,WAAO,KAAK,sBAA+B,SAAS,cAAc,SAAS,MAAM;AAAA,EACnF;AAAA,EAEA,wBACE,SACA,cACA,SACA,QACoC;AACpC,WAAO,KAAK,sBAA8B,SAAS,cAAc,SAAS,MAAM;AAAA,EAClF;AAAA,EAEM,wBACJ,SACA,cACA,SACA,QACoC;AAAA;AACpC,aAAO,KAAK,sBAA8B,SAAS,cAAc,SAAS,MAAM;AAAA,IAClF;AAAA;AAAA,EAEM,wBACJ,SACA,cACA,SACA,QAC+B;AAAA;AAC/B,aAAO,KAAK,sBAAyB,SAAS,cAAc,SAAS,MAAM;AAAA,IAC7E;AAAA;AAAA,EAEc,sBACZ,SACA,cACA,KACA,QAC+B;AAAA;AAC/B,UAAI;AACF,cAAM,mBAAmB,KAAK,gBAAgB,SAAS,cAAc,KAAK,MAAM;AAEhF,YAAI,QAAO,qDAAkB,UAAS,OAAO,cAAc;AACzD,gBAAM,IAAI,kBAAkB;AAAA,QAC9B;AAEA,eAAO;AAAA,MACT,SAAS,OAAgB;AACvB,YAAI,EAAE,iBAAiBC,oBAAmB;AACxC,gBAAM,IAAI,cAAc,+BAAiB,YAAW,eAAe;AAAA,QACrE;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA,EAEQ,gBACN,SACA,cACA,KACA,QACsB;AA7G1B;AA8GI,QAAI,EAAE,WAAW,KAAK,qBAAqB;AACzC,YAAM,UAAU,0BAA0B,OAAO;AACjD,uCAAQ,MAAM;AACd,YAAM,IAAI,kBAAkB,OAAO;AAAA,IACrC;AACA,UAAM,WAAiB,KAAK,mBAAmB,OAAO;AAEtD,QAAI,SAAS,UAAU;AACrB,aAAO,EAAE,OAAO,cAAc,QAAQ,0BAA0B,SAAS;AAAA,IAC3E;AAEA,UAAM,gBAAgB,QAAO,qCAAU;AACvC,UAAM,UAAU,iBAAgB,cAAS,qBAAT,kCAA4B,OAAO,SAAS;AAE5E,UAAM,QAAQ,YAAW,qCAAU,SAAS;AAE5C,QAAI,UAAU,QAAW;AACvB,YAAM,UAAU,oCAAoC,OAAO;AAC3D,uCAAQ,MAAM;AACd,YAAM,IAAI,kBAAkB,OAAO;AAAA,IACrC;AAEA,WAAO;AAAA,MACL;AAAA,OACI,WAAW,EAAE,QAAQ,IAFpB;AAAA,MAGL,QAAQ,gBAAgB,0BAA0B,kBAAkB,0BAA0B;AAAA,IAChG;AAAA,EACF;AACF;;;AE1HA,SAAS,eAAe,aAAAC,YAAW,gBAAAC,eAAc,6BAAAC,kCAAiC;;;AChBlF,SAAS,2BAA2B;AACpC,SAAS,oBAAoB;AAUtB,IAAM,0BAAN,cAAsC,oBAAoC;AAAA,EAG9E,cAAc;AACX,UAAM;AAHV,SAAmB,eAAe,IAAI,aAAa,EAAE,mBAAmB,KAAK,CAAC;AAI1E,SAAK,aAAa,GAAG,SAAS,CAAC,QAAQ;AAhB7C;AAiBQ,iBAAK,YAAL,mBAAc,MAAM,gCAAgC;AAAA,IACtD,CAAC;AAAA,EACH;AACJ;;;ACnBA,SAAS,gBAAAC,eAAc,oBAAAC,yBAAwB;AAGxC,IAAM,gBAAN,cAA4BA,kBAAiB;AAAA,EAClD,YACS,MACP,SACA;AACA,UAAM,OAAO;AAHN;AAAA,EAIT;AACF;AAEO,IAAM,iBAAN,cAA6BD,cAAa;AAAA,EAC/C,YACE,SACO,gBACP;AACA,UAAM,OAAO;AAFN;AAAA,EAGT;AACF;AAEO,IAAM,0BAA0B,CAAC,mBAA+D;AACrG,QAAM,mBAAmB,eACtB,IAAI,CAAC,EAAE,cAAc,MAAM,MAAM;AAChC,WAAO,EAAE,QAAQ,cAAc,MAAM;AAAA,EACvC,CAAC,EACA,KAAK;AAGR,SAAO,IAAI;AAAA,IACT,6BAA6B,iBAAiB,CAAC,EAAE,MAAM,KAAK,iBAAiB,CAAC,EAAE,KAAK;AAAA,IACrF;AAAA,EACF;AACF;AAEO,IAAM,wCAAwC,CACnD,QACA,oBACG;AACH,QAAM,SAAS,OACZ,IAAI,CAAC,GAAG,MAAM;AACb,QAAI,EAAE,WAAW,YAAY;AAC3B,aAAO,EAAE,OAAO,EAAE,QAAQ,cAAc,gBAAgB,CAAC,EAAE,KAAK;AAAA,IAClE;AACA,WAAO;AAAA,EACT,CAAC,EACA,OAAO,CAAC,QAAyD,QAAQ,GAAG,CAAC;AAEhF,MAAI,OAAO,QAAQ;AACjB,UAAM,wBAAwB,MAAM;AAAA,EACtC;AACF;;;AC9CO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,QAAgB;AAAhB;AAAA,EAAiB;AAAA,EAE/B,YAAY,OAA2B,aAA0B,OAAkB;AAAA;AAT3F;AAUI,iBAAW,QAAQ,wBAAS,CAAC,GAAG;AAE9B,eAAO,OAAO,WAAW;AAEzB,eAAO,OAAO,YAAY,SAAS,mBAC7B,OAAM,kCAAM,WAAN,8BAAe,aAAa,OAAO,OAAO,KAAK,GAC1D;AAAA,MACH;AAGA,aAAO,OAAO,OAAO,YAAY,OAAO;AAAA,IAC1C;AAAA;AAAA,EAEM,WACJ,OACA,aACA,mBACA,OACA;AAAA;AA5BJ;AA8BI,iBAAW,QAAQ,wBAAS,CAAC,GAAG;AAC9B,eAAM,kCAAM,UAAN,8BAAc,aAAa,mBAAmB;AAAA,MACtD;AAAA,IACF;AAAA;AAAA,EAEM,WAAW,OAA2B,aAA0B,KAAc,OAAkB;AAAA;AAnCxG;AAqCI,iBAAW,QAAQ,wBAAS,CAAC,GAAG;AAC9B,YAAI;AACF,iBAAM,kCAAM,UAAN,8BAAc,aAAa,KAAK;AAAA,QACxC,SAASE,MAAK;AACZ,eAAK,OAAO,MAAM,wCAAwCA,IAAG,EAAE;AAC/D,cAAIA,gBAAe,OAAO;AACxB,iBAAK,OAAO,MAAMA,KAAI,KAAK;AAAA,UAC7B;AACA,eAAK,OAAO,MAAOA,QAAA,gBAAAA,KAAe,KAAK;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA;AAAA,EAEM,aACJ,OACA,aACA,mBACA,OACA;AAAA;AAvDJ;AAyDI,iBAAW,QAAQ,wBAAS,CAAC,GAAG;AAC9B,YAAI;AACF,iBAAM,kCAAM,YAAN,8BAAgB,aAAa,mBAAmB;AAAA,QACxD,SAAS,KAAK;AACZ,eAAK,OAAO,MAAM,0CAA0C,GAAG,EAAE;AACjE,cAAI,eAAe,OAAO;AACxB,iBAAK,OAAO,MAAM,IAAI,KAAK;AAAA,UAC7B;AACA,eAAK,OAAO,MAAO,2BAAe,KAAK;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA;AACF;;;ACrEA,SAAS,4BAA4B;;;ACU9B,IAAM,gBAAN,MAAoB;AAAA,EAGzB,YAAoB,QAAiC;AAAjC;AAFpB,SAAiB,mBAAmD,CAAC;AAAA,EAEf;AAAA,EAEtD,iBAAiB,eAAmC;AAftD;AAgBI,UAAM,WAAW,cAAc;AAC/B,mBAAS,WAAT,mBAAiB,WAAW,qBAAe,OAAO,CAAC,YAA2B;AAC5E,WAAK,qBAAqB,cAAc,MAAM,qBAAe,OAAO,OAAO;AAAA,IAC7E;AAEA,mBAAS,WAAT,mBAAiB,WAAW,qBAAe,OAAO,CAAC,YAA2B;AAC5E,WAAK,qBAAqB,cAAc,MAAM,qBAAe,OAAO,OAAO;AAAA,IAC7E;AAEA,mBAAS,WAAT,mBAAiB,WAAW,qBAAe,sBAAsB,CAAC,YAA2B;AAC3F,WAAK,OAAO,KAAK,qBAAe,sBAAsB,OAAO;AAAA,IAC/D;AAEA,mBAAS,WAAT,mBAAiB,WAAW,qBAAe,OAAO,CAAC,YAA2B;AAC5E,WAAK,qBAAqB,cAAc,MAAM,qBAAe,OAAO,OAAO;AAAA,IAC7E;AAAA,EACF;AAAA,EAEA,eAAe,MAAc;AAC3B,WAAO,KAAK,iBAAiB,IAAI;AAAA,EACnC;AAAA,EAEQ,gCAAgC;AACtC,UAAM,WAAW,OAAO,OAAO,KAAK,gBAAgB;AACpD,QAAI,SAAS,SAAS,qBAAe,KAAK,GAAG;AAC3C,aAAO,qBAAe;AAAA,IACxB,WAAW,SAAS,SAAS,qBAAe,SAAS,GAAG;AACtD,aAAO,qBAAe;AAAA,IACxB,WAAW,SAAS,SAAS,qBAAe,KAAK,GAAG;AAClD,aAAO,qBAAe;AAAA,IACxB,WAAW,SAAS,SAAS,qBAAe,KAAK,GAAG;AAClD,aAAO,qBAAe;AAAA,IACxB;AACA,WAAO,qBAAe;AAAA,EACxB;AAAA,EAEQ,qBAAqB,MAAc,QAAwB,SAAwB;AACzF,UAAM,gBAAgB,KAAK,8BAA8B;AACzD,SAAK,iBAAiB,IAAI,IAAI;AAC9B,UAAM,YAAY,KAAK,8BAA8B;AACrD,QAAI,kBAAkB,WAAW;AAC/B,UAAI,cAAc,qBAAe,SAAS,cAAc,qBAAe,OAAO;AAC5E,aAAK,OAAO,KAAK,qBAAe,OAAO,OAAO;AAAA,MAChD,WAAW,cAAc,qBAAe,OAAO;AAC7C,aAAK,OAAO,KAAK,qBAAe,OAAO,OAAO;AAAA,MAChD,WAAW,cAAc,qBAAe,OAAO;AAC7C,aAAK,OAAO,KAAK,qBAAe,OAAO,OAAO;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACF;;;ACXO,IAAe,yBAAf,MAAsC;AAAA,EAAtC;AACL,SAAO,UAAqC;AAAA;AAAA,EAE5C,2BAA2B,iBAA6C,cAA2C;AACjH,QACE,gBAAgB,mBAAmB,qBAAe,aAClD,gBAAgB,mBAAmB,qBAAe,OAClD;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,2BACE,kBACA,UACA,SACS;AACT,WAAO;AAAA,EACT;AAAA,EAEA,4BACE,iBACA,UACA,oBACA,uBACS;AACT,QACE,gBAAgB,mBAAmB,qBAAe,aAClD,gBAAgB,mBAAmB,qBAAe,OAClD;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAQU,SAAS,YAIZ;AACL,WAAO,iBAAiB,cAAc,CAAC,CAAC,WAAW,QAAQ;AAAA,EAC7D;AAAA,EAEU,iBAAiB,YAAiD,MAA0B;AAzGxG;AA0GI,WAAO,iBAAiB,eACnB,gBAAW,gBAAX,mBAA6C,UAAS,OACvD,WAAW,QAAQ,cAAc;AAAA,EACvC;AAAA,EAEU,sBAA2C,aAA4D;AA/GnH;AAgHI,UAAM,SAA2C,CAAC;AAClD,eAAW,cAAc,aAAa;AACpC,UAAI,iBAAiB,YAAY;AAC/B,eAAO,KAAK,EAAE,cAAc,WAAW,cAAc,OAAO,WAAW,YAAY,CAAC;AAAA,MACtF,WAAW,WAAW,QAAQ,WAAW;AACvC,eAAO,KAAK;AAAA,UACV,cAAc,WAAW;AAAA,UACzB,OAAO,IAAI,cAAc,WAAW,QAAQ,YAAW,gBAAW,QAAQ,iBAAnB,YAAmC,eAAe;AAAA,QAC3G,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO,EAAE,OAAO;AAAA,EAClB;AAAA,EAEU,wBAA6C,YAAgD;AACrG,WAAO,EAAE,SAAS,WAAW,SAAS,UAAU,WAAW,UAAU,cAAc,WAAW,aAAa;AAAA,EAC7G;AACF;;;AC9HA,SAAS,aAAAC,kBAAiB;AAMnB,IAAM,qBAAN,cAAiC,uBAAuB;AAAA,EACpD,2BACP,iBACA,SACA,QACS;AACT,QAAI,KAAK,iBAAiB,QAAQA,WAAU,cAAc,GAAG;AAC3D,aAAO;AAAA,IACT;AACA,QAAI,KAAK,SAAS,MAAM,GAAG;AACzB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAES,qBACP,iBACA,SACA,aACgB;AAChB,UAAM,kBAAkB,YAAY,YAAY,SAAS,CAAC;AAC1D,QAAI,KAAK,SAAS,eAAe,GAAG;AAClC,aAAO,KAAK,sBAAsB,WAAW;AAAA,IAC/C;AACA,WAAO,KAAK,wBAAwB,eAAe;AAAA,EACrD;AACF;;;AC1BO,IAAM,0BAAN,cAAsC,uBAAuB;AAAA,EACzD,2BACP,iBACA,SACA,QACS;AAET,WAAO,KAAK,SAAS,MAAM;AAAA,EAC7B;AAAA,EAES,qBACP,iBACA,SACA,aACgB;AAChB,UAAM,kBAAkB,YAAY,YAAY,SAAS,CAAC;AAC1D,QAAI,KAAK,SAAS,eAAe,GAAG;AAClC,aAAO,KAAK,sBAAsB,WAAW;AAAA,IAC/C;AACA,WAAO,KAAK,wBAAwB,eAAe;AAAA,EACrD;AACF;;;ACrBA,SAAS,gBAAAC,qBAAoB;AAQtB,IAAM,qBAAN,cAAiC,uBAAuB;AAAA,EAG7D,YACU,kBACA,YACR;AACA,UAAM;AAHE;AACA;AAJV,SAAS,UAAU;AAAA,EAOnB;AAAA,EAES,qBACP,iBACA,SACA,aACgB;AA/BpB;AAgCI,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI,WAAW;AACf,eAAW,CAAC,GAAG,UAAU,KAAK,YAAY,QAAQ,GAAG;AACnD,UAAI,KAAK,SAAS,UAAU,GAAG;AAC7B,eAAO,KAAK,sBAAsB,WAAW;AAAA,MAC/C;AACA,UAAI,WAAW,aAAa,KAAK,kBAAkB;AACjD,6BAAqB;AAAA,MACvB;AACA,UAAI,MAAM,GAAG;AACX,0BAAkB;AAAA,MACpB;AACA,UAAI,OAAO,UAAU,eAAe,UAAU,WAAW,QAAQ,OAAO;AACtE,mBAAW;AAAA,MACb,OAAO;AACL,gBAAQ,WAAW,QAAQ;AAAA,MAC7B;AAAA,IACF;AAEA,QAAI,CAAC,oBAAoB;AACvB,YAAM,IAAIA,cAAa,mDAAmD;AAAA,IAC5E;AAEA,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAIA,cAAa,kDAAkD;AAAA,IAC3E;AAEA,QAAI,UAAU;AACZ,iBAAK,eAAL,8BAAkB;AAClB,aAAO;AAAA,QACL,SAAS,mBAAmB;AAAA,QAC5B,UAAU,mBAAmB;AAAA,MAC/B;AAAA,IACF;AAEA,WAAO,KAAK,wBAAwB,eAAe;AAAA,EACrD;AACF;;;AT5CO,IAAM,gBAAN,MAAM,eAAkC;AAAA,EAgB7C,YACW,sBACQ,qBAA6C,IAAI,mBAAmB,GACpE,SAAiB,IAAI,cAAc,GACpD;AAHS;AACQ;AACA;AAlBnB,SAAS,SAAS;AAElB,SAAgB,SAAS,IAAI,wBAAwB;AAErD,SAAQ,eAAwD,oBAAI,QAAwC;AAC5G,SAAQ,YAAmD,oBAAI,QAAsC;AAIrG,2BAAwC,CAAC;AACzC,SAAQ,wBAA4D,CAAC;AAGrE,SAAQ,gBAAgB,IAAI,cAAc,KAAK,MAAM;AAOnD,SAAK,eAAe,IAAI,aAAa,KAAK,MAAM;AAEhD,SAAK,kBAAkB,oBAAoB;AAE3C,UAAM,oBAAoB,OAAO,KAAK,KAAK,qBAAqB,EAAE,OAAO,CAAC,KAAK,SAAS;AACtF,aAAO,iCAAK,MAAL,EAAU,CAAC,IAAI,GAAG,KAAK,sBAAsB,IAAI,EAAE,SAAS,SAAS;AAAA,IAC9E,GAAG,CAAC,CAAC;AAEL,SAAK,WAAW,iCACX,oBADW;AAAA,MAEd,MAAM,eAAc;AAAA,IACtB;AAAA,EACF;AAAA,EAEQ,kBAAkB,sBAA4C;AA9DxE;AA+DI,UAAM,kBAA8C,CAAC;AAErD,eAAW,uBAAuB,sBAAsB;AACtD,YAAM,eAAe,oBAAoB,SAAS,SAAS;AAC3D,YAAM,iBAAgB,yBAAoB,SAApB,YAA4B;AAElD,UAAI,oBAAoB,QAAQ,gBAAgB,oBAAoB,IAAI,GAAG;AACzE,cAAM,IAAI,MAAM,+BAA+B;AAAA,MACjD;AAEA,4FAAmC,CAAC;AACpC,sBAAgB,aAAa,EAAE,KAAK,oBAAoB,QAAQ;AAAA,IAClE;AAEA,eAAW,QAAQ,OAAO,KAAK,eAAe,GAAG;AAC/C,YAAM,kBAAkB,gBAAgB,IAAI,EAAE,SAAS;AACvD,eAAS,IAAI,GAAG,IAAI,gBAAgB,IAAI,EAAE,QAAQ,KAAK;AACrD,cAAM,cAAc,kBAAkB,GAAG,IAAI,IAAI,IAAI,CAAC,KAAK;AAC3D,aAAK,sBAAsB,WAAW,IAAI,EAAE,UAAU,gBAAgB,IAAI,EAAE,CAAC,GAAG,MAAM,YAAY;AAClG,aAAK,gBAAgB,KAAK,KAAK,sBAAsB,WAAW,CAAC;AACjE,aAAK,cAAc,iBAAiB,KAAK,sBAAsB,WAAW,CAAC;AAAA,MAC7E;AAAA,IACF;AAGA,WAAO,OAAO,KAAK,eAAe;AAClC,WAAO,OAAO,KAAK,qBAAqB;AAAA,EAC1C;AAAA,EAEM,WAAW,SAA4C;AAAA;AAC3D,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,KAAK,gBAAgB,IAAI,CAAC,aAAU;AA9F1C;AA8F6C,sCAAS,UAAS,eAAlB,4BAA+B;AAAA,SAAQ;AAAA,MAChF;AACA,4CAAsC,QAAQ,KAAK,eAAe;AAAA,IACpE;AAAA;AAAA,EAEM,UAAyB;AAAA;AAC7B,YAAM,SAAS,MAAM,QAAQ,WAAW,KAAK,gBAAgB,IAAI,CAAC,aAAU;AApGhF;AAoGmF,oCAAS,UAAS,YAAlB;AAAA,OAA6B,CAAC;AAC7G,4CAAsC,QAAQ,KAAK,eAAe;AAAA,IACpE;AAAA;AAAA,EAEA,yBACE,SACA,cACA,SACqC;AACrC,WAAO,KAAK,oBAA6B,SAAS,WAAW,cAAc,OAAO;AAAA,EACpF;AAAA,EAEA,wBACE,SACA,cACA,SACoC;AACpC,WAAO,KAAK,oBAAoB,SAAS,UAAU,cAAc,OAAO;AAAA,EAC1E;AAAA,EAEA,wBACE,SACA,cACA,SACoC;AACpC,WAAO,KAAK,oBAAoB,SAAS,UAAU,cAAc,OAAO;AAAA,EAC1E;AAAA,EAEA,wBACE,SACA,cACA,SAC+B;AAC/B,WAAO,KAAK,oBAAoB,SAAS,UAAU,cAAc,OAAO;AAAA,EAC1E;AAAA,EAEc,oBACZ,SACA,UACA,cACA,SAC+B;AAAA;AA7InC;AA8II,YAAM,cAAc,KAAK,aAAa,IAAI,OAAO;AACjD,YAAM,YAAY,KAAK,UAAU,IAAI,OAAO;AAE5C,UAAI,CAAC,eAAe,CAAC,WAAW;AAC9B,cAAM,IAAIC,cAAa,2CAA2C;AAAA,MACpE;AAEA,YAAM,QAAkE,CAAC;AAEzE,iBAAW,iBAAiB,KAAK,iBAAiB;AAChD,cAAM,OAAO,KAAK;AAAA,UAChB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,cAAM,KAAK,IAAI;AAEf,YAAI,KAAK,mBAAmB,YAAY,cAAc;AACpD,gBAAM,CAAC,kBAAkB,IAAI,MAAM;AACnC,cAAI,CAAC,oBAAoB;AACvB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,MAAM,QAAQ,IAAI,KAAK;AACvC,YAAM,cAAc,QACjB,IAAI,CAAC,CAAC,EAAE,UAAU,MAAM,UAAU,EAClC,OAAO,CAAC,MAAwC,QAAQ,CAAC,CAAC;AAE7D,YAAM,cAAc,KAAK,mBAAmB,qBAAqB,EAAE,SAAS,SAAS,GAAG,SAAS,WAAW;AAE5G,WAAI,iBAAY,WAAZ,mBAAoB,QAAQ;AAC9B,cAAM,wBAAwB,YAAY,MAAM;AAAA,MAClD;AAEA,UAAI,CAAC,YAAY,SAAS;AACxB,cAAM,IAAIA,cAAa,0CAA0C;AAAA,MACnE;AAEA,aAAO,YAAY;AAAA,IACrB;AAAA;AAAA,EAEc,sBACZ,SACA,UACA,cACA,eACA,aACA,WACA,SACwD;AAAA;AACxD,UAAI,mBAAqD;AACzD,YAAM,WAAW,cAAc;AAC/B,YAAM,kBAAkB;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,cAAc;AAAA,QAC5B,gBAAgB,KAAK,cAAc,eAAe,cAAc,IAAI;AAAA,MACtE;AAEA,UAAI,CAAC,KAAK,mBAAmB,2BAA2B,iBAAiB,OAAO,GAAG;AACjF,eAAO,CAAC,MAAM,IAAI;AAAA,MACpB;AAEA,UAAI;AAEJ,UAAI;AACF,2BAAmB,MAAM,KAAK,yBAAyB,SAAS,cAAc,UAAU,aAAa,SAAS;AAC9G,qBAAa;AAAA,UACX,SAAS;AAAA,UACT;AAAA,UACA,cAAc,cAAc;AAAA,QAC9B;AAAA,MACF,SAAS,OAAgB;AACvB,qBAAa;AAAA,UACX,aAAa;AAAA,UACb;AAAA,UACA,cAAc,cAAc;AAAA,QAC9B;AAAA,MACF;AAEA,aAAO;AAAA,QACL,KAAK,mBAAmB,YAAY,eAChC,KAAK,mBAAmB,2BAA2B,iBAAiB,SAAS,UAAU,IACvF;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA;AAAA,EAEc,yBACZ,SACA,cACA,UACA,aACA,WACA;AAAA;AApPJ;AAqPI,UAAI,kBAAiD;AACrD,UAAI;AAGJ,YAAM,kBAAkB,iCAAK,cAAL,EAAkB,SAAS,mBAAK,YAAY,SAAU;AAE9E,UAAI;AAEF,0BAAkB,MAAM,KAAK,aAAa,YAAY,SAAS,OAAO,iBAAiB,SAAS;AAEhG,cAAM,oBAAqB,MAAM,KAAK;AAAA,UACpC;AAAA,UACA;AAAA,UACA;AAAA,UACA,mBAAmB,CAAC;AAAA,QACtB;AAEA,4BAAoB,iCACf,oBADe;AAAA,UAElB,cAAc,OAAO,QAAO,uBAAkB,iBAAlB,YAAkC,CAAC,CAAC;AAAA,UAChE;AAAA,QACF;AAEA,cAAM,KAAK,aAAa,WAAW,SAAS,OAAO,iBAAiB,mBAAmB,SAAS;AAAA,MAClG,SAAS,OAAgB;AACvB,cAAM,KAAK,aAAa,WAAW,SAAS,OAAO,iBAAiB,OAAO,SAAS;AACpF,4BAAoB,KAAK,0BAA0B,SAAS,cAAc,KAAK;AAAA,MACjF;AACA,YAAM,KAAK,aAAa,aAAa,SAAS,OAAO,iBAAiB,mBAAmB,SAAS;AAClG,aAAO;AAAA,IACT;AAAA;AAAA,EAEc,oBACZ,UACA,SACA,cACA,SACA;AAAA;AACA,cAAQ,OAAO,cAAc;AAAA,QAC3B,KAAK;AACH,iBAAO,MAAM,SAAS,wBAAwB,SAAS,cAAc,SAAS,KAAK,MAAM;AAAA,QAC3F,KAAK;AACH,iBAAO,MAAM,SAAS,wBAAwB,SAAS,cAAc,SAAS,KAAK,MAAM;AAAA,QAC3F,KAAK;AACH,iBAAO,MAAM,SAAS,wBAAwB,SAAS,cAAc,SAAS,KAAK,MAAM;AAAA,QAC3F,KAAK;AACH,iBAAO,MAAM,SAAS,yBAAyB,SAAS,cAAc,SAAS,KAAK,MAAM;AAAA,QAC5F;AACE,gBAAM,IAAIA,cAAa,8BAA8B;AAAA,MACzD;AAAA,IACF;AAAA;AAAA,EAEA,IAAW,QAAgB;AACzB,WAAO;AAAA,MACL;AAAA,QACE,QAAQ,CAAO,aAAgC,UAAiD;AAC9F,eAAK,aAAa,IAAI,YAAY,SAAS,WAAW;AACtD,eAAK,UAAU,IAAI,YAAY,SAAS,wBAAS,CAAC,CAAC;AACnD,iBAAO,YAAY;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,mBAA2B,SAA4B,sBAAkD;AArTjH;AAsTI,eAAW,iBAAiB,KAAK,iBAAiB;AAChD,UAAI,CAAC,cAAc,SAAS,OAAO;AACjC;AAAA,MACF;AAEA,YAAM,kBAAkB;AAAA,QACtB,UAAU,cAAc;AAAA,QACxB,cAAc,cAAc;AAAA,QAC5B,gBAAgB,KAAK,cAAc,eAAe,cAAc,IAAI;AAAA,MACtE;AAEA,UACE,KAAK,mBAAmB;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,GACA;AACA,YAAI;AACF,oCAAc,UAAS,UAAvB,4BAA+B,mBAAmB,SAAS;AAAA,QAC7D,SAAS,OAAO;AAEd,eAAK,OAAO;AAAA,YACV,yBAAyB,iBAAiB,oBAAoB,cAAc,IAAI;AAAA,YAChF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,0BACN,SACA,cACA,KACA,eAA6B,CAAC,GACR;AACtB,UAAM,eAAwB,2BAAe;AAC7C,UAAM,aAAwB,2BAA0B,SAAQC,WAAU;AAE1E,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,QAAQC,2BAA0B;AAAA,MAClC,cAAc,OAAO,OAAO,YAAY;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AACF;;;AUpWA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACOP;AAAA,EACE,aAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,6BAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAuBA,IAAM,oBAAN,MAA0C;AAAA,EAK/C,YAGmB,kBACA,wBACA,iBACA,oBACA,kBACA,4BACA,cACA,SACjB,UAA6B,CAAC,GAC9B;AATiB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAbnB,SAAQ,SAAiB,CAAC;AAgBxB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,IAAI,WAA2B;AArEjC;AAsEI,WAAO;AAAA;AAAA,MAEL,OAAM,UAAK,QAAQ,WAAb,YAAuB,KAAK,QAAQ;AAAA,MAC1C,SAAQ,UAAK,QAAQ,WAAb,YAAuB,KAAK,QAAQ;AAAA,MAC5C,SAAS,KAAK,QAAQ;AAAA,MACtB,kBAAkB,KAAK,iBAAiB,EAAE;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,IAAI,iBAAiC;AACnC,WAAO,KAAK,uBAAuB;AAAA,EACrC;AAAA,EAEA,WAAW,WAA2B,SAAuB,SAA8B;AAnF7F;AAoFI,SAAK,gBAAgB,EAAE,WAAW,WAAW,OAAO;AACpD,UAAM,eAAe,mBAAmB,WAAW,KAAK,eAAe;AAEvE,QAAI,cAAc;AAEhB,UAAI;AACF,gBAAQ;AAAA,UACN,YAAY,KAAK,SAAS;AAAA,UAC1B,QAAQ,KAAK,SAAS;AAAA,UACtB,cAAc,KAAK,UAAU,SAAS;AAAA,QACxC,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,mBAAK,YAAL,mBAAc,MAAM,gCAAgC;AAAA,MACtD;AAAA,IACF;AAEA,SAAI,mCAAS,WAAU,OAAO,QAAQ,OAAO,qBAAqB,YAAY;AAC5E,cAAQ,OAAO,iBAAiB,SAAS,MAAM;AAC7C,aAAK,cAAc,WAAW,OAAO;AAAA,MACvC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,cAAc,WAA2B,SAAuB;AAC9D,SAAK,gBAAgB,EAAE,cAAc,WAAW,OAAO;AAAA,EACzD;AAAA,EAEA,YAAY,WAA2B;AACrC,WAAO,KAAK,gBAAgB,EAAE,YAAY,SAAS;AAAA,EACrD;AAAA,EAEA,UAAU,QAAmC;AAC3C,SAAK,gBAAgB,IAAI,WAAW,MAAM;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,SAA+C;AACxD,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,aAAgC;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAY,OAAkC;AAC5C,SAAK,SAAS,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,WAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAgC;AAC9B,SAAK,SAAS,CAAC;AACf,WAAO;AAAA,EACT;AAAA,EAEM,gBACJ,SACA,cACA,SACA,SACkB;AAAA;AAClB,cAAQ,MAAM,KAAK,kBAAkB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,IACjF;AAAA;AAAA,EAEA,kBACE,SACA,cACA,SACA,SACqC;AACrC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,KAAK,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEM,eACJ,SACA,cACA,SACA,SACY;AAAA;AACZ,cAAQ,MAAM,KAAK,iBAAoB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,IACnF;AAAA;AAAA,EAEA,iBACE,SACA,cACA,SACA,SAC+B;AAC/B,WAAO,KAAK;AAAA,MACV;AAAA;AAAA,MAEA,KAAK,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEM,eACJ,SACA,cACA,SACA,SACY;AAAA;AACZ,cAAQ,MAAM,KAAK,iBAAiB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,IAChF;AAAA;AAAA,EAEA,iBACE,SACA,cACA,SACA,SAC+B;AAC/B,WAAO,KAAK;AAAA,MACV;AAAA;AAAA,MAEA,KAAK,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEM,eACJ,SACA,cACA,SACA,SACY;AAAA;AACZ,cAAQ,MAAM,KAAK,iBAAiB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,IAChF;AAAA;AAAA,EAEA,iBACE,SACA,cACA,SACA,SAC+B;AAC/B,WAAO,KAAK,SAAY,SAAS,KAAK,UAAU,yBAAyB,cAAc,UAAU,SAAS,OAAO;AAAA,EACnH;AAAA,EAEA,MAAM,eAAuB,UAA6B,CAAC,GAAG,oBAA0C,CAAC,GAAS;AA9OpH;AA+OI,QAAI;AACF,WAAK,uBAAuB;AAE5B,UAAI,OAAO,KAAK,UAAU,UAAU,YAAY;AAE9C,cAAM,gBAAgB,OAAO,OAAO,KAAK,cAAc,OAAO,CAAC;AAC/D,gBAAO,gBAAK,WAAU,UAAf,4BAAuB,eAAe,eAAe;AAAA,MAC9D,OAAO;AACL,aAAK,QAAQ,MAAM,2DAA2D;AAAA,MAChF;AAAA,IACF,SAAS,KAAK;AACZ,WAAK,QAAQ,MAAM,mCAAmC,GAAG;AAAA,IAC3D;AAAA,EACF;AAAA,EAEc,SACZ,IACA,IAMA,IACA,IAG+B;AAAA,+CAX/B,SACA,UAMA,cACA,UACA,oBAAuC,CAAC,GACxC,UAAiC,CAAC,GACH;AA1QnC;AA6QI,YAAM,WAAW;AAAA,QACf,GAAG,KAAK,iBAAiB;AAAA,QACzB,GAAG,KAAK,SAAS;AAAA,QACjB,GAAI,QAAQ,SAAS,CAAC;AAAA,QACtB,GAAI,KAAK,UAAU,SAAS,CAAC;AAAA,MAC/B;AACA,YAAM,mBAAmB,CAAC,GAAG,QAAQ,EAAE,QAAQ;AAE/C,YAAM,gBAAgB,KAAK,cAAc,iBAAiB;AAK1D,YAAM,eAAe,iBAAiB;AAAA,QAAiB,MACrD,OAAO,OAAO;AAAA,UACZ;AAAA,UACA;AAAA,UACA,eAAe;AAAA,UACf,gBAAgB,KAAK;AAAA,UACrB,kBAAkB,KAAK,UAAU;AAAA,UACjC,SAAS;AAAA,UACT,QAAQ,KAAK;AAAA,UACb,UAAU,IAAI,YAAY;AAAA,QAC5B,CAAC;AAAA,MACH;AAEA,UAAI;AAEJ,UAAI;AACF,cAAM,gBAAgB,MAAM,KAAK,YAAY,UAAU,cAAc,eAAe,OAAO;AAE3F,aAAK,uBAAuB;AAG5B,cAAM,aAAa,MAAM,SAAS,KAAK,KAAK,WAAW,SAAS,cAAc,eAAe,KAAK,OAAO;AAEzG,cAAM,oBAAoB,iCACrB,aADqB;AAAA,UAExB,cAAc,OAAO,QAAO,gBAAW,iBAAX,YAA2B,CAAC,CAAC;AAAA,UACzD;AAAA,QACF;AAEA,YAAI,kBAAkB,WAAW;AAC/B,gBAAM,MAAM,4BAA4B,kBAAkB,WAAW,kBAAkB,YAAY;AACnG,gBAAM,KAAK,WAAW,kBAAkB,cAAc,KAAK,OAAO;AAClE,8BAAoB,KAAK,0BAA0B,SAAS,cAAc,KAAK,kBAAkB,YAAY;AAAA,QAC/G,OAAO;AACL,gBAAM,KAAK,WAAW,kBAAkB,cAAc,mBAAmB,OAAO;AAChF,8BAAoB;AAAA,QACtB;AAAA,MACF,SAAS,KAAc;AACrB,cAAM,KAAK,WAAW,kBAAkB,cAAc,KAAK,OAAO;AAClE,4BAAoB,KAAK,0BAA0B,SAAS,cAAc,GAAG;AAAA,MAC/E;AAEA,YAAM,KAAK,aAAa,kBAAkB,cAAc,mBAAmB,OAAO;AAClF,aAAO;AAAA,IACT;AAAA;AAAA,EAEc,YACZ,OACA,cACA,eACA,SACA;AAAA;AA7UJ;AA8UI,YAAM,qBAAqB;AAE3B,iBAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,cAAM,mBAAmB,MAAM,SAAS,IAAI;AAC5C,cAAM,cAAc,aAAa,gBAAgB;AAGjD,eAAO,OAAO,YAAY,SAAS,kBAAkB;AAErD,cAAM,aAAa,OAAM,kCAAM,WAAN,8BAAe,aAAa,OAAO,OAAO,QAAQ,SAAS;AACpF,YAAI,YAAY;AACd,iBAAO,OAAO,oBAAoB,UAAU;AAE5C,mBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,mBAAO,OAAO,aAAa,gBAAgB,EAAE,SAAS,kBAAkB;AAAA,UAC1E;AAAA,QACF;AAAA,MACF;AAGA,aAAO,OAAO,OAAO,kBAAkB;AAAA,IACzC;AAAA;AAAA,EAEc,WACZ,OACA,cACA,mBACA,SACA;AAAA;AA1WJ;AA4WI,iBAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,cAAM,cAAc,aAAa,KAAK;AACtC,eAAM,kCAAM,UAAN,8BAAc,aAAa,mBAAmB,QAAQ;AAAA,MAC9D;AAAA,IACF;AAAA;AAAA,EAEc,WAAW,OAAe,cAA6B,KAAc,SAAgC;AAAA;AAlXrH;AAoXI,iBAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,YAAI;AACF,gBAAM,cAAc,aAAa,KAAK;AACtC,iBAAM,kCAAM,UAAN,8BAAc,aAAa,KAAK,QAAQ;AAAA,QAChD,SAASC,MAAK;AACZ,eAAK,QAAQ,MAAM,wCAAwCA,IAAG,EAAE;AAChE,cAAIA,gBAAe,OAAO;AACxB,iBAAK,QAAQ,MAAMA,KAAI,KAAK;AAAA,UAC9B;AACA,eAAK,QAAQ,MAAOA,QAAA,gBAAAA,KAAe,KAAK;AAAA,QAC1C;AAAA,MACF;AAAA,IACF;AAAA;AAAA,EAEc,aACZ,OACA,cACA,mBACA,SACA;AAAA;AAvYJ;AAyYI,iBAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,YAAI;AACF,gBAAM,cAAc,aAAa,KAAK;AACtC,iBAAM,kCAAM,YAAN,8BAAgB,aAAa,mBAAmB,QAAQ;AAAA,QAChE,SAAS,KAAK;AACZ,eAAK,QAAQ,MAAM,0CAA0C,GAAG,EAAE;AAClE,cAAI,eAAe,OAAO;AACxB,iBAAK,QAAQ,MAAM,IAAI,KAAK;AAAA,UAC9B;AACA,eAAK,QAAQ,MAAO,2BAAe,KAAK;AAAA,QAC1C;AAAA,MACF;AAAA,IACF;AAAA;AAAA,EAEA,IAAY,YAAsB;AAChC,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA,EAEA,IAAY,kBAAkC;AAC5C,WAAO,KAAK,uBAAuB;AAAA,EACrC;AAAA,EAEA,IAAY,UAAU;AACpB,WAAO,KAAK,iBAAiB,KAAK,aAAa;AAAA,EACjD;AAAA,EAEQ,cAAc,mBAAsC;AAE1D,WAAO,gEACF,KAAK,mBAAmB,IACxB,KAAK,2BAA2B,IAChC,KAAK,WACL;AAAA,EAEP;AAAA,EAEQ,yBAAyB;AAE/B,QAAI,KAAK,mBAAmB,qBAAe,WAAW;AACpD,YAAM,IAAI,sBAAsB,kCAAkC;AAAA,IACpE,WAAW,KAAK,mBAAmB,qBAAe,OAAO;AACvD,YAAM,IAAI,mBAAmB,6CAA6C;AAAA,IAC5E;AAAA,EACF;AAAA,EAEQ,0BACN,SACA,cACA,KACA,eAA6B,CAAC,GACR;AACtB,UAAM,eAAwB,2BAAe;AAC7C,UAAM,aAAwB,2BAA0B,SAAQC,WAAU;AAE1E,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,QAAQC,2BAA0B;AAAA,MAClC,cAAc,OAAO,OAAO,YAAY;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AACF;;;ACrcA,IAAM,mCAAN,MAA+E;AAAA,EAC7E,wBAA2C;AACzC,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,sBACE,GACA,aACG,MACG;AACN,aAAS,GAAG,IAAI;AAAA,EAClB;AACF;AAEO,IAAM,sCAAsC,IAAI,iCAAiC;;;ACfxF,SAAS,yBAAyB;AAE3B,IAAM,gDAAN,MAA4F;AAAA,EAA5F;AACL,SAAQ,oBAAoB,IAAI,kBAAqC;AAAA;AAAA,EAErE,wBAA2C;AAP7C;AAQI,YAAO,UAAK,kBAAkB,SAAS,MAAhC,YAAqC,CAAC;AAAA,EAC/C;AAAA,EAEA,sBACE,oBACA,aACG,MACG;AACN,SAAK,kBAAkB,IAAI,oBAAoB,UAAU,GAAG,IAAI;AAAA,EAClE;AACF;;;AHOA,IAAM,6BAA6B,OAAO,IAAI,yBAAyB;AAKvE,IAAM,cAAc;AAEb,IAAM,iBAAN,MAAM,wBACH,qBAIV;AAAA,EAaU,cAAc;AACpB,UAAM,QAAQ;AAbhB,SAAU,kBAAyC;AACnD,SAAU,cAAc,IAAI,wBAAwB;AACpD,SAAU,mBAAoE,IAAI;AAAA,MAChF;AAAA,MACA,qBAAe;AAAA,MACf,KAAK;AAAA,IACP;AACA,SAAU,yBAAuF,oBAAI,IAAI;AACzG,SAAU,sBAAsB,MAAM,IAAI,wBAAwB;AAElE,SAAQ,gCAA8D;AAAA,EAItE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,cAA8B;AACnC,UAAM,YAAY,YAAY,0BAA0B;AACxD,QAAI,WAAW;AACb,aAAO;AAAA,IACT;AAEA,UAAM,WAAW,IAAI,gBAAe;AACpC,gBAAY,0BAA0B,IAAI;AAC1C,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB,QAAiC;AAtE7D;AAuEI,QAAI,CAAC,QAAQ;AACX,aAAO,KAAK,iBAAiB;AAAA,IAC/B;AAEA,YAAO,gBAAK,uBAAuB,IAAI,MAAM,MAAtC,mBAAyC,WAAzC,YAAmD,KAAK,iBAAiB;AAAA,EAClF;AAAA,EAqBM,mBAAmB,kBAAsC,qBAA+C;AAAA;AAC5G,YAAM,SAAS,kBAAkB,gBAAgB;AACjD,YAAM,WAAW,SACb,kBAA4B,mBAAmB,IAC/C,kBAA4B,gBAAgB;AAEhD,YAAM,KAAK,qBAAqB,QAAQ,QAAQ;AAAA,IAClD;AAAA;AAAA,EAkBA,YAAY,kBAAsC,qBAAsC;AACtF,UAAM,SAAS,kBAAkB,gBAAgB;AACjD,UAAM,WAAW,SACb,kBAA4B,mBAAmB,IAC/C,kBAA4B,gBAAgB;AAEhD,UAAM,eAAe,KAAK,qBAAqB,QAAQ,QAAQ;AAK/D,YAAQ,QAAQ,YAAY,EAAE,MAAM,CAAC,QAAQ;AAC3C,WAAK,QAAQ,MAAM,yCAAyC,GAAG;AAAA,IACjE,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAmBA,YAAY,QAA2B;AACrC,WAAO,KAAK,qBAAqB,MAAM;AAAA,EACzC;AAAA,EAEA,WAAW,SAAkC;AAC3C,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,aAAgC;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA,EAqCA,UACE,iBACA,kBACA,oBACQ;AAjNZ;AAkNI,UAAM,SAAS,kBAAkB,eAAe;AAChD,UAAM,UAAU,kBAAkB,gBAAgB;AAClD,UAAM,WACJ,6BAAqC,eAAe,MAApD,YACA,kBAAqC,gBAAgB,MADrD,YAEA,kBAAqC,kBAAkB;AAEzD,WAAO,IAAI;AAAA,MACT,MAAM,KAAK,qBAAqB,MAAM;AAAA,MACtC,MAAM,KAAK,kBAAkB,MAAM;AAAA,MACnC,MAAM,KAAK,mCAAmC,MAAM;AAAA,MACpD,MAAM,KAAK,WAAW;AAAA,MACtB,MAAM,KAAK,SAAS;AAAA,MACpB,MAAM,KAAK,sBAAsB;AAAA,MACjC,MAAM,KAAK;AAAA,MACX,EAAE,QAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAgC;AAC9B,WAAO,MAAM,4BAA4B,aAAa;AAAA,EACxD;AAAA,EAEA,gCACE,8BACsD;AACtD,UAAM,cAAc;AACpB,QAAI,QAAO,6EAA8B,2BAA0B,YAAY;AAC7E,WAAK,QAAQ,MAAM,GAAG,WAAW,4CAA4C;AAAA,IAC/E,WAAW,QAAO,6EAA8B,2BAA0B,YAAY;AACpF,WAAK,QAAQ,MAAM,GAAG,WAAW,4CAA4C;AAAA,IAC/E,OAAO;AACL,WAAK,gCAAgC;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,sBACE,oBACA,aACG,MACG;AACN,SAAK,8BAA8B,sBAAsB,oBAAoB,UAAU,GAAG,IAAI;AAAA,EAChG;AAAA,EAEA,wBAA4C;AAC1C,QAAI;AACF,aAAO,KAAK,8BAA8B,sBAAsB;AAAA,IAClE,SAAS,KAAc;AACrB,YAAM,QAAQ;AACd,WAAK,QAAQ,MAAM,sCAAsC,+BAAO,OAAO,4BAA4B;AACnG,WAAK,QAAQ,MAAM,+BAAO,KAAK;AAC/B,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF;AAMO,IAAM,cAAc,eAAe,YAAY;;;AI5QtD,cAAc;",
6
+ "names": ["OpenFeatureError", "OpenFeatureError", "ErrorCode", "GeneralError", "StandardResolutionReasons", "GeneralError", "OpenFeatureError", "err", "ErrorCode", "GeneralError", "GeneralError", "ErrorCode", "StandardResolutionReasons", "ErrorCode", "StandardResolutionReasons", "err", "ErrorCode", "StandardResolutionReasons"]
7
7
  }
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { BaseHook, FlagValue, EvaluationContext, HookHints, EvaluationDetails, JsonValue, CommonProvider, ServerProviderStatus, Logger, ResolutionDetails, GenericEventEmitter, ServerProviderEvents, TrackingEventDetails, EvaluationLifeCycle, ManageContext, ManageLogger, Eventing, ClientMetadata, OpenFeatureCommonAPI, ProviderWrapper } from '@openfeature/core';
1
+ import { BaseHook, FlagValue, EvaluationContext, HookHints, EvaluationDetails, JsonValue, CommonProvider, ServerProviderStatus, Logger, ResolutionDetails, GenericEventEmitter, ServerProviderEvents, FlagValueType, TrackingEventDetails, ErrorCode, ProviderMetadata, OpenFeatureError, GeneralError, EvaluationLifeCycle, ManageContext, ManageLogger, Eventing, ClientMetadata, OpenFeatureCommonAPI, ProviderWrapper } from '@openfeature/core';
2
2
  export * from '@openfeature/core';
3
3
  export { ServerProviderEvents as ProviderEvents, ServerProviderStatus as ProviderStatus } from '@openfeature/core';
4
4
  import { EventEmitter } from 'node:events';
@@ -213,6 +213,149 @@ declare class OpenFeatureEventEmitter extends GenericEventEmitter<ServerProvider
213
213
  constructor();
214
214
  }
215
215
 
216
+ type StrategyEvaluationContext = {
217
+ flagKey: string;
218
+ flagType: FlagValueType;
219
+ };
220
+ type StrategyProviderContext = {
221
+ provider: Provider;
222
+ providerName: string;
223
+ providerStatus: ServerProviderStatus;
224
+ };
225
+ type StrategyPerProviderContext = StrategyEvaluationContext & StrategyProviderContext;
226
+ type ProviderResolutionResultBase = {
227
+ provider: Provider;
228
+ providerName: string;
229
+ };
230
+ type ProviderResolutionSuccessResult<T extends FlagValue> = ProviderResolutionResultBase & {
231
+ details: ResolutionDetails<T>;
232
+ };
233
+ type ProviderResolutionErrorResult = ProviderResolutionResultBase & {
234
+ thrownError: unknown;
235
+ };
236
+ type ProviderResolutionResult<T extends FlagValue> = ProviderResolutionSuccessResult<T> | ProviderResolutionErrorResult;
237
+ type FinalResult<T extends FlagValue> = {
238
+ details?: ResolutionDetails<T>;
239
+ provider?: Provider;
240
+ providerName?: string;
241
+ errors?: {
242
+ providerName: string;
243
+ error: unknown;
244
+ }[];
245
+ };
246
+ /**
247
+ * Base strategy to inherit from. Not directly usable, as strategies must implement the "determineResult" method
248
+ * Contains default implementations for `shouldEvaluateThisProvider` and `shouldEvaluateNextProvider`
249
+ */
250
+ declare abstract class BaseEvaluationStrategy {
251
+ runMode: 'parallel' | 'sequential';
252
+ shouldEvaluateThisProvider(strategyContext: StrategyPerProviderContext, _evalContext?: EvaluationContext): boolean;
253
+ shouldEvaluateNextProvider<T extends FlagValue>(_strategyContext?: StrategyPerProviderContext, _context?: EvaluationContext, _result?: ProviderResolutionResult<T>): boolean;
254
+ shouldTrackWithThisProvider(strategyContext: StrategyProviderContext, _context?: EvaluationContext, _trackingEventName?: string, _trackingEventDetails?: TrackingEventDetails): boolean;
255
+ abstract determineFinalResult<T extends FlagValue>(strategyContext: StrategyEvaluationContext, context: EvaluationContext, resolutions: ProviderResolutionResult<T>[]): FinalResult<T>;
256
+ protected hasError(resolution: ProviderResolutionResult<FlagValue>): resolution is ProviderResolutionErrorResult | (ProviderResolutionSuccessResult<FlagValue> & {
257
+ details: ResolutionDetails<FlagValue> & {
258
+ errorCode: ErrorCode;
259
+ };
260
+ });
261
+ protected hasErrorWithCode(resolution: ProviderResolutionResult<FlagValue>, code: ErrorCode): boolean;
262
+ protected collectProviderErrors<T extends FlagValue>(resolutions: ProviderResolutionResult<T>[]): FinalResult<T>;
263
+ protected resolutionToFinalResult<T extends FlagValue>(resolution: ProviderResolutionSuccessResult<T>): {
264
+ details: ResolutionDetails<T>;
265
+ provider: Provider;
266
+ providerName: string;
267
+ };
268
+ }
269
+
270
+ /**
271
+ * Return the first result that did not indicate "flag not found".
272
+ * If any provider in the course of evaluation returns or throws an error, throw that error
273
+ */
274
+ declare class FirstMatchStrategy extends BaseEvaluationStrategy {
275
+ shouldEvaluateNextProvider<T extends FlagValue>(strategyContext: StrategyPerProviderContext, context: EvaluationContext, result: ProviderResolutionResult<T>): boolean;
276
+ determineFinalResult<T extends FlagValue>(strategyContext: StrategyPerProviderContext, context: EvaluationContext, resolutions: ProviderResolutionResult<T>[]): FinalResult<T>;
277
+ }
278
+
279
+ /**
280
+ * Return the first result that did NOT result in an error
281
+ * If any provider in the course of evaluation returns or throws an error, ignore it as long as there is a successful result
282
+ * If there is no successful result, throw all errors
283
+ */
284
+ declare class FirstSuccessfulStrategy extends BaseEvaluationStrategy {
285
+ shouldEvaluateNextProvider<T extends FlagValue>(strategyContext: StrategyPerProviderContext, context: EvaluationContext, result: ProviderResolutionResult<T>): boolean;
286
+ determineFinalResult<T extends FlagValue>(strategyContext: StrategyPerProviderContext, context: EvaluationContext, resolutions: ProviderResolutionResult<T>[]): FinalResult<T>;
287
+ }
288
+
289
+ /**
290
+ * Evaluate all providers in parallel and compare the results.
291
+ * If the values agree, return the value
292
+ * If the values disagree, return the value from the configured "fallback provider" and execute the "onMismatch"
293
+ * callback if defined
294
+ */
295
+ declare class ComparisonStrategy extends BaseEvaluationStrategy {
296
+ private fallbackProvider;
297
+ private onMismatch?;
298
+ runMode: "parallel";
299
+ constructor(fallbackProvider: Provider, onMismatch?: ((resolutions: ProviderResolutionResult<FlagValue>[]) => void) | undefined);
300
+ determineFinalResult<T extends FlagValue>(strategyContext: StrategyPerProviderContext, context: EvaluationContext, resolutions: ProviderResolutionResult<T>[]): FinalResult<T>;
301
+ }
302
+
303
+ type ProviderEntryInput = {
304
+ provider: Provider;
305
+ name?: string;
306
+ };
307
+ type RegisteredProvider = Required<ProviderEntryInput>;
308
+
309
+ declare class MultiProvider implements Provider {
310
+ readonly constructorProviders: ProviderEntryInput[];
311
+ private readonly evaluationStrategy;
312
+ private readonly logger;
313
+ readonly runsOn = "server";
314
+ readonly events: OpenFeatureEventEmitter;
315
+ private hookContexts;
316
+ private hookHints;
317
+ metadata: ProviderMetadata;
318
+ providerEntries: RegisteredProvider[];
319
+ private providerEntriesByName;
320
+ private hookExecutor;
321
+ private statusTracker;
322
+ constructor(constructorProviders: ProviderEntryInput[], evaluationStrategy?: BaseEvaluationStrategy, logger?: Logger);
323
+ private registerProviders;
324
+ initialize(context?: EvaluationContext): Promise<void>;
325
+ onClose(): Promise<void>;
326
+ resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, context: EvaluationContext): Promise<ResolutionDetails<boolean>>;
327
+ resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext): Promise<ResolutionDetails<string>>;
328
+ resolveNumberEvaluation(flagKey: string, defaultValue: number, context: EvaluationContext): Promise<ResolutionDetails<number>>;
329
+ resolveObjectEvaluation<U extends JsonValue>(flagKey: string, defaultValue: U, context: EvaluationContext): Promise<ResolutionDetails<U>>;
330
+ private flagResolutionProxy;
331
+ private evaluateProviderEntry;
332
+ private evaluateProviderAndHooks;
333
+ private callProviderResolve;
334
+ get hooks(): Hook[];
335
+ track(trackingEventName: string, context: EvaluationContext, trackingEventDetails: TrackingEventDetails): void;
336
+ private getErrorEvaluationDetails;
337
+ }
338
+
339
+ declare class ErrorWithCode extends OpenFeatureError {
340
+ code: ErrorCode;
341
+ constructor(code: ErrorCode, message: string);
342
+ }
343
+ declare class AggregateError extends GeneralError {
344
+ originalErrors: {
345
+ source: string;
346
+ error: unknown;
347
+ }[];
348
+ constructor(message: string, originalErrors: {
349
+ source: string;
350
+ error: unknown;
351
+ }[]);
352
+ }
353
+ declare const constructAggregateError: (providerErrors: {
354
+ error: unknown;
355
+ providerName: string;
356
+ }[]) => AggregateError;
357
+ declare const throwAggregateErrorFromPromiseResults: (result: PromiseSettledResult<unknown>[], providerEntries: RegisteredProvider[]) => void;
358
+
216
359
  interface Tracking {
217
360
  /**
218
361
  * Track a user action or application state, usually representing a business objective or outcome.
@@ -417,5 +560,5 @@ declare class OpenFeatureAPI extends OpenFeatureCommonAPI<ServerProviderStatus,
417
560
  */
418
561
  declare const OpenFeature: OpenFeatureAPI;
419
562
 
420
- export { AsyncLocalStorageTransactionContextPropagator, InMemoryProvider, NOOP_PROVIDER, NOOP_TRANSACTION_CONTEXT_PROPAGATOR, OpenFeature, OpenFeatureAPI, OpenFeatureEventEmitter };
421
- export type { Client, Features, FlagEvaluationOptions, Hook, ManageTransactionContextPropagator, Provider, Tracking, TransactionContext, TransactionContextPropagator };
563
+ export { AggregateError, AsyncLocalStorageTransactionContextPropagator, BaseEvaluationStrategy, ComparisonStrategy, ErrorWithCode, FirstMatchStrategy, FirstSuccessfulStrategy, InMemoryProvider, MultiProvider, NOOP_PROVIDER, NOOP_TRANSACTION_CONTEXT_PROPAGATOR, OpenFeature, OpenFeatureAPI, OpenFeatureEventEmitter, constructAggregateError, throwAggregateErrorFromPromiseResults };
564
+ export type { Client, Features, FinalResult, FlagEvaluationOptions, Hook, ManageTransactionContextPropagator, Provider, ProviderResolutionErrorResult, ProviderResolutionResult, ProviderResolutionSuccessResult, StrategyEvaluationContext, StrategyPerProviderContext, StrategyProviderContext, Tracking, TransactionContext, TransactionContextPropagator };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfeature/server-sdk",
3
- "version": "1.19.0",
3
+ "version": "1.20.1",
4
4
  "description": "OpenFeature SDK for JavaScript",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "files": [