@remix-run/headers
Version:
A toolkit for working with HTTP headers in JavaScript
126 lines (125 loc) • 4.37 kB
JavaScript
import {} from "./header-value.js";
import { parseParams, quote } from "./param-values.js";
import { capitalize, isValidDate } from "./utils.js";
/**
* The value of a `Set-Cookie` HTTP header.
*
* [MDN `Set-Cookie` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie)
*
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc6265#section-4.1)
*/
export class SetCookie {
domain;
expires;
httpOnly;
maxAge;
name;
partitioned;
path;
sameSite;
secure;
value;
/**
* @param init A string or object to initialize the header
*/
constructor(init) {
if (init) {
if (typeof init === 'string') {
let params = parseParams(init);
if (params.length > 0) {
this.name = params[0][0];
this.value = params[0][1];
for (let [key, value] of params.slice(1)) {
switch (key.toLowerCase()) {
case 'domain':
this.domain = value;
break;
case 'expires': {
if (typeof value === 'string') {
let date = new Date(value);
if (isValidDate(date)) {
this.expires = date;
}
}
break;
}
case 'httponly':
this.httpOnly = true;
break;
case 'max-age': {
if (typeof value === 'string') {
let v = parseInt(value, 10);
if (!isNaN(v))
this.maxAge = v;
}
break;
}
case 'partitioned':
this.partitioned = true;
break;
case 'path':
this.path = value;
break;
case 'samesite':
if (typeof value === 'string' && /strict|lax|none/i.test(value)) {
this.sameSite = capitalize(value);
}
break;
case 'secure':
this.secure = true;
break;
}
}
}
}
else {
this.domain = init.domain;
this.expires = init.expires;
this.httpOnly = init.httpOnly;
this.maxAge = init.maxAge;
this.name = init.name;
this.partitioned = init.partitioned;
this.path = init.path;
this.sameSite = init.sameSite;
this.secure = init.secure;
this.value = init.value;
}
}
}
/**
* Returns the string representation of the header value.
*
* @return The header value as a string
*/
toString() {
if (!this.name) {
return '';
}
let parts = [`${this.name}=${quote(this.value || '')}`];
if (this.domain) {
parts.push(`Domain=${this.domain}`);
}
if (this.expires) {
parts.push(`Expires=${this.expires.toUTCString()}`);
}
if (this.httpOnly) {
parts.push('HttpOnly');
}
if (this.maxAge != null) {
parts.push(`Max-Age=${this.maxAge}`);
}
if (this.partitioned) {
parts.push('Partitioned');
}
if (this.path) {
parts.push(`Path=${this.path}`);
}
if (this.sameSite) {
parts.push(`SameSite=${this.sameSite}`);
}
if (this.secure) {
parts.push('Secure');
}
return parts.join('; ');
}
}