{"version":3,"sources":["../src/provider/index.ts"],"names":["options"],"mappings":"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","sourcesContent":["import type { JsonValue, ProviderData } from 'flags';\n\ninterface GrowthbookFeature {\n  id: string;\n  dateCreated: string;\n  dateUpdated: string;\n  archived: boolean;\n  description: string;\n  owner: string;\n  project: string;\n  valueType: 'string' | 'number' | 'boolean' | 'json';\n  defaultValue: string;\n  tags: string[];\n  environments: Record<\n    string,\n    {\n      enabled: boolean;\n      defaultValue: string;\n      rules: unknown[];\n    }\n  >;\n  prerequisites: [];\n  revision: unknown;\n}\n\ninterface GrowthbookFeaturesResponse {\n  features: GrowthbookFeature[];\n  limit: number;\n  offset: number;\n  count: number;\n  total: number;\n  hasMore: boolean;\n  nextOffset: number;\n}\n\nexport async function getProviderData(options: {\n  /** GrowthBook API Key or Personal Access Token **/\n  apiKey: string;\n  /** Override the application API host for self-hosted users **/\n  appApiHost?: string;\n  /** Override the application URL for self-hosted users **/\n  appOrigin?: string;\n  /** Provide your GrowthBook SDK key to filter flag definitions **/\n  clientKey?: string;\n}): Promise<ProviderData> {\n  const apiKey = options.apiKey;\n  const appApiHost = options.appApiHost || 'https://api.growthbook.io';\n  const appOrigin = options.appOrigin || 'https://app.growthbook.io';\n  const clientKey = options.clientKey;\n\n  if (!apiKey) {\n    return {\n      definitions: {},\n      hints: [\n        {\n          key: 'growthbook/missing-api-key',\n          text: 'Missing GrowthBook API Key',\n        },\n      ],\n    };\n  }\n\n  const hints: ProviderData['hints'] = [];\n\n  const features = await getFeatures({ apiKey, appApiHost, clientKey });\n\n  if (features instanceof Error) {\n    return {\n      definitions: {},\n      hints: [\n        {\n          key: 'growthbook/fetch-failed',\n          text: features.message,\n        },\n      ],\n    };\n  }\n\n  const definitions: ProviderData['definitions'] = {};\n  for (const feature of features) {\n    if (feature.archived) continue;\n\n    let options: { label: string; value: JsonValue }[] = [];\n\n    switch (feature.valueType) {\n      case 'boolean':\n        options = [\n          { label: 'On', value: true },\n          { label: 'Off', value: false },\n        ];\n        break;\n      case 'string':\n        options = [\n          { label: `\"${feature.defaultValue}\"`, value: feature.defaultValue },\n        ];\n        break;\n      case 'number':\n        options = [\n          {\n            label: String(feature.defaultValue),\n            value: Number(feature.defaultValue),\n          },\n        ];\n        break;\n      case 'json':\n        options = [\n          {\n            label: 'JSON',\n            value: tryParseJSON(feature.defaultValue),\n          },\n        ];\n        break;\n      default:\n        hints.push({\n          key: 'growthbook/invalid-feature-type',\n          text: `Invalid feature type: ${feature.valueType}`,\n        });\n    }\n    const typeLabel =\n      feature.valueType === 'json'\n        ? 'JSON'\n        : feature.valueType.charAt(0).toUpperCase() +\n          feature.valueType.slice(1);\n\n    definitions[feature.id] = {\n      description: `[${typeLabel}] ${feature.description}`,\n      origin: `${appOrigin}/features/${feature.id}`,\n      options,\n      createdAt: new Date(feature.dateCreated).getTime(),\n      updatedAt: new Date(feature.dateUpdated).getTime(),\n    };\n  }\n\n  return { definitions, hints };\n}\n\n/**\n * Fetch all Feature Flags.\n */\nasync function getFeatures(options: {\n  apiKey: string;\n  appApiHost: string;\n  clientKey?: string;\n}): Promise<GrowthbookFeature[] | Error> {\n  try {\n    const features: GrowthbookFeaturesResponse['features'] = [];\n\n    let offset = 0;\n    let hasMore = true;\n\n    while (hasMore) {\n      const params = new URLSearchParams();\n      if (offset) params.append('offset', String(offset));\n      if (options.clientKey) params.append('clientKey', options.clientKey);\n      const qs = params.toString() ? `?${params.toString()}` : '';\n      const url = `${options.appApiHost}/api/v1/features${qs}`;\n      const response = await fetch(url, {\n        method: 'GET',\n        headers: {\n          Authorization: `Bearer ${options.apiKey}`,\n        },\n        cache: 'no-store',\n      });\n\n      if (response.status !== 200) {\n        await response.arrayBuffer(); // ensure stream is drained\n        return new Error(\n          `Failed to fetch GrowthBook (Received ${response.status} response)`,\n        );\n      }\n\n      const body = (await response.json()) as GrowthbookFeaturesResponse;\n      features.push(...body.features);\n      hasMore = body.hasMore;\n      offset = body.nextOffset;\n    }\n\n    return features;\n  } catch (e) {\n    return e instanceof Error ? e : new Error(String(e));\n  }\n}\n\nfunction tryParseJSON(value: string): JsonValue {\n  try {\n    return JSON.parse(value);\n  } catch {\n    return {};\n  }\n}\n"]}