first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

0
node_modules/structured-headers/dist/build generated vendored Normal file
View File

4
node_modules/structured-headers/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export * from './serializer';
export * from './parser';
export * from './types';
export { Token } from './token';

19
node_modules/structured-headers/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Token = void 0;
__exportStar(require("./serializer"), exports);
__exportStar(require("./parser"), exports);
__exportStar(require("./types"), exports);
var token_1 = require("./token");
Object.defineProperty(exports, "Token", { enumerable: true, get: function () { return token_1.Token; } });
//# sourceMappingURL=index.js.map

1
node_modules/structured-headers/dist/index.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,2CAAyB;AACzB,0CAAwB;AACxB,iCAAgC;AAAvB,8FAAA,KAAK,OAAA"}

38
node_modules/structured-headers/dist/parser.d.ts generated vendored Normal file
View File

@@ -0,0 +1,38 @@
import { Dictionary, List, Item } from './types';
export declare function parseDictionary(input: string): Dictionary;
export declare function parseList(input: string): List;
export declare function parseItem(input: string): Item;
export declare class ParseError extends Error {
constructor(position: number, message: string);
}
export default class Parser {
input: string;
pos: number;
constructor(input: string);
parseDictionary(): Dictionary;
parseList(): List;
parseItem(standaloneItem?: boolean): Item;
private parseItemOrInnerList;
private parseInnerList;
private parseBareItem;
private parseParameters;
private parseIntegerOrDecimal;
private parseString;
private parseToken;
private parseByteSequence;
private parseBoolean;
private parseKey;
/**
* Looks at the next character without advancing the cursor.
*/
private lookChar;
/**
* Checks if the next character is 'char', and fail otherwise.
*/
private expectChar;
private getChar;
private eof;
private skipOWS;
private skipWS;
private checkTrail;
}

343
node_modules/structured-headers/dist/parser.js generated vendored Normal file
View File

