{"version":3,"sources":["cookie.ts"],"sourcesContent":["// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.\n// Structured similarly to Go's cookie.go\n// https://github.com/golang/go/blob/master/src/net/http/cookie.go\n// This module is browser compatible.\n\n/** Make an assertion, error will be thrown if `expr` does not have truthy value. */\nexport function assert(expr: unknown, msg = \"\"): asserts expr {\n\tif (!expr) {\n\t  throw new Error(msg);\n\t}\n}\n\nexport interface Cookie {\n  /** Name of the cookie. */\n  name: string;\n  /** Value of the cookie. */\n  value: string;\n  /** The cookie's `Expires` attribute, either as an explicit date or UTC milliseconds.\n   * @example <caption>Explicit date:</caption>\n   *\n   * ```ts\n   * import { Cookie } from \"https://deno.land/std@$STD_VERSION/http/cookie.ts\";\n   * const cookie: Cookie = {\n   *   name: 'name',\n   *   value: 'value',\n   *   // expires on Fri Dec 30 2022\n   *   expires: new Date('2022-12-31')\n   * }\n   * ```\n   *\n   * @example <caption>UTC milliseconds</caption>\n   *\n   * ```ts\n   * import { Cookie } from \"https://deno.land/std@$STD_VERSION/http/cookie.ts\";\n   * const cookie: Cookie = {\n   *   name: 'name',\n   *   value: 'value',\n   *   // expires 10 seconds from now\n   *   expires: Date.now() + 10000\n   * }\n   * ```\n   */\n  expires?: Date | number;\n  /** The cookie's `Max-Age` attribute, in seconds. Must be a non-negative integer. A cookie with a `maxAge` of `0` expires immediately. */\n  maxAge?: number;\n  /** The cookie's `Domain` attribute. Specifies those hosts to which the cookie will be sent. */\n  domain?: string;\n  /** The cookie's `Path` attribute. A cookie with a path will only be included in the `Cookie` request header if the requested URL matches that path. */\n  path?: string;\n  /** The cookie's `Secure` attribute. If `true`, the cookie will only be included in the `Cookie` request header if the connection uses SSL and HTTPS. */\n  secure?: boolean;\n  /** The cookie's `HTTPOnly` attribute. If `true`, the cookie cannot be accessed via JavaScript. */\n  httpOnly?: boolean;\n  /**\n   * Allows servers to assert that a cookie ought not to\n   * be sent along with cross-site requests.\n   */\n  sameSite?: \"Strict\" | \"Lax\" | \"None\";\n  /** Additional key value pairs with the form \"key=value\" */\n  unparsed?: string[];\n}\n\nconst FIELD_CONTENT_REGEXP = /^(?=[\\x20-\\x7E]*$)[^()@<>,;:\\\\\"\\[\\]?={}\\s]+$/;\n\nfunction toString(cookie: Cookie): string {\n  if (!cookie.name) {\n    return \"\";\n  }\n  const out: string[] = [];\n  validateName(cookie.name);\n  validateValue(cookie.name, cookie.value);\n  out.push(`${cookie.name}=${cookie.value}`);\n\n  // Fallback for invalid Set-Cookie\n  // ref: https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1\n  if (cookie.name.startsWith(\"__Secure\")) {\n    cookie.secure = true;\n  }\n  if (cookie.name.startsWith(\"__Host\")) {\n    cookie.path = \"/\";\n    cookie.secure = true;\n    delete cookie.domain;\n  }\n\n  if (cookie.secure) {\n    out.push(\"Secure\");\n  }\n  if (cookie.httpOnly) {\n    out.push(\"HttpOnly\");\n  }\n  if (typeof cookie.maxAge === \"number\" && Number.isInteger(cookie.maxAge)) {\n    assert(\n      cookie.maxAge >= 0,\n      \"Max-Age must be an integer superior or equal to 0\",\n    );\n    out.push(`Max-Age=${cookie.maxAge}`);\n  }\n  if (cookie.domain) {\n    validateDomain(cookie.domain);\n    out.push(`Domain=${cookie.domain}`);\n  }\n  if (cookie.sameSite) {\n    out.push(`SameSite=${cookie.sameSite}`);\n  }\n  if (cookie.path) {\n    validatePath(cookie.path);\n    out.push(`Path=${cookie.path}`);\n  }\n  if (cookie.expires) {\n    const { expires } = cookie;\n    const date = typeof expires === \"number\" ? new Date(expires) : expires;\n    out.push(`Expires=${date.toUTCString()}`);\n  }\n  if (cookie.unparsed) {\n    out.push(cookie.unparsed.join(\"; \"));\n  }\n  return out.join(\"; \");\n}\n\n/**\n * Validate Cookie Name.\n * @param name Cookie name.\n */\nfunction validateName(name: string | undefined | null) {\n  if (name && !FIELD_CONTENT_REGEXP.test(name)) {\n    throw new TypeError(`Invalid cookie name: \"${name}\".`);\n  }\n}\n\n/**\n * Validate Path Value.\n * See {@link https://tools.ietf.org/html/rfc6265#section-4.1.2.4}.\n * @param path Path value.\n */\nfunction validatePath(path: string | null) {\n  if (path === null) {\n    return;\n  }\n  for (let i = 0; i < path.length; i++) {\n    const c = path.charAt(i);\n    if (\n      c < String.fromCharCode(0x20) || c > String.fromCharCode(0x7E) ||\n      c === \";\"\n    ) {\n      throw new Error(\n        path + \": Invalid cookie path char '\" + c + \"'\",\n      );\n    }\n  }\n}\n\n/**\n * Validate Cookie Value.\n * See {@link https://tools.ietf.org/html/rfc6265#section-4.1}.\n * @param value Cookie value.\n */\nfunction validateValue(name: string, value: string | null) {\n  if (value === null) return;\n  for (let i = 0; i < value.length; i++) {\n    const c = value.charAt(i);\n    if (\n      c < String.fromCharCode(0x21) || c === String.fromCharCode(0x22) ||\n      c === String.fromCharCode(0x2c) || c === String.fromCharCode(0x3b) ||\n      c === String.fromCharCode(0x5c) || c === String.fromCharCode(0x7f)\n    ) {\n      throw new Error(\n        \"RFC2616 cookie '\" + name + \"' cannot contain character '\" + c + \"'\",\n      );\n    }\n    if (c > String.fromCharCode(0x80)) {\n      throw new Error(\n        \"RFC2616 cookie '\" + name + \"' can only have US-ASCII chars as value\" +\n          c.charCodeAt(0).toString(16),\n      );\n    }\n  }\n}\n\n/**\n * Validate Cookie Domain.\n * See {@link https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.2.3}.\n * @param domain Cookie domain.\n */\nfunction validateDomain(domain: string) {\n  const char1 = domain.charAt(0);\n  const charN = domain.charAt(domain.length - 1);\n  if (char1 === \"-\" || charN === \".\" || charN === \"-\") {\n    throw new Error(\n      \"Invalid first/last char in cookie domain: \" + domain,\n    );\n  }\n}\n\n/**\n * Parse cookies of a header\n *\n * @example\n * ```ts\n * import { getCookies } from \"https://deno.land/std@$STD_VERSION/http/cookie.ts\";\n *\n * const headers = new Headers();\n * headers.set(\"Cookie\", \"full=of; tasty=chocolate\");\n *\n * const cookies = getCookies(headers);\n * console.log(cookies); // { full: \"of\", tasty: \"chocolate\" }\n * ```\n *\n * @param headers The headers instance to get cookies from\n * @return Object with cookie names as keys\n */\nexport function getCookies(headers: Headers): Record<string, string> {\n  const cookie = headers.get(\"Cookie\");\n  if (cookie !== null) {\n    const out: Record<string, string> = {};\n    const c = cookie.split(\";\");\n    for (const kv of c) {\n      const [cookieKey, ...cookieVal] = kv.split(\"=\");\n      assert(cookieKey !== undefined);\n      const key = cookieKey.trim();\n      out[key] = cookieVal.join(\"=\");\n    }\n    return out;\n  }\n  return {};\n}\n\n/**\n * Set the cookie header properly in the headers\n *\n * @example\n * ```ts\n * import {\n *   Cookie,\n *   setCookie,\n * } from \"https://deno.land/std@$STD_VERSION/http/cookie.ts\";\n *\n * const headers = new Headers();\n * const cookie: Cookie = { name: \"Space\", value: \"Cat\" };\n * setCookie(headers, cookie);\n *\n * const cookieHeader = headers.get(\"set-cookie\");\n * console.log(cookieHeader); // Space=Cat\n * ```\n *\n * @param headers The headers instance to set the cookie to\n * @param cookie Cookie to set\n */\nexport function setCookie(headers: Headers, cookie: Cookie) {\n  // Parsing cookie headers to make consistent set-cookie header\n  // ref: https://tools.ietf.org/html/rfc6265#section-4.1.1\n  const v = toString(cookie);\n  if (v) {\n    headers.append(\"Set-Cookie\", v);\n  }\n}\n\n/**\n * Set the cookie header with empty value in the headers to delete it\n *\n * > Note: Deleting a `Cookie` will set its expiration date before now. Forcing\n * > the browser to delete it.\n *\n * @example\n * ```ts\n * import { deleteCookie } from \"https://deno.land/std@$STD_VERSION/http/cookie.ts\";\n *\n * const headers = new Headers();\n * deleteCookie(headers, \"deno\");\n *\n * const cookieHeader = headers.get(\"set-cookie\");\n * console.log(cookieHeader); // deno=; Expires=Thus, 01 Jan 1970 00:00:00 GMT\n * ```\n *\n * @param headers The headers instance to delete the cookie from\n * @param name Name of cookie\n * @param attributes Additional cookie attributes\n */\nexport function deleteCookie(\n  headers: Headers,\n  name: string,\n  attributes?: { path?: string; domain?: string },\n) {\n  setCookie(headers, {\n    name: name,\n    value: \"\",\n    expires: new Date(0),\n    ...attributes,\n  });\n}\n\nfunction parseSetCookie(value: string): Cookie | null {\n  const attrs = value\n    .split(\";\")\n    .map((attr) => {\n      const [key, ...values] = attr.trim().split(\"=\");\n      return [key, values.join(\"=\")];\n    });\n  const cookie: Cookie = {\n    name: attrs[0][0],\n    value: attrs[0][1],\n  };\n\n  for (const [key, value] of attrs.slice(1)) {\n    switch (key.toLocaleLowerCase()) {\n      case \"expires\":\n        cookie.expires = new Date(value);\n        break;\n      case \"max-age\":\n        cookie.maxAge = Number(value);\n        if (cookie.maxAge < 0) {\n          console.warn(\n            \"Max-Age must be an integer superior or equal to 0. Cookie ignored.\",\n          );\n          return null;\n        }\n        break;\n      case \"domain\":\n        cookie.domain = value;\n        break;\n      case \"path\":\n        cookie.path = value;\n        break;\n      case \"secure\":\n        cookie.secure = true;\n        break;\n      case \"httponly\":\n        cookie.httpOnly = true;\n        break;\n      case \"samesite\":\n        cookie.sameSite = value as Cookie[\"sameSite\"];\n        break;\n      default:\n        if (!Array.isArray(cookie.unparsed)) {\n          cookie.unparsed = [];\n        }\n        cookie.unparsed.push([key, value].join(\"=\"));\n    }\n  }\n  if (cookie.name.startsWith(\"__Secure-\")) {\n    /** This requirement is mentioned in https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie but not the RFC. */\n    if (!cookie.secure) {\n      console.warn(\n        \"Cookies with names starting with `__Secure-` must be set with the secure flag. Cookie ignored.\",\n      );\n      return null;\n    }\n  }\n  if (cookie.name.startsWith(\"__Host-\")) {\n    if (!cookie.secure) {\n      console.warn(\n        \"Cookies with names starting with `__Host-` must be set with the secure flag. Cookie ignored.\",\n      );\n      return null;\n    }\n    if (cookie.domain !== undefined) {\n      console.warn(\n        \"Cookies with names starting with `__Host-` must not have a domain specified. Cookie ignored.\",\n      );\n      return null;\n    }\n    if (cookie.path !== \"/\") {\n      console.warn(\n        \"Cookies with names starting with `__Host-` must have path be `/`. Cookie has been ignored.\",\n      );\n      return null;\n    }\n  }\n  return cookie;\n}\n\n/**\n * Parse set-cookies of a header\n *\n * @example\n * ```ts\n * import { getSetCookies } from \"https://deno.land/std@$STD_VERSION/http/cookie.ts\";\n *\n * const headers = new Headers([\n *   [\"Set-Cookie\", \"lulu=meow; Secure; Max-Age=3600\"],\n *   [\"Set-Cookie\", \"booya=kasha; HttpOnly; Path=/\"],\n * ]);\n *\n * const cookies = getSetCookies(headers);\n * console.log(cookies); // [{ name: \"lulu\", value: \"meow\", secure: true, maxAge: 3600 }, { name: \"booya\", value: \"kahsa\", httpOnly: true, path: \"/ }]\n * ```\n *\n * @param headers The headers instance to get set-cookies from\n * @return List of cookies\n */\nexport function getSetCookies(headers: Headers): Cookie[] {\n  // TODO(lino-levan): remove this ts-ignore when Typescript 5.2 lands in Deno\n  // @ts-ignore Typescript's TS Dom types will be out of date until 5.2\n  return headers.getSetCookie()\n    /** Parse each `set-cookie` header separately */\n    .map(parseSetCookie)\n    /** Skip empty cookies */\n    .filter(Boolean) as Cookie[];\n}"],"names":["assert","expr","msg","Error","FIELD_CONTENT_REGEXP","toString","cookie","name","out","validateName","validateValue","value","push","startsWith","secure","path","domain","httpOnly","maxAge","Number","isInteger","validateDomain","sameSite","validatePath","expires","date","Date","toUTCString","unparsed","join","test","TypeError","i","length","c","charAt","String","fromCharCode","charCodeAt","char1","charN","getCookies","headers","get","kv","split","cookieKey","cookieVal","undefined","trim","setCookie","v","append","deleteCookie","attributes","parseSetCookie","attrs","map","attr","key","values","slice","toLocaleLowerCase","console","warn","Array","isArray","getSetCookies","getSetCookie","filter","Boolean"],"mappings":"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","sourceRoot":"/lib/uix-0.4.39/src/lib/cookie/","file":"cookie.ts"}