Skip to main content
Module

x/request_cookie_store/set-cookie.js.map

An implementation of the Cookie Store API for request handlers.
Go to Latest
File
{"version":3,"file":"set-cookie.js","sourceRoot":"","sources":["src/set-cookie.ts"],"names":[],"mappings":"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","sourcesContent":["import { CookieInit } from 'cookie-store-interface';\n\nexport const attrsToSetCookie = (attrs: string[][]) => attrs.map(att => att.join('=')).join('; ');\n\n/** Matches control characters. TODO: more comprehensive list? */\nconst RE_CONTROL = /\\p{Cc}/u;\n\ntype Attr = [string] | [string, string];\ntype Attrs = [[string, string], ...Attr[]];\n\n/**\n * Implements <https://wicg.github.io/cookie-store/#set-a-cookie>\n * with some additional behaviors taken from Chrome's implementation.\n */\nexport function setCookie(options: string | CookieInit, value?: string, origin?: URL | null): null | [Attrs, Date | null] {\n const [name, val] = (typeof options === 'string'\n ? [options, value]\n : [options.name, options.value]).map(x => x?.toString())\n\n if (name == null || val == null)\n throw TypeError(\"required value(s) missing\");\n if (!name.length && val.includes('='))\n throw TypeError(\"Cookie value cannot contain '=' if the name is empty\");\n if (!name.length && !val.length)\n throw TypeError(\"Cookie name and value both cannot be empty\");\n\n // Unspecified, emulating Chrome's current behavior \n if (RE_CONTROL.test(name + val) || name.includes('=') || val.includes(';'))\n return null;\n\n if (val.includes(', ')) {\n throw TypeError(\"The cookie value must not contain sequence: ', '.\");\n }\n\n const attrs: Attrs = [[name, val]];\n const host = origin?.host;\n let expires: Date | null = null;\n\n if (typeof options !== 'string') {\n const { domain, path = '/', sameSite = 'strict' } = options;\n\n if (domain) {\n // Unspecified, emulating Chrome's current behavior \n const d = domain.toString();\n\n if (RE_CONTROL.test(d) || domain.includes(';'))\n return null;\n\n if (d.startsWith('.'))\n throw TypeError('Cookie domain cannot start with \".\"');\n\n if (host && !host.endsWith(`.${d}`))\n throw TypeError('Cookie dom must domain-match current host');\n\n attrs.push(['Domain', d]);\n }\n\n if (options.expires) {\n expires = options.expires instanceof Date\n ? options.expires\n : new Date(options.expires);\n attrs.push(['Expires', expires.toUTCString()]);\n }\n\n {\n if (!path?.toString().startsWith('/'))\n throw TypeError('Cookie path must start with \"/\"');\n\n // Unspecified, emulating Chrome's current behavior \n if (RE_CONTROL.test(path) || path.includes(';'))\n return null;\n\n attrs.push(['Path', path]);\n }\n\n // Altercated to allow for missing origin\n // TODO: should that be a thing?\n if (origin && origin.hostname !== 'localhost')\n attrs.push(['Secure']);\n\n // Unspecified\n if (options.httpOnly)\n attrs.push(['HttpOnly']);\n\n switch (sameSite) {\n case 'none': attrs.push(['SameSite', 'None']); break;\n case 'lax': attrs.push(['SameSite', 'Lax']); break;\n case 'strict': attrs.push(['SameSite', 'Strict']); break;\n default: throw TypeError(`The provided value '${sameSite}' is not a valid enum value of type CookieSameSite.`);\n }\n }\n\n return [attrs, expires]\n}\n\n/** \n * A not-so-strict parser for cookie headers.\n * - Allows pretty much everything in the value, including `=` \n * - Trims keys and values\n * - Ignores when both name and value are empty (but either empty allowed)\n * \n * For more on the state of allowed cookie characters, \n * see <https://stackoverflow.com/a/1969339/870615>.\n */\nexport function parseCookieHeader(cookie?: string | null) {\n return new Map(cookie?.split(/;\\s+/)\n .map(x => x.split('='))\n .map(([n, ...vs]) => [n.trim(), vs.join('=').trim()] as const)\n .filter(([n, v]) => !(n === '' && v === ''))\n );\n}\n"]}