UNPKG

@flags-sdk/flagsmith

Version:

Flagsmith provider for the Flags SDK

1 lines 8.5 kB
{"version":3,"sources":["../src/index.ts","../src/provider/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Adapter } from 'flags';\nimport flagsmith from 'flagsmith';\nimport { IIdentity, IInitConfig, IFlagsmithFeature } from 'flagsmith/types';\n\nexport type { IIdentity } from 'flagsmith/types';\nexport { getProviderData } from './provider';\n\nlet defaultFlagsmithAdapter: AdapterResponse | undefined;\n\nexport type FlagsmithValue = IFlagsmithFeature['value'];\n\nexport type EntitiesType = IIdentity;\n\nexport type AdapterResponse = {\n booleanValue: () => Adapter<boolean, EntitiesType>;\n stringValue: () => Adapter<string, EntitiesType>;\n numberValue: () => Adapter<number, EntitiesType>;\n};\n\nfunction createFlagsmithAdapter(params: IInitConfig): AdapterResponse {\n async function initialize() {\n await flagsmith.init({ fetch: globalThis.fetch, ...params });\n }\n\n function booleanValue(): Adapter<boolean, EntitiesType> {\n return {\n async decide({\n key,\n defaultValue,\n entities: identity,\n }): Promise<boolean> {\n await initialize();\n\n if (identity) {\n await flagsmith.identify(identity);\n }\n const state = flagsmith.getState();\n const flagState = state.flags?.[key];\n\n if (!flagState) {\n return defaultValue as boolean;\n }\n\n return flagState.enabled;\n },\n };\n }\n\n function stringValue(): Adapter<string, EntitiesType> {\n return {\n async decide({ key, defaultValue, entities: identity }): Promise<string> {\n await initialize();\n\n if (identity) {\n await flagsmith.identify(identity);\n }\n const state = flagsmith.getState();\n const flagState = state.flags?.[key];\n\n if (!flagState || !flagState.enabled) {\n return defaultValue as string;\n }\n\n return flagState.value as string;\n },\n };\n }\n\n function numberValue(): Adapter<number, EntitiesType> {\n return {\n async decide({ key, defaultValue, entities: identity }): Promise<number> {\n await initialize();\n\n if (identity) {\n await flagsmith.identify(identity);\n }\n const state = flagsmith.getState();\n const flagState = state.flags?.[key];\n\n if (!flagState || !flagState.enabled) {\n return defaultValue as number;\n }\n\n return flagState.value as number;\n },\n };\n }\n\n return {\n booleanValue,\n stringValue,\n numberValue,\n };\n}\n\nfunction assertEnv(name: string): string {\n const value = process.env[name];\n console.log('value', process.env);\n if (!value) {\n throw new Error(`Flagsmith Adapter: Missing ${name} environment variable`);\n }\n return value;\n}\n\nexport const getOrCreateDefaultFlagsmithAdapter = () => {\n if (!defaultFlagsmithAdapter) {\n const environmentId = assertEnv('FLAGSMITH_ENVIRONMENT_ID');\n defaultFlagsmithAdapter = createFlagsmithAdapter({\n environmentID: environmentId,\n });\n }\n return defaultFlagsmithAdapter;\n};\n\n// Lazy default adapter\nexport const flagsmithAdapter: AdapterResponse =\n getOrCreateDefaultFlagsmithAdapter();\n","import type { FlagDefinitionType, ProviderData } from 'flags';\n\ntype FlagsmithApiData = {\n id: number;\n feature: {\n id: number;\n name: string;\n created_date: string;\n description: string;\n initial_value: string;\n default_enabled: boolean;\n type: string;\n };\n feature_state_value: string;\n environment: number;\n identity: number;\n feature_segment: number;\n enabled: boolean;\n}[];\n\nexport async function getProviderData(options: {\n environmentKey: string;\n projectId: string;\n}): Promise<ProviderData> {\n const hints: Exclude<ProviderData['hints'], undefined> = [];\n\n if (!options.environmentKey) {\n hints.push({\n key: 'flagsmith/missing-environment-id',\n text: 'Missing Flagsmith Environment ID',\n });\n }\n\n if (!options.projectId) {\n hints.push({\n key: 'flagsmith/missing-project-id',\n text: 'Missing Flagsmith Project ID',\n });\n }\n\n if (hints.length > 0) return { definitions: {}, hints };\n\n try {\n const res = await fetch(`https://api.flagsmith.com/api/v1/flags/`, {\n method: 'GET',\n headers: {\n 'X-Environment-Key': options.environmentKey,\n },\n // @ts-expect-error used by some Next.js versions\n cache: 'no-store',\n });\n\n if (res.status !== 200) {\n return {\n definitions: {},\n hints: [\n {\n key: `flagsmith/response-not-ok/${options.environmentKey}`,\n text: `Failed to fetch Flagsmith (Received ${res.status} response)`,\n },\n ],\n };\n }\n\n const data = (await res.json()) as FlagsmithApiData;\n const definitions = data?.reduce<Record<string, FlagDefinitionType>>(\n (acc, flag) => {\n acc[flag.feature.name] = {\n origin: `https://app.flagsmith.com/project/${options.projectId}/environment/${options.environmentKey}/features/?feature=${flag?.id}`,\n description: flag.feature.description,\n createdAt: new Date(flag.feature.created_date).getTime(),\n options: [\n {\n value: flag.feature_state_value,\n label: flag.feature_state_value,\n },\n ],\n };\n return acc;\n },\n {},\n );\n\n return {\n definitions,\n hints: [],\n };\n } catch (error) {\n return {\n definitions: {},\n hints: [\n {\n key: 'flagsmith/response-not-ok',\n text: `Failed to fetch Flagsmith`,\n },\n ],\n };\n }\n}\n"]}