next-client-cookies
Version:
SSR and client support for Next.js v13 cookies (app directory)
1 lines • 6.04 kB
Source Map (JSON)
{"version":3,"sources":["../src/provider.tsx"],"sourcesContent":["'use client';\n\nimport React, { FC, ReactNode, useContext, useEffect, useMemo } from 'react';\nimport { CookieAttributes, Cookies } from './types';\nimport jsCookies from 'js-cookie';\nimport { ServerInsertedHTMLContext } from 'next/navigation';\nimport { ServerInsertedHTMLHook } from 'next/dist/shared/lib/server-inserted-html.shared-runtime';\nimport { Ctx } from './context';\nimport { CookieRecord, SecureValueRef, useSecureCookies } from './secure';\n\ntype CookieCommand = {\n [key in keyof Cookies]: [key, ...Parameters<Cookies[key]>];\n}['set' | 'remove'];\n\ntype SerializedValue<T> = {\n [K in keyof T]: Date extends T[K]\n ? string\n : object extends T[K]\n ? SerializedValue<T[K]>\n : T[K];\n};\n\nconst windowVarName = '__cookies_commands';\n\ndeclare global {\n interface Window {\n [windowVarName]: SerializedValue<CookieCommand>[];\n }\n}\n\n/**\n * @deprecated Use `<CookiesProvider />` from `next-client-cookies/server` instead.\n */\nexport const CookiesProvider: FC<{\n value: CookieRecord[];\n children: ReactNode;\n}> = ({ value, children }) => {\n const cookies = useCookieRecords(value);\n\n return <Ctx.Provider value={cookies}>{children}</Ctx.Provider>;\n};\n\nexport const SecureCookiesProvider: FC<{\n value: SecureValueRef;\n children: ReactNode;\n}> = ({ value, children }) => {\n const secureValue = useSecureCookies(value);\n const cookies = secureValue ? useCookieRecords(secureValue) : null;\n\n return <Ctx.Provider value={cookies}>{children}</Ctx.Provider>;\n};\n\nconst useCookieRecords = (value: CookieRecord[]): Cookies => {\n const insertedHTML = useContext<ServerInsertedHTMLHook | null>(\n ServerInsertedHTMLContext as never,\n );\n\n const cookies = useMemo((): Cookies => {\n const map: Partial<Record<string, string>> = Object.fromEntries(\n value.map((c) => [c.name, c.value]),\n );\n\n return {\n get: (name?: string) => (name == null ? { ...map } : map[name]) as never,\n set: (...args) => {\n insertedHTML?.(() => getCookieCommandHtml('set', ...args));\n map[args[0]] = args[1];\n },\n remove: (...args) => {\n insertedHTML?.(() => getCookieCommandHtml('remove', ...args));\n delete map[args[0]];\n },\n };\n }, [value, insertedHTML]);\n\n useEffect(() => {\n const commands = window[windowVarName] || [];\n if (!commands.length) return;\n\n for (const command of commands) {\n runCookieCommand(command);\n }\n }, []);\n\n return cookies;\n};\n\nconst getCookieCommandHtml = (...command: CookieCommand) => (\n <script\n dangerouslySetInnerHTML={{\n __html: `window.${windowVarName} = window.${windowVarName} || [];window.${windowVarName}.push(${JSON.stringify(\n command,\n ).replaceAll('</', '<\\\\/')});`,\n }}\n />\n);\n\nconst runCookieCommand = (command: SerializedValue<CookieCommand>) => {\n if (typeof window === 'undefined') return;\n\n switch (command[0]) {\n case 'set': {\n jsCookies.set(\n command[1],\n command[2],\n command[3] && deserializeCookieAttributes(command[3]),\n );\n break;\n }\n\n case 'remove': {\n jsCookies.remove(\n command[1],\n command[2] && deserializeCookieAttributes(command[2]),\n );\n break;\n }\n }\n};\n\nconst deserializeCookieAttributes = (\n attributes: SerializedValue<CookieAttributes>,\n): CookieAttributes => ({\n ...attributes,\n expires:\n typeof attributes.expires === 'string'\n ? new Date(attributes.expires)\n : attributes.expires,\n});\n"],"mappings":";;;AAEA,OAAOA,SAAwBC,YAAYC,WAAWC,eAAe;AAErE,OAAOC,eAAe;AACtB,SAASC,iCAAiC;AAE1C,SAASC,WAAW;AACpB,SAAuCC,wBAAwB;AAc/D,MAAMC,gBAAgB;AAWf,MAAMC,kBAGR,wBAAC,EAAEC,OAAOC,SAAQ,MAAE;AACvB,QAAMC,UAAUC,iBAAiBH,KAAAA;AAEjC,SAAO,sBAAA,cAACJ,IAAIQ,UAAQ;IAACJ,OAAOE;KAAUD,QAAAA;AACxC,GAJK;AAME,MAAMI,wBAGR,wBAAC,EAAEL,OAAOC,SAAQ,MAAE;AACvB,QAAMK,cAAcT,iBAAiBG,KAAAA;AACrC,QAAME,UAAUI,cAAcH,iBAAiBG,WAAAA,IAAe;AAE9D,SAAO,sBAAA,cAACV,IAAIQ,UAAQ;IAACJ,OAAOE;KAAUD,QAAAA;AACxC,GALK;AAOL,MAAME,mBAAmB,wBAACH,UAAAA;AACxB,QAAMO,eAAehB,WACnBI,yBAAAA;AAGF,QAAMO,UAAUT,QAAQ,MAAA;AACtB,UAAMe,MAAuCC,OAAOC,YAClDV,MAAMQ,IAAI,CAACG,MAAM;MAACA,EAAEC;MAAMD,EAAEX;KAAM,CAAA;AAGpC,WAAO;MACLa,KAAK,CAACD,SAAmBA,QAAQ,OAAO;QAAE,GAAGJ;MAAI,IAAIA,IAAII,IAAAA;MACzDE,KAAK,IAAIC,SAAAA;AACPR,uBAAe,MAAMS,qBAAqB,OAAA,GAAUD,IAAAA,CAAAA;AACpDP,YAAIO,KAAK,CAAA,CAAE,IAAIA,KAAK,CAAA;MACtB;MACAE,QAAQ,IAAIF,SAAAA;AACVR,uBAAe,MAAMS,qBAAqB,UAAA,GAAaD,IAAAA,CAAAA;AACvD,eAAOP,IAAIO,KAAK,CAAA,CAAE;MACpB;IACF;EACF,GAAG;IAACf;IAAOO;GAAa;AAExBf,YAAU,MAAA;AACR,UAAM0B,WAAWC,OAAOrB,aAAAA,KAAkB,CAAA;AAC1C,QAAI,CAACoB,SAASE;AAAQ;AAEtB,eAAWC,WAAWH,UAAU;AAC9BI,uBAAiBD,OAAAA;IACnB;EACF,GAAG,CAAA,CAAE;AAEL,SAAOnB;AACT,GAjCyB;AAmCzB,MAAMc,uBAAuB,2BAAIK,YAC/B,sBAAA,cAACE,UAAAA;EACCC,yBAAyB;IACvBC,QAAQ,UAAU3B,aAAAA,aAA0BA,aAAAA,iBAA8BA,aAAAA,SAAsB4B,KAAKC,UACnGN,OAAAA,EACAO,WAAW,MAAM,MAAA,CAAA;EACrB;IANyB;AAU7B,MAAMN,mBAAmB,wBAACD,YAAAA;AACxB,MAAI,OAAOF,WAAW;AAAa;AAEnC,UAAQE,QAAQ,CAAA,GAAE;IAChB,KAAK,OAAO;AACV3B,gBAAUoB,IACRO,QAAQ,CAAA,GACRA,QAAQ,CAAA,GACRA,QAAQ,CAAA,KAAMQ,4BAA4BR,QAAQ,CAAA,CAAE,CAAA;AAEtD;IACF;IAEA,KAAK,UAAU;AACb3B,gBAAUuB,OACRI,QAAQ,CAAA,GACRA,QAAQ,CAAA,KAAMQ,4BAA4BR,QAAQ,CAAA,CAAE,CAAA;AAEtD;IACF;EACF;AACF,GArByB;AAuBzB,MAAMQ,8BAA8B,wBAClCC,gBACsB;EACtB,GAAGA;EACHC,SACE,OAAOD,WAAWC,YAAY,WAC1B,IAAIC,KAAKF,WAAWC,OAAO,IAC3BD,WAAWC;AACnB,IARoC;","names":["React","useContext","useEffect","useMemo","jsCookies","ServerInsertedHTMLContext","Ctx","useSecureCookies","windowVarName","CookiesProvider","value","children","cookies","useCookieRecords","Provider","SecureCookiesProvider","secureValue","insertedHTML","map","Object","fromEntries","c","name","get","set","args","getCookieCommandHtml","remove","commands","window","length","command","runCookieCommand","script","dangerouslySetInnerHTML","__html","JSON","stringify","replaceAll","deserializeCookieAttributes","attributes","expires","Date"]}