@exodus/networking-common
Version:
Platform-agnostic interfaces and common utilities to be used across our networking modules
56 lines (55 loc) • 1.69 kB
JavaScript
function toFirstLower(value) {
const first = value[0];
if (!first)
return '';
return first.toLowerCase() + value.slice(1);
}
function assertDefined(value, message) {
if (value === undefined || value === null)
throw new Error(message);
}
const FACTORIES = new Map(Object.entries({
'Max-Age': {
key: 'maxAge',
getInstance: Number,
},
HttpOnly: {
key: 'httpOnly',
getInstance: () => true,
},
Expires: {
key: 'expires',
getInstance: (value) => {
assertDefined(value, 'Malformed cookie string: Received undefined value for property Expires');
return new Date(value);
},
},
Secure: {
key: 'secure',
getInstance: () => true,
},
}));
function deserializeNameAndValue(nameValue) {
if (!nameValue.includes('=')) {
return { name: '', value: nameValue };
}
const [name, value] = nameValue.split(/=(.*)/u);
return { name, value };
}
export default function deserialize(cookieString) {
const [nameValue, ...rest] = cookieString.split('; ');
assertDefined(nameValue, `Malformed cookie string: ${cookieString}`);
const { name, value } = deserializeNameAndValue(nameValue);
const cookie = { name, value };
rest.forEach((property) => {
const [key, value] = property.split('=');
assertDefined(key, 'Malformed cookie string: Encountered property without key.');
const factory = FACTORIES.get(key);
if (factory) {
cookie[factory.key] = factory.getInstance(value);
return;
}
cookie[toFirstLower(key)] = value;
});
return cookie;
}