{"version":3,"file":"devtools.mjs","names":["GrowthBook","UserScopedGrowthBook","applyDevtoolsState","devtoolsState","gb","inDevMode","attributes","setAttributeOverrides","features","map","Map","Object","entries","setForcedFeatures","experiments","setForcedVariations","devtoolsPlugin","Error","devtoolsNextjsPlugin","_ref","searchParams","requestCookies","request","extractGbDebugPayload","_ref2","_requestCookies$get","_gbdebug","URLSearchParams","_searchParams$get","get","undefined","value","payload","nextUrl","cookies","state","JSON","parse","e","console","error","devtoolsExpressPlugin","_ref3","_request$query","query","_request$cookies","getDebugScriptContents","source","event","getDebugEvent","concat","stringify","apiHost","clientKey","getApiInfo","logs","sdkInfo","version","getDecryptedPayload","getAttributes","userContext","getUserContext","getVersion","_objectSpread","attributeOverrides"],"sources":["../../../src/plugins/devtools.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { GrowthBook } from \"../GrowthBook\";\nimport {\n  Attributes,\n  FeatureApiResponse,\n  LogUnion,\n  Plugin,\n} from \"../types/growthbook\";\nimport { GrowthBookClient, UserScopedGrowthBook } from \"../GrowthBookClient\";\n\nexport type DevtoolsState = {\n  attributes?: Record<string, any>;\n  features?: Record<string, any>;\n  experiments?: Record<string, number>;\n};\n\nexport interface NextjsReadonlyRequestCookiesCompat {\n  get: (name: string) => { name: string; value: string } | undefined;\n}\nexport interface NextjsRequestCompat {\n  nextUrl: {\n    searchParams: URLSearchParams;\n  };\n  cookies: {\n    get: (name: string) => { name: string; value: string } | undefined;\n  };\n}\nexport interface ExpressRequestCompat {\n  cookies: Record<string, string | string[]>;\n  query: Record<string, string>;\n  [key: string]: unknown;\n}\n\nfunction applyDevtoolsState(\n  devtoolsState: DevtoolsState,\n  gb: GrowthBook | UserScopedGrowthBook,\n) {\n  // Only enable in dev mode\n  if (!gb.inDevMode()) {\n    return;\n  }\n\n  if (\n    devtoolsState.attributes &&\n    typeof devtoolsState.attributes === \"object\"\n  ) {\n    gb.setAttributeOverrides(devtoolsState.attributes);\n  }\n  if (devtoolsState.features && typeof devtoolsState.features === \"object\") {\n    const map = new Map(Object.entries(devtoolsState.features));\n    gb.setForcedFeatures(map);\n  }\n  if (\n    devtoolsState.experiments &&\n    typeof devtoolsState.experiments === \"object\"\n  ) {\n    gb.setForcedVariations(devtoolsState.experiments);\n  }\n}\n\nexport function devtoolsPlugin(devtoolsState?: DevtoolsState): Plugin {\n  return (gb: GrowthBook | UserScopedGrowthBook | GrowthBookClient) => {\n    // Only works for user-scoped GrowthBook instances\n    if (\"createScopedInstance\" in gb) {\n      throw new Error(\n        \"devtoolsPlugin can only be set on a user-scoped instance\",\n      );\n    }\n    if (devtoolsState) {\n      applyDevtoolsState(devtoolsState, gb);\n    }\n  };\n}\n\n/**\n * For NextJS environments.\n * When using server components, use the `searchParams` and `requestCookies` fields.\n *  - Note: In NextJS 15+, you should await these values before passing them to the plugin\n * When using middleware / api routes, provide the `request` field instead.\n */\nexport function devtoolsNextjsPlugin({\n  searchParams,\n  requestCookies,\n  request,\n}: {\n  searchParams?: { _gbdebug?: string };\n  requestCookies?: NextjsReadonlyRequestCookiesCompat;\n  request?: NextjsRequestCompat;\n}): Plugin {\n  function extractGbDebugPayload({\n    searchParams,\n    requestCookies,\n  }: {\n    searchParams?: { _gbdebug?: string } | URLSearchParams;\n    requestCookies?: NextjsReadonlyRequestCookiesCompat;\n  }): string | undefined {\n    if (searchParams) {\n      if (\"_gbdebug\" in searchParams) {\n        return searchParams._gbdebug;\n      }\n      if (searchParams instanceof URLSearchParams) {\n        return searchParams.get(\"_gbdebug\") ?? undefined;\n      }\n    }\n    return requestCookies?.get(\"_gbdebug\")?.value;\n  }\n\n  return (gb: GrowthBook | UserScopedGrowthBook | GrowthBookClient) => {\n    let payload = extractGbDebugPayload({ searchParams, requestCookies });\n\n    if (!payload && request) {\n      payload = extractGbDebugPayload({\n        searchParams: request.nextUrl.searchParams,\n        requestCookies: request.cookies,\n      });\n    }\n\n    let state: DevtoolsState = {};\n    if (payload) {\n      try {\n        state = JSON.parse(payload);\n      } catch (e) {\n        console.error(\"cannot parse devtools payload\", e);\n      }\n    }\n\n    devtoolsPlugin(state)(gb);\n  };\n}\n\n/**\n * Intended to be used with cookieParser() middleware from npm: 'cookie-parser'.\n */\nexport function devtoolsExpressPlugin({\n  request,\n}: {\n  request?: ExpressRequestCompat;\n}): Plugin {\n  return (gb: GrowthBook | UserScopedGrowthBook | GrowthBookClient) => {\n    let payload =\n      typeof request?.query?.[\"_gbdebug\"] === \"string\"\n        ? request.query[\"_gbdebug\"]\n        : undefined;\n    if (!payload) {\n      payload =\n        typeof request?.cookies?.[\"_gbdebug\"] === \"string\"\n          ? request.cookies[\"_gbdebug\"]\n          : undefined;\n    }\n\n    let state: DevtoolsState = {};\n    if (payload) {\n      try {\n        state = JSON.parse(payload);\n      } catch (e) {\n        console.error(\"cannot parse devtools payload\", e);\n      }\n    }\n\n    devtoolsPlugin(state)(gb);\n  };\n}\n\nexport type SdkInfo = {\n  apiHost: string;\n  clientKey: string;\n  source?: string;\n  version?: string;\n  payload?: FeatureApiResponse;\n  attributes?: Attributes;\n};\nexport type LogEvent = {\n  logs: LogUnion[];\n  sdkInfo?: SdkInfo;\n};\n/**\n * Helper method to get debug script contents for DevTools\n * @param gb - GrowthBook instance. DevMode must be enabled to view log events.\n * @param {string} [source] - Label these events for ease of reading in DevTools\n * @example\n * A React logger component (implement yourself):\n ```\n  return (\n    <script dangerouslySetInnerHTML={{\n      __html: getDebugScriptContents(gb, \"nextjs\")\n    }} />\n  );\n ```\n */\nexport function getDebugScriptContents(\n  gb: GrowthBook,\n  source?: string,\n): string {\n  const event = getDebugEvent(gb, source);\n  if (!event) return \"\";\n  return `(window._gbdebugEvents = (window._gbdebugEvents || [])).push(${JSON.stringify(\n    event,\n  )});`;\n}\n\nexport function getDebugEvent(\n  gb: GrowthBook | UserScopedGrowthBook,\n  source?: string,\n): LogEvent | null {\n  if (!(\"logs\" in gb)) return null;\n  // Only enable in dev mode\n  if (!gb.inDevMode()) {\n    return null;\n  }\n  if (gb instanceof GrowthBook) {\n    // GrowthBook SDK\n    const [apiHost, clientKey] = gb.getApiInfo();\n    return {\n      logs: gb.logs,\n      sdkInfo: {\n        apiHost,\n        clientKey,\n        source,\n        version: gb.version,\n        payload: gb.getDecryptedPayload(),\n        attributes: gb.getAttributes(),\n      },\n    };\n  } else if (gb instanceof UserScopedGrowthBook) {\n    // UserScopedGrowthBook SDK\n    const userContext = gb.getUserContext();\n    const [apiHost, clientKey] = gb.getApiInfo();\n    return {\n      logs: gb.logs,\n      sdkInfo: {\n        apiHost,\n        clientKey,\n        source,\n        version: gb.getVersion(),\n        payload: gb.getDecryptedPayload(),\n        attributes: {\n          ...userContext.attributes,\n          ...userContext.attributeOverrides,\n        },\n      },\n    };\n  }\n  return null;\n}\n"],"mappings":";;;;;AAAA;AACA,SAASA,UAAU,QAAQ,mBAAe;AAO1C,SAA2BC,oBAAoB,QAAQ,yBAAqB;AAyB5E,SAASC,kBAAkBA,CACzBC,aAA4B,EAC5BC,EAAqC,EACrC;EACA;EACA,IAAI,CAACA,EAAE,CAACC,SAAS,CAAC,CAAC,EAAE;IACnB;EACF;EAEA,IACEF,aAAa,CAACG,UAAU,IACxB,OAAOH,aAAa,CAACG,UAAU,KAAK,QAAQ,EAC5C;IACAF,EAAE,CAACG,qBAAqB,CAACJ,aAAa,CAACG,UAAU,CAAC;EACpD;EACA,IAAIH,aAAa,CAACK,QAAQ,IAAI,OAAOL,aAAa,CAACK,QAAQ,KAAK,QAAQ,EAAE;IACxE,MAAMC,GAAG,GAAG,IAAIC,GAAG,CAACC,MAAM,CAACC,OAAO,CAACT,aAAa,CAACK,QAAQ,CAAC,CAAC;IAC3DJ,EAAE,CAACS,iBAAiB,CAACJ,GAAG,CAAC;EAC3B;EACA,IACEN,aAAa,CAACW,WAAW,IACzB,OAAOX,aAAa,CAACW,WAAW,KAAK,QAAQ,EAC7C;IACAV,EAAE,CAACW,mBAAmB,CAACZ,aAAa,CAACW,WAAW,CAAC;EACnD;AACF;AAEA,OAAO,SAASE,cAAcA,CAACb,aAA6B,EAAU;EACpE,OAAQC,EAAwD,IAAK;IACnE;IACA,IAAI,sBAAsB,IAAIA,EAAE,EAAE;MAChC,MAAM,IAAIa,KAAK,CACb,0DACF,CAAC;IACH;IACA,IAAId,aAAa,EAAE;MACjBD,kBAAkB,CAACC,aAAa,EAAEC,EAAE,CAAC;IACvC;EACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASc,oBAAoBA,CAAAC,IAAA,EAQzB;EAAA,IAR0B;IACnCC,YAAY;IACZC,cAAc;IACdC;EAKF,CAAC,GAAAH,IAAA;EACC,SAASI,qBAAqBA,CAAAC,KAAA,EAMP;IAAA,IAAAC,mBAAA;IAAA,IANQ;MAC7BL,YAAY;MACZC;IAIF,CAAC,GAAAG,KAAA;IACC,IAAIJ,YAAY,EAAE;MAChB,IAAI,UAAU,IAAIA,YAAY,EAAE;QAC9B,OAAOA,YAAY,CAACM,QAAQ;MAC9B;MACA,IAAIN,YAAY,YAAYO,eAAe,EAAE;QAAA,IAAAC,iBAAA;QAC3C,QAAAA,iBAAA,GAAOR,YAAY,CAACS,GAAG,CAAC,UAAU,CAAC,cAAAD,iBAAA,cAAAA,iBAAA,GAAIE,SAAS;MAClD;IACF;IACA,OAAOT,cAAc,aAAdA,cAAc,gBAAAI,mBAAA,GAAdJ,cAAc,CAAEQ,GAAG,CAAC,UAAU,CAAC,cAAAJ,mBAAA,uBAA/BA,mBAAA,CAAiCM,KAAK;EAC/C;EAEA,OAAQ3B,EAAwD,IAAK;IACnE,IAAI4B,OAAO,GAAGT,qBAAqB,CAAC;MAAEH,YAAY;MAAEC;IAAe,CAAC,CAAC;IAErE,IAAI,CAACW,OAAO,IAAIV,OAAO,EAAE;MACvBU,OAAO,GAAGT,qBAAqB,CAAC;QAC9BH,YAAY,EAAEE,OAAO,CAACW,OAAO,CAACb,YAAY;QAC1CC,cAAc,EAAEC,OAAO,CAACY;MAC1B,CAAC,CAAC;IACJ;IAEA,IAAIC,KAAoB,GAAG,CAAC,CAAC;IAC7B,IAAIH,OAAO,EAAE;MACX,IAAI;QACFG,KAAK,GAAGC,IAAI,CAACC,KAAK,CAACL,OAAO,CAAC;MAC7B,CAAC,CAAC,OAAOM,CAAC,EAAE;QACVC,OAAO,CAACC,KAAK,CAAC,+BAA+B,EAAEF,CAAC,CAAC;MACnD;IACF;IAEAtB,cAAc,CAACmB,KAAK,CAAC,CAAC/B,EAAE,CAAC;EAC3B,CAAC;AACH;;AAEA;AACA;AACA;AACA,OAAO,SAASqC,qBAAqBA,CAAAC,KAAA,EAI1B;EAAA,IAJ2B;IACpCpB;EAGF,CAAC,GAAAoB,KAAA;EACC,OAAQtC,EAAwD,IAAK;IAAA,IAAAuC,cAAA;IACnE,IAAIX,OAAO,GACT,QAAOV,OAAO,aAAPA,OAAO,gBAAAqB,cAAA,GAAPrB,OAAO,CAAEsB,KAAK,cAAAD,cAAA,uBAAdA,cAAA,CAAiB,UAAU,CAAC,MAAK,QAAQ,GAC5CrB,OAAO,CAACsB,KAAK,CAAC,UAAU,CAAC,GACzBd,SAAS;IACf,IAAI,CAACE,OAAO,EAAE;MAAA,IAAAa,gBAAA;MACZb,OAAO,GACL,QAAOV,OAAO,aAAPA,OAAO,gBAAAuB,gBAAA,GAAPvB,OAAO,CAAEY,OAAO,cAAAW,gBAAA,uBAAhBA,gBAAA,CAAmB,UAAU,CAAC,MAAK,QAAQ,GAC9CvB,OAAO,CAACY,OAAO,CAAC,UAAU,CAAC,GAC3BJ,SAAS;IACjB;IAEA,IAAIK,KAAoB,GAAG,CAAC,CAAC;IAC7B,IAAIH,OAAO,EAAE;MACX,IAAI;QACFG,KAAK,GAAGC,IAAI,CAACC,KAAK,CAACL,OAAO,CAAC;MAC7B,CAAC,CAAC,OAAOM,CAAC,EAAE;QACVC,OAAO,CAACC,KAAK,CAAC,+BAA+B,EAAEF,CAAC,CAAC;MACnD;IACF;IAEAtB,cAAc,CAACmB,KAAK,CAAC,CAAC/B,EAAE,CAAC;EAC3B,CAAC;AACH;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAAS0C,sBAAsBA,CACpC1C,EAAc,EACd2C,MAAe,EACP;EACR,MAAMC,KAAK,GAAGC,aAAa,CAAC7C,EAAE,EAAE2C,MAAM,CAAC;EACvC,IAAI,CAACC,KAAK,EAAE,OAAO,EAAE;EACrB,uEAAAE,MAAA,CAAuEd,IAAI,CAACe,SAAS,CACnFH,KACF,CAAC;AACH;AAEA,OAAO,SAASC,aAAaA,CAC3B7C,EAAqC,EACrC2C,MAAe,EACE;EACjB,IAAI,EAAE,MAAM,IAAI3C,EAAE,CAAC,EAAE,OAAO,IAAI;EAChC;EACA,IAAI,CAACA,EAAE,CAACC,SAAS,CAAC,CAAC,EAAE;IACnB,OAAO,IAAI;EACb;EACA,IAAID,EAAE,YAAYJ,UAAU,EAAE;IAC5B;IACA,MAAM,CAACoD,OAAO,EAAEC,SAAS,CAAC,GAAGjD,EAAE,CAACkD,UAAU,CAAC,CAAC;IAC5C,OAAO;MACLC,IAAI,EAAEnD,EAAE,CAACmD,IAAI;MACbC,OAAO,EAAE;QACPJ,OAAO;QACPC,SAAS;QACTN,MAAM;QACNU,OAAO,EAAErD,EAAE,CAACqD,OAAO;QACnBzB,OAAO,EAAE5B,EAAE,CAACsD,mBAAmB,CAAC,CAAC;QACjCpD,UAAU,EAAEF,EAAE,CAACuD,aAAa,CAAC;MAC/B;IACF,CAAC;EACH,CAAC,MAAM,IAAIvD,EAAE,YAAYH,oBAAoB,EAAE;IAC7C;IACA,MAAM2D,WAAW,GAAGxD,EAAE,CAACyD,cAAc,CAAC,CAAC;IACvC,MAAM,CAACT,OAAO,EAAEC,SAAS,CAAC,GAAGjD,EAAE,CAACkD,UAAU,CAAC,CAAC;IAC5C,OAAO;MACLC,IAAI,EAAEnD,EAAE,CAACmD,IAAI;MACbC,OAAO,EAAE;QACPJ,OAAO;QACPC,SAAS;QACTN,MAAM;QACNU,OAAO,EAAErD,EAAE,CAAC0D,UAAU,CAAC,CAAC;QACxB9B,OAAO,EAAE5B,EAAE,CAACsD,mBAAmB,CAAC,CAAC;QACjCpD,UAAU,EAAAyD,aAAA,CAAAA,aAAA,KACLH,WAAW,CAACtD,UAAU,GACtBsD,WAAW,CAACI,kBAAkB;MAErC;IACF,CAAC;EACH;EACA,OAAO,IAAI;AACb","ignoreList":[]}