@@ -0,0 +1,343 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParseError = exports.parseItem = exports.parseList = exports.parseDictionary = void 0;
const types_1 = require("./types");
const token_1 = require("./token");
const util_1 = require("./util");
function parseDictionary(input) {
const parser = new Parser(input);
return parser.parseDictionary();
}
exports.parseDictionary = parseDictionary;
function parseList(input) {
const parser = new Parser(input);
return parser.parseList();
}
exports.parseList = parseList;
function parseItem(input) {
const parser = new Parser(input);
return parser.parseItem();
}
exports.parseItem = parseItem;
class ParseError extends Error {
constructor(position, message) {
super(`Parse error: ${message} at offset ${position}`);
}
}
exports.ParseError = ParseError;
class Parser {
constructor(input) {
this.input = input;
this.pos = 0;
}
parseDictionary() {
this.skipWS();
const dictionary = new Map();
while (!this.eof()) {
const thisKey = this.parseKey();
let member;
if (this.lookChar() === '=') {
this.pos++;
member = this.parseItemOrInnerList();
}
else {
member = [true, this.parseParameters()];
}
dictionary.set(thisKey, member);
this.skipOWS();
if (this.eof()) {
return dictionary;
}
this.expectChar(',');
this.pos++;
this.skipOWS();
if (this.eof()) {
throw new ParseError(this.pos, 'Dictionary contained a trailing comma');
}
}
return dictionary;
}
parseList() {
this.skipWS();
const members = [];
while (!this.eof()) {
members.push(this.parseItemOrInnerList());
this.skipOWS();
if (this.eof()) {
return members;
}
this.expectChar(',');
this.pos++;
this.skipOWS();
if (this.eof()) {
throw new ParseError(this.pos, 'A list may not end with a trailing comma');
}
}
return members;
}
parseItem(standaloneItem = true) {
if (standaloneItem)
this.skipWS();
const result = [
this.parseBareItem(),
this.parseParameters()
];
if (standaloneItem)
this.checkTrail();
return result;
}
parseItemOrInnerList() {
if (this.lookChar() === '(') {
return this.parseInnerList();
}
else {
return this.parseItem(false);
}
}
parseInnerList() {
this.expectChar('(');
this.pos++;
const innerList = [];
while (!this.eof()) {
this.skipWS();
if (this.lookChar() === ')') {
this.pos++;
return [
innerList,
this.parseParameters()
];
}
innerList.push(this.parseItem(false));
const nextChar = this.lookChar();
if (nextChar !== ' ' && nextChar !== ')') {
throw new ParseError(this.pos, 'Expected a whitespace or ) after every item in an inner list');
}
}
throw new ParseError(this.pos, 'Could not find end of inner list');
}
parseBareItem() {
const char = this.lookChar();
if (char.match(/^[-0-9]/)) {
return this.parseIntegerOrDecimal();
}
if (char === '"') {
return this.parseString();
}
if (char.match(/^[A-Za-z*]/)) {
return this.parseToken();
}
if (char === ':') {
return this.parseByteSequence();
}
if (char === '?') {
return this.parseBoolean();
}
throw new ParseError(this.pos, 'Unexpected input');
}
parseParameters() {
const parameters = new Map();
while (!this.eof()) {
const char = this.lookChar();
if (char !== ';') {
break;
}
this.pos++;
this.skipWS();
const key = this.parseKey();
let value = true;
if (this.lookChar() === '=') {
this.pos++;
value = this.parseBareItem();
}
parameters.set(key, value);
}
return parameters;
}
parseIntegerOrDecimal() {
let type = 'integer';
let sign = 1;
let inputNumber = '';
if (this.lookChar() === '-') {
sign = -1;
this.pos++;
}
// The spec wants this check but it's unreachable code.
//if (this.eof()) {
// throw new ParseError(this.pos, 'Empty integer');
//}
if (!isDigit(this.lookChar())) {
throw new ParseError(this.pos, 'Expected a digit (0-9)');
}
while (!this.eof()) {
const char = this.getChar();
if (isDigit(char)) {
inputNumber += char;
}
else if (type === 'integer' && char === '.') {
if (inputNumber.length > 12) {
throw new ParseError(this.pos, 'Exceeded maximum decimal length');
}
inputNumber += '.';
type = 'decimal';
}
else {
// We need to 'prepend' the character, so it's just a rewind
this.pos--;
break;
}
if (type === 'integer' && inputNumber.length > 15) {
throw new ParseError(this.pos, 'Exceeded maximum integer length');
}
if (type === 'decimal' && inputNumber.length > 16) {
throw new ParseError(this.pos, 'Exceeded maximum decimal length');
}
}
if (type === 'integer') {
return parseInt(inputNumber, 10) * sign;
}
else {
if (inputNumber.endsWith('.')) {
throw new ParseError(this.pos, 'Decimal cannot end on a period');
}
if (inputNumber.split('.')[1].length > 3) {
throw new ParseError(this.pos, 'Number of digits after the decimal point cannot exceed 3');
}
return parseFloat(inputNumber) * sign;
}
}
parseString() {
let outputString = '';
this.expectChar('"');
this.pos++;
while (!this.eof()) {
const char = this.getChar();
if (char === '\\') {
if (this.eof()) {
throw new ParseError(this.pos, 'Unexpected end of input');
}
const nextChar = this.getChar();
if (nextChar !== '\\' && nextChar !== '"') {
throw new ParseError(this.pos, 'A backslash must be followed by another backslash or double quote');
}
outputString += nextChar;
}
else if (char === '"') {
return outputString;
}
else if (!util_1.isAscii(char)) {
throw new Error('Strings must be in the ASCII range');
}
else {
outputString += char;
}
}
throw new ParseError(this.pos, 'Unexpected end of input');
}
parseToken() {
// The specification wants this check, but it's an unreachable code block.
// if (!/^[A-Za-z*]/.test(this.lookChar())) {
// throw new ParseError(this.pos, 'A token must begin with an asterisk or letter (A-Z, a-z)');
//}
let outputString = '';
while (!this.eof()) {
const char = this.lookChar();
if (!/^[:/!#$%&'*+\-.^_`|~A-Za-z0-9]$/.test(char)) {
return new token_1.Token(outputString);
}
outputString += this.getChar();
}
return new token_1.Token(outputString);
}
parseByteSequence() {
this.expectChar(':');
this.pos++;
const endPos = this.input.indexOf(':', this.pos);
if (endPos === -1) {
throw new ParseError(this.pos, 'Could not find a closing ":" character to mark end of Byte Sequence');
}
const b64Content = this.input.substring(this.pos, endPos);
this.pos += b64Content.length + 1;
if (!/^[A-Za-z0-9+/=]*$/.test(b64Content)) {
throw new ParseError(this.pos, 'ByteSequence does not contain a valid base64 string');
}
return new types_1.ByteSequence(b64Content);
}
parseBoolean() {
this.expectChar('?');
this.pos++;
const char = this.getChar();
if (char === '1') {
return true;
}
if (char === '0') {
return false;
}
throw new ParseError(this.pos, 'Unexpected character. Expected a "1" or a "0"');
}
parseKey() {
if (!this.lookChar().match(/^[a-z*]/)) {
throw new ParseError(this.pos, 'A key must begin with an asterisk or letter (a-z)');
}
let outputString = '';
while (!this.eof()) {
const char = this.lookChar();
if (!/^[a-z0-9_\-.*]$/.test(char)) {
return outputString;
}
outputString += this.getChar();
}
return outputString;
}
/**
* Looks at the next character without advancing the cursor.
*/
lookChar() {
return this.input[this.pos];
}
/**
* Checks if the next character is 'char', and fail otherwise.
*/
expectChar(char) {
if (this.lookChar() !== char) {
throw new ParseError(this.pos, `Expected ${char}`);
}
}
getChar() {
return this.input[this.pos++];
}
eof() {
return this.pos >= this.input.length;
}
// Advances the pointer to skip all whitespace.
skipOWS() {
while (true) {
const c = this.input.substr(this.pos, 1);
if (c === ' ' || c === '\t') {
this.pos++;
}
else {
break;
}
}
}
// Advances the pointer to skip all spaces
skipWS() {
while (this.lookChar() === ' ') {
this.pos++;
}
}
// At the end of parsing, we need to make sure there are no bytes after the
// header except whitespace.
checkTrail() {
this.skipWS();
if (!this.eof()) {
throw new ParseError(this.pos, 'Unexpected characters at end of input');
}
}
}
exports.default = Parser;
const isDigitRegex = /^[0-9]$/;
function isDigit(char) {
return isDigitRegex.test(char);
}
//# sourceMappingURL=parser.js.map

1
node_modules/structured-headers/dist/parser.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

6
node_modules/structured-headers/dist/serializer.d.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
import { Dictionary, Item, List } from './types';
export declare class SerializeError extends Error {
}
export declare function serializeList(input: List): string;
export declare function serializeDictionary(input: Dictionary): string;
export declare function serializeItem(input: Item): string;

112
node_modules/structured-headers/dist/serializer.js generated vendored Normal file
View File

@@ -0,0 +1,112 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.serializeItem = exports.serializeDictionary = exports.serializeList = exports.SerializeError = void 0;
const types_1 = require("./types");
const token_1 = require("./token");
const util_1 = require("./util");
class SerializeError extends Error {
}
exports.SerializeError = SerializeError;
function serializeList(input) {
return input.map(value => {
if (util_1.isInnerList(value)) {
return serializeInnerList(value);
}
else {
return serializeItem(value);
}
}).join(', ');
}
exports.serializeList = serializeList;
function serializeDictionary(input) {
return Array.from(input.entries()).map(([key, value]) => {
let out = serializeKey(key);
if (value[0] === true) {
out += serializeParameters(value[1]);
}
else {
out += '=';
if (util_1.isInnerList(value)) {
out += serializeInnerList(value);
}
else {
out += serializeItem(value);
}
}
return out;
}).join(', ');
}
exports.serializeDictionary = serializeDictionary;
function serializeItem(input) {
return serializeBareItem(input[0]) + serializeParameters(input[1]);
}
exports.serializeItem = serializeItem;
function serializeInnerList(input) {
return `(${input[0].map(value => serializeItem(value)).join(' ')})${serializeParameters(input[1])}`;
}
function serializeBareItem(input) {
if (typeof input === 'number') {
if (Number.isInteger(input)) {
return serializeInteger(input);
}
return serializeDecimal(input);
}
if (typeof input === 'string') {
return serializeString(input);
}
if (input instanceof token_1.Token) {
return serializeToken(input);
}
if (input instanceof types_1.ByteSequence) {
return serializeByteSequence(input);
}
if (typeof input === 'boolean') {
return serializeBoolean(input);
}
throw new SerializeError(`Cannot serialize values of type ${typeof input}`);
}
function serializeInteger(input) {
if (input < -999999999999999 || input > 999999999999999) {
throw new SerializeError('Structured headers can only encode integers in the range range of -999,999,999,999,999 to 999,999,999,999,999 inclusive');
}
return input.toString();
}
function serializeDecimal(input) {
const out = input.toFixed(3).replace(/0+$/, '');
const signifantDigits = out.split('.')[0].replace('-', '').length;
if (signifantDigits > 12) {
throw new SerializeError('Fractional numbers are not allowed to have more than 12 significant digits before the decimal point');
}
return out;
}
function serializeString(input) {
if (!util_1.isAscii(input)) {
throw new SerializeError('Only ASCII strings may be serialized');
}
return `"${input.replace(/("|\\)/g, (v) => '\\' + v)}"`;
}
function serializeBoolean(input) {
return input ? '?1' : '?0';
}
function serializeByteSequence(input) {
return `:${input.toBase64()}:`;
}
function serializeToken(input) {
return input.toString();
}
function serializeParameters(input) {
return Array.from(input).map(([key, value]) => {
let out = ';' + serializeKey(key);
if (value !== true) {
out += '=' + serializeBareItem(value);
}
return out;
}).join('');
}
function serializeKey(input) {
if (!util_1.isValidKeyStr(input)) {
throw new SerializeError('Keys in dictionaries must only contain lowercase letter, numbers, _-*. and must start with a letter or *');
}
return input;
}
//# sourceMappingURL=serializer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"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"}

5
node_modules/structured-headers/dist/token.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
export declare class Token {
private value;
constructor(value: string);
toString(): string;
}

17
node_modules/structured-headers/dist/token.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Token = void 0;
const util_1 = require("./util");
class Token {
constructor(value) {
if (!util_1.isValidTokenStr(value)) {
throw new TypeError('Invalid character in Token string. Tokens must start with *, A-Z and the rest of the string may only contain a-z, A-Z, 0-9, :/!#$%&\'*+-.^_`|~');
}
this.value = value;
}
toString() {
return this.value;
}
}
exports.Token = Token;
//# sourceMappingURL=token.js.map

1
node_modules/structured-headers/dist/token.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":";;;AAAA,iCAAyC;AAEzC,MAAa,KAAK;IAGhB,YAAY,KAAa;QAEvB,IAAI,CAAC,sBAAe,CAAC,KAAK,CAAC,EAAE;YAC3B,MAAM,IAAI,SAAS,CAAC,gJAAgJ,CAAC,CAAC;SACvK;QACD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAErB,CAAC;IAED,QAAQ;QAEN,OAAO,IAAI,CAAC,KAAK,CAAC;IAEpB,CAAC;CAEF;AAlBD,sBAkBC"}

34
node_modules/structured-headers/dist/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,34 @@
import { Token } from './token';
/**
* Lists are arrays of zero or more members, each of which can be an Item
* or an Inner List, both of which can be Parameterized
*/
export declare type List = (InnerList | Item)[];
/**
* An Inner List is an array of zero or more Items. Both the individual Items
* and the Inner List itself can be Parameterized.
*/
export declare type InnerList = [Item[], Parameters];
/**
* Parameters are an ordered map of key-value pairs that are associated with
* an Item or Inner List. The keys are unique within the scope of the
* Parameters they occur within, and the values are bare items (i.e., they
* themselves cannot be parameterized
*/
export declare type Parameters = Map<string, BareItem>;
/**
* Dictionaries are ordered maps of key-value pairs, where the keys are short
* textual strings and the values are Items or arrays of Items, both of which
* can be Parameterized.
*
* There can be zero or more members, and their keys are unique in the scope
* of the Dictionary they occur within.
*/
export declare type Dictionary = Map<string, Item | InnerList>;
export declare class ByteSequence {
base64Value: string;
constructor(base64Value: string);
toBase64(): string;
}
export declare type BareItem = number | string | Token | ByteSequence | boolean;
export declare type Item = [BareItem, Parameters];

13
node_modules/structured-headers/dist/types.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ByteSequence = void 0;
class ByteSequence {
constructor(base64Value) {
this.base64Value = base64Value;
}
toBase64() {
return this.base64Value;
}
}
exports.ByteSequence = ByteSequence;
//# sourceMappingURL=types.js.map

1
node_modules/structured-headers/dist/types.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAgCA,MAAa,YAAY;IAGvB,YAAY,WAAmB;QAE7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IAEjC,CAAC;IAED,QAAQ;QAEN,OAAO,IAAI,CAAC,WAAW,CAAC;IAE1B,CAAC;CAEF;AAfD,oCAeC"}

5
node_modules/structured-headers/dist/util.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import { Item, InnerList } from './types';
export declare function isAscii(str: string): boolean;
export declare function isValidTokenStr(str: string): boolean;
export declare function isValidKeyStr(str: string): boolean;
export declare function isInnerList(input: Item | InnerList): input is InnerList;

23
node_modules/structured-headers/dist/util.js generated vendored Normal file
View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isInnerList = exports.isValidKeyStr = exports.isValidTokenStr = exports.isAscii = void 0;
const asciiRe = /^[\x20-\x7E]*$/;
const tokenRe = /^[a-zA-Z*][:/!#$%&'*+\-.^_`|~A-Za-z0-9]*$/;
const keyRe = /^[a-z*][*\-_.a-z0-9]*$/;
function isAscii(str) {
return asciiRe.test(str);
}
exports.isAscii = isAscii;
function isValidTokenStr(str) {
return tokenRe.test(str);
}
exports.isValidTokenStr = isValidTokenStr;
function isValidKeyStr(str) {
return keyRe.test(str);
}
exports.isValidKeyStr = isValidKeyStr;
function isInnerList(input) {
return Array.isArray(input[0]);
}
exports.isInnerList = isInnerList;
//# sourceMappingURL=util.js.map

1
node_modules/structured-headers/dist/util.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;;AAEA,MAAM,OAAO,GAAG,gBAAgB,CAAC;AACjC,MAAM,OAAO,GAAG,2CAA2C,CAAC;AAC5D,MAAM,KAAK,GAAG,wBAAwB,CAAC;AAEvC,SAAgB,OAAO,CAAC,GAAW;IAEjC,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE3B,CAAC;AAJD,0BAIC;AAED,SAAgB,eAAe,CAAC,GAAW;IAEzC,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE3B,CAAC;AAJD,0CAIC;AAED,SAAgB,aAAa,CAAC,GAAW;IAEvC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEzB,CAAC;AAJD,sCAIC;AAGD,SAAgB,WAAW,CAAC,KAAuB;IAEjD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEjC,CAAC;AAJD,kCAIC"}

71
node_modules/structured-headers/package.json generated vendored Normal file
View File

@@ -0,0 +1,71 @@
{
"name": "structured-headers",
"version": "0.4.1",
"description": "Implementation of RFC8941, structured headers for HTTP.",
"main": "dist/index.js",
"scripts": {
"test": "make test",
"prepare": "make build",
"build": "make build"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/evert/structured-header.git"
},
"keywords": [
"http",
"structured-header",
"RFC8941",
"headers"
],
"author": "Evert Pot <me@evertpot.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/evert/structured-header/issues"
},
"files": [
"src/",
"dist/",
"browser/structured-header.min.js",
"browser/structured-header.min.js.map",
"LICENSE"
],
"homepage": "https://github.com/evert/structured-header#readme",
"devDependencies": {
"@types/node": "^12.20.13",
"@typescript-eslint/eslint-plugin": "^4.23.0",
"@typescript-eslint/parser": "^4.23.0",
"base32-decode": "^1.0.0",
"base32-encode": "^1.1.1",
"chai": "^4.2.0",
"eslint": "^7.26.0",
"mocha": "^9.0.0",
"nyc": "^15.1.0",
"ts-node": "^10.0.0",
"typescript": "^4.2.4",
"webpack": "^5.37.0",
"webpack-cli": "^4.7.0"
},
"nyc": {
"extension": [
".ts"
]
},
"mocha": {
"require": [
"ts-node/register"
],
"recursive": true,
"extension": [
"ts",
"js",
"tsx"
],
"exit": true
},
"browserslist": [
"last 2 versions",
"not ie 11",
"not op_mini all"
]
}

233
node_modules/structured-headers/readme.md generated vendored Normal file
View File

@@ -0,0 +1,233 @@
Structured Headers parser for Javascript
========================================
This library is a parser and serializer for the [Structured Headers][1]
specification, a.k.a. "Structured Field Values for HTTP" (RFC8941).
This specification defines a standard serialization for complex HTTP header
values, including lists (arrays), dictionaries (maps) and also numbers,
booleans, and binary data.
The library is written in Typescript, and the examples in this document are
too, but plain Javascript is also fully supported.
Compatibility
-------------
This package has 2725 unittests, the vast majority are supplied from the
official [HTTP WG test suite][2].
However, there are 2 differences in the serializer:
1. Javascript can't differentiate between `1.0` and `1`. As a result we're
skipping the tests that require a serialiation output of `1.0`.
2. Javascript rounds slightly different from the spec. The tests suggest that
`0.0025` should round to the nearest event number (`0.002`), but Javascript
rounds to `0.003`.
No fix is planned for #1, because there's no reasonably way to fix this
without wrapping every number in a custom class, and this will negatively
impact the developer experience. We do intend to fix #2 in the future with a
custom rounding algorithm.
This library emits and expects the _exact_ data structures as they are
suggested by the RFC. The result of this is that the returned types can be
a bit complex.
In the future we intend to loosen the required types for the serializer, and
add new helper functions that give you simpler structures _if_ you don't need
certain features for a header (such as `Parameters`).
Let us know what you would like to see here!
Installation
------------
Using npm:
```
npm install structured-headers
```
API
---
### Parsing an item
The following are examples of `item` headers:
Parsed as string
```
# Parsed as string
Header: "foo"
# A simple string, called a 'Token' in the spec
Header: foo
# Parsed as number
Header: 5
Header: -10
Header: 5.01415
# Parsed into boolean
Header: ?1
Header: ?0
# Binaries are base64 encoded
Header: :RE0gbWUgZm9yIGEgZnJlZSBjb29raWU=:
# Items can have parameters
Header: "Hello world"; a="5"
```
To parse these header values, use the `parseItem`:
```typescript
import { parseItem } from 'structured-headers';
console.log(
parseItem(header)
);
```
parseItem returns a tuple (array with 2 items), the first item is the value,
the second is a `Map` object with parameters.
The type is roughly:
```typescript
// The raw value
type BareItem = number | string | Token | ByteSequence | boolean;
// The return type of parseItem
type Item = [
BareItem,
Map<string, BareItem>
];
```
### Parsing a list
A list is an array of items. Some examples:
```
# A simple list
Header: 5, "foo", bar, ?1
# Each element can have parameters
Header: sometoken; param1; param2=hi, 42
# A list can also contain lists itself. These are called 'inner lists' and
# use parenthesis
Header: sometoken, (innerlistitem1 innerlistitem2), (anotherlist)
```
To parse these:
```typescript
import { parseList } from 'structured-headers';
console.log(
parseList(header)
);
```
`parseList` returns an array with each member. The return type is:
```typescript
type InnerList = [Item[], Parameters];
type List = (InnerList|Item)[];
```
### Parsing a dictionary
A dictionary is a key->value object. Examples:
```
# A simple dictionary
Header: fn="evert", ln="pot", coffee=?1
# Each item may have parameters too
Header: foo=123; q=1, bar=123, q=0.5
# A dictionary value may be an inner list again
Header: foo=(1 2 3)
```
To parse dictionaries:
```typescript
import { parseDictionary } from 'structured-headers';
console.log(
parseDictionary(header)
);
```
The return type for `parseDictionary` is a `Map`.
```typescript
type Dictionary = Map<string, Item|InnerList>;
```
### Serializing
The serialiser functions work the exact same way, but in opposite direction.
They all return strings.
Currently the serializes expect the *exact type* that the parsers return, but
the intention is to loosen the types for serialization, so it's a bit more
ergnomic to call. Want this? Let me know by opening an issue.
```javascript
import {
serializeDictionary,
serializeList,
serializeItem
} from 'structured-headers';
// Returns "foo", "bar"
serializeList([
['foo', new Map()],
['bar', new Map()],
]);
// Returns a=1, b=?0
sh.serializeDictionary(new Map([
['a', [1, new Map()]],
['b', [false, new Map()]],
]));
// Returns 42
serializeItem([42, new Map()]);
// Returns 5.5
serializeItem([5.5, new Map()]);
// Returns "hello world"
serializeItem(["hello world", new Map()]);
// Returns ?1
serializeItem([true, new Map()]);
// Returns a base-64 representation like: *aGVsbG8=*
serializeItem([new ByteSequence('aGVsbG8='), new Map()]);
```
Browser support
---------------
There is a minified version of this library in the `browser/` directory. This minified
file will expose a global variable called 'structuredHeader' which contains the rest
of the api.
[1]: https://datatracker.ietf.org/doc/html/rfc8941
[2]: https://github.com/httpwg/structured-field-tests

4
node_modules/structured-headers/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export * from './serializer';
export * from './parser';
export * from './types';
export { Token } from './token';

443
node_modules/structured-headers/src/parser.ts generated vendored Normal file
View File

@@ -0,0 +1,443 @@
import {
Dictionary,
List,
Item,
BareItem,
Parameters,
InnerList,
ByteSequence
} from './types';
import { Token } from './token';
import { isAscii } from './util';
export function parseDictionary(input: string): Dictionary {
const parser = new Parser(input);
return parser.parseDictionary();
}
export function parseList(input: string): List {
const parser = new Parser(input);
return parser.parseList();
}
export function parseItem(input: string): Item {
const parser = new Parser(input);
return parser.parseItem();
}
export class ParseError extends Error {
constructor(position: number, message:string) {
super(`Parse error: ${message} at offset ${position}`);
}
}
export default class Parser {
input: string;
pos: number;
constructor(input: string) {
this.input = input;
this.pos = 0;
}
parseDictionary(): Dictionary {
this.skipWS();
const dictionary = new Map();
while(!this.eof()) {
const thisKey = this.parseKey();
let member;
if (this.lookChar()==='=') {
this.pos++;
member = this.parseItemOrInnerList();
} else {
member = [true, this.parseParameters()];
}
dictionary.set(thisKey, member);
this.skipOWS();
if (this.eof()) {
return dictionary;
}
this.expectChar(',');
this.pos++;
this.skipOWS();
if (this.eof()) {
throw new ParseError(this.pos, 'Dictionary contained a trailing comma');
}
}
return dictionary;
}
parseList(): List {
this.skipWS();
const members: List = [];
while(!this.eof()) {
members.push(
this.parseItemOrInnerList()
);
this.skipOWS();
if (this.eof()) {
return members;
}
this.expectChar(',');
this.pos++;
this.skipOWS();
if (this.eof()) {
throw new ParseError(this.pos, 'A list may not end with a trailing comma');
}
}
return members;
}
parseItem(standaloneItem: boolean = true): Item {
if (standaloneItem) this.skipWS();
const result: Item = [
this.parseBareItem(),
this.parseParameters()
];
if (standaloneItem) this.checkTrail();
return result;
}
private parseItemOrInnerList(): Item|InnerList {
if (this.lookChar()==='(') {
return this.parseInnerList();
} else {
return this.parseItem(false);
}
}
private parseInnerList(): InnerList {
this.expectChar('(');
this.pos++;
const innerList: Item[] = [];
while(!this.eof()) {
this.skipWS();
if (this.lookChar() === ')') {
this.pos++;
return [
innerList,
this.parseParameters()
];
}
innerList.push(this.parseItem(false));
const nextChar = this.lookChar();
if (nextChar!==' ' && nextChar !== ')') {
throw new ParseError(this.pos, 'Expected a whitespace or ) after every item in an inner list');
}
}
throw new ParseError(this.pos, 'Could not find end of inner list');
}
private parseBareItem(): BareItem {
const char = this.lookChar();
if (char.match(/^[-0-9]/)) {
return this.parseIntegerOrDecimal();
}
if (char === '"') {
return this.parseString();
}
if (char.match(/^[A-Za-z*]/)) {
return this.parseToken();
}
if (char === ':' ) {
return this.parseByteSequence();
}
if (char === '?') {
return this.parseBoolean();
}
throw new ParseError(this.pos, 'Unexpected input');
}
private parseParameters(): Parameters {
const parameters = new Map();
while(!this.eof()) {
const char = this.lookChar();
if (char!==';') {
break;
}
this.pos++;
this.skipWS();
const key = this.parseKey();
let value: BareItem = true;
if (this.lookChar() === '=') {
this.pos++;
value = this.parseBareItem();
}
parameters.set(key, value);
}
return parameters;
}
private parseIntegerOrDecimal(): number {
let type: 'integer' | 'decimal' = 'integer';
let sign = 1;
let inputNumber = '';
if (this.lookChar()==='-') {
sign = -1;
this.pos++;
}
// The spec wants this check but it's unreachable code.
//if (this.eof()) {
// throw new ParseError(this.pos, 'Empty integer');
//}
if (!isDigit(this.lookChar())) {
throw new ParseError(this.pos, 'Expected a digit (0-9)');
}
while(!this.eof()) {
const char = this.getChar();
if (isDigit(char)) {
inputNumber+=char;
} else if (type === 'integer' && char === '.') {
if (inputNumber.length>12) {
throw new ParseError(this.pos, 'Exceeded maximum decimal length');
}
inputNumber+='.';
type = 'decimal';
} else {
// We need to 'prepend' the character, so it's just a rewind
this.pos--;
break;
}
if (type === 'integer' && inputNumber.length>15) {
throw new ParseError(this.pos, 'Exceeded maximum integer length');
}
if (type === 'decimal' && inputNumber.length>16) {
throw new ParseError(this.pos, 'Exceeded maximum decimal length');
}
}
if (type === 'integer') {
return parseInt(inputNumber, 10) * sign;
} else {
if (inputNumber.endsWith('.')) {
throw new ParseError(this.pos, 'Decimal cannot end on a period');
}
if (inputNumber.split('.')[1].length>3) {
throw new ParseError(this.pos, 'Number of digits after the decimal point cannot exceed 3');
}
return parseFloat(inputNumber) * sign;
}
}
private parseString(): string {
let outputString = '';
this.expectChar('"');
this.pos++;
while(!this.eof()) {
const char = this.getChar();
if (char==='\\') {
if (this.eof()) {
throw new ParseError(this.pos, 'Unexpected end of input');
}
const nextChar = this.getChar();
if (nextChar!=='\\' && nextChar !== '"') {
throw new ParseError(this.pos, 'A backslash must be followed by another backslash or double quote');
}
outputString+=nextChar;
} else if (char === '"') {
return outputString;
} else if (!isAscii(char)) {
throw new Error('Strings must be in the ASCII range');
} else {
outputString += char;
}
}
throw new ParseError(this.pos, 'Unexpected end of input');
}
private parseToken(): Token {
// The specification wants this check, but it's an unreachable code block.
// if (!/^[A-Za-z*]/.test(this.lookChar())) {
// throw new ParseError(this.pos, 'A token must begin with an asterisk or letter (A-Z, a-z)');
//}
let outputString = '';
while(!this.eof()) {
const char = this.lookChar();
if (!/^[:/!#$%&'*+\-.^_`|~A-Za-z0-9]$/.test(char)) {
return new Token(outputString);
}
outputString += this.getChar();
}
return new Token(outputString);
}
private parseByteSequence(): ByteSequence {
this.expectChar(':');
this.pos++;
const endPos = this.input.indexOf(':', this.pos);
if (endPos === -1) {
throw new ParseError(this.pos, 'Could not find a closing ":" character to mark end of Byte Sequence');
}
const b64Content = this.input.substring(this.pos, endPos);
this.pos += b64Content.length+1;
if (!/^[A-Za-z0-9+/=]*$/.test(b64Content)) {
throw new ParseError(this.pos, 'ByteSequence does not contain a valid base64 string');
}
return new ByteSequence(b64Content);
}
private parseBoolean(): boolean {
this.expectChar('?');
this.pos++;
const char = this.getChar();
if (char === '1') {
return true;
}
if (char === '0') {
return false;
}
throw new ParseError(this.pos, 'Unexpected character. Expected a "1" or a "0"');
}
private parseKey(): string {
if (!this.lookChar().match(/^[a-z*]/)) {
throw new ParseError(this.pos, 'A key must begin with an asterisk or letter (a-z)');
}
let outputString = '';
while(!this.eof()) {
const char = this.lookChar();
if (!/^[a-z0-9_\-.*]$/.test(char)) {
return outputString;
}
outputString += this.getChar();
}
return outputString;
}
/**
* Looks at the next character without advancing the cursor.
*/
private lookChar():string {
return this.input[this.pos];
}
/**
* Checks if the next character is 'char', and fail otherwise.
*/
private expectChar(char: string): void {
if (this.lookChar()!==char) {
throw new ParseError(this.pos, `Expected ${char}`);
}
}
private getChar(): string {
return this.input[this.pos++];
}
private eof():boolean {
return this.pos>=this.input.length;
}
// Advances the pointer to skip all whitespace.
private skipOWS(): void {
while (true) {
const c = this.input.substr(this.pos, 1);
if (c === ' ' || c === '\t') {
this.pos++;
} else {
break;
}
}
}
// Advances the pointer to skip all spaces
private skipWS(): void {
while(this.lookChar()===' ') {
this.pos++;
}
}
// At the end of parsing, we need to make sure there are no bytes after the
// header except whitespace.
private checkTrail(): void {
this.skipWS();
if (!this.eof()) {
throw new ParseError(this.pos, 'Unexpected characters at end of input');
}
}
}
const isDigitRegex = /^[0-9]$/;
function isDigit(char: string): boolean {
return isDigitRegex.test(char);
}

147
node_modules/structured-headers/src/serializer.ts generated vendored Normal file
View File

@@ -0,0 +1,147 @@
import {
BareItem,
ByteSequence,
Dictionary,
InnerList,
Item,
List,
Parameters,
} from './types';
import { Token } from './token';
import { isAscii, isInnerList, isValidKeyStr } from './util';
export class SerializeError extends Error {}
export function serializeList(input: List): string {
return input.map(value => {
if (isInnerList(value)) {
return serializeInnerList(value);
} else {
return serializeItem(value);
}
}).join(', ');
}
export function serializeDictionary(input: Dictionary): string {
return Array.from(
input.entries()
).map(([key, value]) => {
let out = serializeKey(key);
if (value[0]===true) {
out += serializeParameters(value[1]);
} else {
out += '=';
if (isInnerList(value)) {
out += serializeInnerList(value);
} else {
out += serializeItem(value);
}
}
return out;
}).join(', ');
}
export function serializeItem(input: Item): string {
return serializeBareItem(input[0]) + serializeParameters(input[1]);
}
function serializeInnerList(input: InnerList): string {
return `(${input[0].map(value => serializeItem(value)).join(' ')})${serializeParameters(input[1])}`;
}
function serializeBareItem(input: BareItem): string {
if (typeof input === 'number') {
if (Number.isInteger(input)) {
return serializeInteger(input);
}
return serializeDecimal(input);
}
if (typeof input === 'string') {
return serializeString(input);
}
if (input instanceof Token) {
return serializeToken(input);
}
if (input instanceof ByteSequence) {
return serializeByteSequence(input);
}
if (typeof input === 'boolean') {
return serializeBoolean(input);
}
throw new SerializeError(`Cannot serialize values of type ${typeof input}`);
}
function serializeInteger(input: number): string {
if (input < -999_999_999_999_999 || input > 999_999_999_999_999) {
throw new SerializeError('Structured headers can only encode integers in the range range of -999,999,999,999,999 to 999,999,999,999,999 inclusive');
}
return input.toString();
}
function serializeDecimal(input: number): string {
const out = input.toFixed(3).replace(/0+$/,'');
const signifantDigits = out.split('.')[0].replace('-','').length;
if (signifantDigits > 12) {
throw new SerializeError('Fractional numbers are not allowed to have more than 12 significant digits before the decimal point');
}
return out;
}
function serializeString(input: string): string {
if (!isAscii(input)) {
throw new SerializeError('Only ASCII strings may be serialized');
}
return `"${input.replace(/("|\\)/g, (v) => '\\' + v)}"`;
}
function serializeBoolean(input: boolean): string {
return input ? '?1' : '?0';
}
function serializeByteSequence(input: ByteSequence): string {
return `:${input.toBase64()}:`;
}
function serializeToken(input: Token): string {
return input.toString();
}
function serializeParameters(input: Parameters): string {
return Array.from(input).map(([key, value]) => {
let out = ';' + serializeKey(key);
if (value!==true) {
out+='=' + serializeBareItem(value);
}
return out;
}).join('');
}
function serializeKey(input: string): string {
if (!isValidKeyStr(input)) {
throw new SerializeError('Keys in dictionaries must only contain lowercase letter, numbers, _-*. and must start with a letter or *');
}
return input;
}

21
node_modules/structured-headers/src/token.ts generated vendored Normal file
View File

@@ -0,0 +1,21 @@
import { isValidTokenStr } from './util';
export class Token {
private value: string;
constructor(value: string) {
if (!isValidTokenStr(value)) {
throw new TypeError('Invalid character in Token string. Tokens must start with *, A-Z and the rest of the string may only contain a-z, A-Z, 0-9, :/!#$%&\'*+-.^_`|~');
}
this.value = value;
}
toString(): string {
return this.value;
}
}

52
node_modules/structured-headers/src/types.ts generated vendored Normal file
View File

@@ -0,0 +1,52 @@
import { Token } from './token';
/**
* Lists are arrays of zero or more members, each of which can be an Item
* or an Inner List, both of which can be Parameterized
*/
export type List = (InnerList|Item)[];
/**
* An Inner List is an array of zero or more Items. Both the individual Items
* and the Inner List itself can be Parameterized.
*/
export type InnerList = [Item[], Parameters];
/**
* Parameters are an ordered map of key-value pairs that are associated with
* an Item or Inner List. The keys are unique within the scope of the
* Parameters they occur within, and the values are bare items (i.e., they
* themselves cannot be parameterized
*/
export type Parameters = Map<string, BareItem>;
/**
* Dictionaries are ordered maps of key-value pairs, where the keys are short
* textual strings and the values are Items or arrays of Items, both of which
* can be Parameterized.
*
* There can be zero or more members, and their keys are unique in the scope
* of the Dictionary they occur within.
*/
export type Dictionary = Map<string, Item|InnerList>;
export class ByteSequence {
base64Value: string;
constructor(base64Value: string) {
this.base64Value = base64Value;
}
toBase64(): string {
return this.base64Value;
}
}
export type BareItem = number | string | Token | ByteSequence | boolean;
export type Item = [BareItem, Parameters];

30
node_modules/structured-headers/src/util.ts generated vendored Normal file
View File

@@ -0,0 +1,30 @@
import { Item, InnerList } from './types';
const asciiRe = /^[\x20-\x7E]*$/;
const tokenRe = /^[a-zA-Z*][:/!#$%&'*+\-.^_`|~A-Za-z0-9]*$/;
const keyRe = /^[a-z*][*\-_.a-z0-9]*$/;
export function isAscii(str: string): boolean {
return asciiRe.test(str);
}
export function isValidTokenStr(str: string): boolean {
return tokenRe.test(str);
}
export function isValidKeyStr(str: string): boolean {
return keyRe.test(str);
}
export function isInnerList(input: Item | InnerList): input is InnerList {
return Array.isArray(input[0]);
}