| 'use strict' |
| |
| const { parseSetCookie } = require('./parse') |
| const { stringify, getHeadersList } = require('./util') |
| const { webidl } = require('../fetch/webidl') |
| const { Headers } = require('../fetch/headers') |
| |
| /** |
| * @typedef {Object} Cookie |
| * @property {string} name |
| * @property {string} value |
| * @property {Date|number|undefined} expires |
| * @property {number|undefined} maxAge |
| * @property {string|undefined} domain |
| * @property {string|undefined} path |
| * @property {boolean|undefined} secure |
| * @property {boolean|undefined} httpOnly |
| * @property {'Strict'|'Lax'|'None'} sameSite |
| * @property {string[]} unparsed |
| */ |
| |
| /** |
| * @param {Headers} headers |
| * @returns {Record<string, string>} |
| */ |
| function getCookies (headers) { |
| webidl.argumentLengthCheck(arguments, 1, { header: 'getCookies' }) |
| |
| webidl.brandCheck(headers, Headers, { strict: false }) |
| |
| const cookie = headers.get('cookie') |
| const out = {} |
| |
| if (!cookie) { |
| return out |
| } |
| |
| for (const piece of cookie.split(';')) { |
| const [name, ...value] = piece.split('=') |
| |
| out[name.trim()] = value.join('=') |
| } |
| |
| return out |
| } |
| |
| /** |
| * @param {Headers} headers |
| * @param {string} name |
| * @param {{ path?: string, domain?: string }|undefined} attributes |
| * @returns {void} |
| */ |
| function deleteCookie (headers, name, attributes) { |
| webidl.argumentLengthCheck(arguments, 2, { header: 'deleteCookie' }) |
| |
| webidl.brandCheck(headers, Headers, { strict: false }) |
| |
| name = webidl.converters.DOMString(name) |
| attributes = webidl.converters.DeleteCookieAttributes(attributes) |
| |
| // Matches behavior of |
| // https://github.com/denoland/deno_std/blob/63827b16330b82489a04614027c33b7904e08be5/http/cookie.ts#L278 |
| setCookie(headers, { |
| name, |
| value: '', |
| expires: new Date(0), |
| ...attributes |
| }) |
| } |
| |
| /** |
| * @param {Headers} headers |
| * @returns {Cookie[]} |
| */ |
| function getSetCookies (headers) { |
| webidl.argumentLengthCheck(arguments, 1, { header: 'getSetCookies' }) |
| |
| webidl.brandCheck(headers, Headers, { strict: false }) |
| |
| const cookies = getHeadersList(headers).cookies |
| |
| if (!cookies) { |
| return [] |
| } |
| |
| // In older versions of undici, cookies is a list of name:value. |
| return cookies.map((pair) => parseSetCookie(Array.isArray(pair) ? pair[1] : pair)) |
| } |
| |
| /** |
| * @param {Headers} headers |
| * @param {Cookie} cookie |
| * @returns {void} |
| */ |
| function setCookie (headers, cookie) { |
| webidl.argumentLengthCheck(arguments, 2, { header: 'setCookie' }) |
| |
| webidl.brandCheck(headers, Headers, { strict: false }) |
| |
| cookie = webidl.converters.Cookie(cookie) |
| |
| const str = stringify(cookie) |
| |
| if (str) { |
| headers.append('Set-Cookie', stringify(cookie)) |
| } |
| } |
| |
| webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ |
| { |
| converter: webidl.nullableConverter(webidl.converters.DOMString), |
| key: 'path', |
| defaultValue: null |
| }, |
| { |
| converter: webidl.nullableConverter(webidl.converters.DOMString), |
| key: 'domain', |
| defaultValue: null |
| } |
| ]) |
| |
| webidl.converters.Cookie = webidl.dictionaryConverter([ |
| { |
| converter: webidl.converters.DOMString, |
| key: 'name' |
| }, |
| { |
| converter: webidl.converters.DOMString, |
| key: 'value' |
| }, |
| { |
| converter: webidl.nullableConverter((value) => { |
| if (typeof value === 'number') { |
| return webidl.converters['unsigned long long'](value) |
| } |
| |
| return new Date(value) |
| }), |
| key: 'expires', |
| defaultValue: null |
| }, |
| { |
| converter: webidl.nullableConverter(webidl.converters['long long']), |
| key: 'maxAge', |
| defaultValue: null |
| }, |
| { |
| converter: webidl.nullableConverter(webidl.converters.DOMString), |
| key: 'domain', |
| defaultValue: null |
| }, |
| { |
| converter: webidl.nullableConverter(webidl.converters.DOMString), |
| key: 'path', |
| defaultValue: null |
| }, |
| { |
| converter: webidl.nullableConverter(webidl.converters.boolean), |
| key: 'secure', |
| defaultValue: null |
| }, |
| { |
| converter: webidl.nullableConverter(webidl.converters.boolean), |
| key: 'httpOnly', |
| defaultValue: null |
| }, |
| { |
| converter: webidl.converters.USVString, |
| key: 'sameSite', |
| allowedValues: ['Strict', 'Lax', 'None'] |
| }, |
| { |
| converter: webidl.sequenceConverter(webidl.converters.DOMString), |
| key: 'unparsed', |
| defaultValue: [] |
| } |
| ]) |
| |
| module.exports = { |
| getCookies, |
| deleteCookie, |
| getSetCookies, |
| setCookie |
| } |