feat: complete Ancestor quote bot with production-ready Docker support

This commit is contained in:
unfunny
2026-09-13 14:14:38 -04:00
parent f2016da05a
commit fe7351a7dc
1145 changed files with 30890 additions and 97684 deletions

91
node_modules/content-type/README.md generated vendored
View File

@@ -1,57 +1,81 @@
# content-type
[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]
[![Build status][build-image]][build-url]
[![Build coverage][coverage-image]][coverage-url]
[![License][license-image]][license-url]
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-image]][node-url]
[![Build Status][ci-image]][ci-url]
[![Coverage Status][coveralls-image]][coveralls-url]
Create and parse HTTP `Content-Type` header.
Create and parse HTTP Content-Type header according to RFC 7231
## Installation
```sh
npm install content-type
$ npm install content-type
```
## API
```js
const contentType = require("content-type");
var contentType = require('content-type')
```
### contentType.parse(string, options?)
### contentType.parse(string)
```js
const obj = contentType.parse("image/svg+xml; charset=utf-8");
var obj = contentType.parse('image/svg+xml; charset=utf-8')
```
Parse a `Content-Type` header. This will return an object with the following properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`):
Parse a `Content-Type` header. This will return an object with the following
properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`):
- `type`: The media type. Example: `'image/svg+xml'`.
- `parameters`: An object of the parameters in the media type (parameter name is always lower case). Example: `{charset: 'utf-8'}`.
- `type`: The media type (the type and subtype, always lower case).
Example: `'image/svg+xml'`
The parser is lenient and does not error. You should validate `type` and `parameters` before trusting them.
- `parameters`: An object of the parameters in the media type (name of parameter
always lower case). Example: `{charset: 'utf-8'}`
#### Options
Throws a `TypeError` if the string is missing or invalid.
- `parameters` (default: `true`): Set to `false` to skip parameters.
- `comma` (default: `false`): Set to `true` to stop on a comma. This can be used to parse the media range in an `Accept` header.
- `start` (default: `0`): Set index to start parsing from.
### contentType.parse(req)
```js
var obj = contentType.parse(req)
```
Parse the `Content-Type` header from the given `req`. Short-cut for
`contentType.parse(req.headers['content-type'])`.
Throws a `TypeError` if the `Content-Type` header is missing or invalid.
### contentType.parse(res)
```js
var obj = contentType.parse(res)
```
Parse the `Content-Type` header set on the given `res`. Short-cut for
`contentType.parse(res.getHeader('content-type'))`.
Throws a `TypeError` if the `Content-Type` header is missing or invalid.
### contentType.format(obj)
```js
const str = contentType.format({
type: "image/svg+xml",
parameters: { charset: "utf-8" },
});
var str = contentType.format({
type: 'image/svg+xml',
parameters: { charset: 'utf-8' }
})
```
Format an object into a `Content-Type` header. This will return a string of the content type for the given object with the following properties (examples are shown that produce the string `'image/svg+xml; charset=utf-8'`):
Format an object into a `Content-Type` header. This will return a string of the
content type for the given object with the following properties (examples are
shown that produce the string `'image/svg+xml; charset=utf-8'`):
- `type`: The media type. Example: `'image/svg+xml'`.
- `parameters`: An optional object of the parameters in the media type. Example: `{charset: 'utf-8'}`.
- `type`: The media type (will be lower-cased). Example: `'image/svg+xml'`
- `parameters`: An object of the parameters in the media type (name of the
parameter will be lower-cased). Example: `{charset: 'utf-8'}`
Throws a `TypeError` if the object contains an invalid type or parameter names.
@@ -59,13 +83,12 @@ Throws a `TypeError` if the object contains an invalid type or parameter names.
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/content-type
[ci-image]: https://badgen.net/github/checks/jshttp/content-type/master?label=ci
[ci-url]: https://github.com/jshttp/content-type/actions/workflows/ci.yml
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/content-type/master
[coveralls-url]: https://coveralls.io/r/jshttp/content-type?branch=master
[node-image]: https://badgen.net/npm/node/content-type
[node-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/content-type
[npm-url]: https://npmjs.org/package/content-type
[downloads-image]: https://img.shields.io/npm/dm/content-type
[downloads-url]: https://npmjs.org/package/content-type
[build-image]: https://img.shields.io/github/actions/workflow/status/jshttp/content-type/ci.yml?branch=master
[build-url]: https://github.com/jshttp/content-type/actions/workflows/ci.yml?query=branch%3Amaster
[coverage-image]: https://img.shields.io/codecov/c/gh/jshttp/content-type
[coverage-url]: https://codecov.io/gh/jshttp/content-type
[license-image]: http://img.shields.io/npm/l/content-type.svg?style=flat
[license-url]: LICENSE
[npm-version-image]: https://badgen.net/npm/v/content-type

View File

@@ -1,46 +0,0 @@
/*!
* content-type
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* The content type object contains a type string and optional parameters.
*/
export interface ContentType {
type: string;
index: number;
parameters: Record<string, string>;
}
/**
* Format an object into a `Content-Type` header.
*/
export declare function format(obj: Partial<ContentType>): string;
/**
* Options for parsing a `Content-Type` header.
*/
export interface ParseOptions {
/**
* Exit early on the first semicolon, returning only the type.
* This is useful for parsing the MIME from `Content-Type` headers.
*
* @default false
*/
parameters?: boolean;
/**
* Exits early on a comma, returning the first value and parameters.
* This is useful for parsing `Accept` headers.
*
* @default false
*/
comma?: boolean;
/**
* The index to start parsing from.
*
* @default 0
*/
start?: number;
}
/**
* Parse a `Content-Type` header.
*/
export declare function parse(header: string, options?: ParseOptions): ContentType;

View File

@@ -1,176 +0,0 @@
"use strict";
/*!
* content-type
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.format = format;
exports.parse = parse;
const TEXT_REGEXP = /^[\u0009\u0020-\u007e\u0080-\u00ff]*$/;
const TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
/**
* RegExp to match chars that must be quoted-pair in RFC 9110 sec 5.6.4
*/
const QUOTE_REGEXP = /[\\"]/g;
/**
* RegExp to match type in RFC 9110 sec 8.3.1
*
* media-type = type "/" subtype
* type = token
* subtype = token
*/
const TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
/**
* Null object perf optimization. Faster than `Object.create(null)` and `{ __proto__: null }`.
*/
const NullObject = /* @__PURE__ */ (() => {
const C = function () { };
C.prototype = Object.create(null);
return C;
})();
/**
* Format an object into a `Content-Type` header.
*/
function format(obj) {
const { type, parameters } = obj;
if (!type || !TYPE_REGEXP.test(type)) {
throw new TypeError(`Invalid type: ${type}`);
}
let result = type;
if (parameters) {
for (const param of Object.keys(parameters)) {
if (!TOKEN_REGEXP.test(param)) {
throw new TypeError(`Invalid parameter name: ${param}`);
}
result += `; ${param}=${qstring(parameters[param])}`;
}
}
return result;
}
/**
* Parse a `Content-Type` header.
*/
function parse(header, options) {
const stopChar = options?.comma === true ? COMMA : 65536; // Sentinel for "no stop char".
const len = header.length;
let index = skipOWS(header, options?.start ?? 0, len);
const valueStart = index;
index = skipValue(header, index, len, stopChar);
const valueEnd = trailingOWS(header, valueStart, index);
const type = header.slice(valueStart, valueEnd).toLowerCase();
if (options?.parameters === false) {
return { type, index, parameters: new NullObject() };
}
return parseParameters(header, type, index, len, stopChar);
}
const SP = 32; // " "
const HTAB = 9; // "\t"
const SEMI = 59; // ";"
const EQ = 61; // "="
const DQUOTE = 34; // '"'
const BSLASH = 92; // "\\"
const COMMA = 44; // ","
/**
* Parses the parameters of a `Content-Type` header starting at the given index.
*/
function parseParameters(header, type, index, len, stopChar) {
const parameters = new NullObject();
parameter: while (index < len) {
if (header.charCodeAt(index) === stopChar)
break;
index = skipOWS(header, index + 1 /* Skip over ; */, len);
const keyStart = index;
while (index < len) {
const code = header.charCodeAt(index);
if (code === stopChar)
break parameter;
if (code === SEMI)
continue parameter;
if (code === EQ) {
const keyEnd = trailingOWS(header, keyStart, index);
const key = header.slice(keyStart, keyEnd).toLowerCase();
index = skipOWS(header, index + 1, len);
if (index < len && header.charCodeAt(index) === DQUOTE) {
index++;
let value = "";
while (index < len) {
const code = header.charCodeAt(index++);
if (code === DQUOTE) {
index = skipValue(header, index, len, stopChar);
if (parameters[key] === undefined)
parameters[key] = value;
break;
}
if (code === BSLASH && index < len) {
value += header[index++];
continue;
}
value += String.fromCharCode(code);
}
continue parameter;
}
const valueStart = index;
index = skipValue(header, index, len, stopChar);
if (parameters[key] === undefined) {
const valueEnd = trailingOWS(header, valueStart, index);
parameters[key] = header.slice(valueStart, valueEnd);
}
continue parameter;
}
index++;
}
}
return { type, index, parameters };
}
/**
* Skip over characters until a semicolon or other exit character.
*/
function skipValue(str, index, len, stopChar) {
while (index < len) {
const code = str.charCodeAt(index);
if (code === SEMI || code === stopChar)
break;
index++;
}
return index;
}
/**
* Skip optional whitespace (OWS) in an HTTP header value.
*
* OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t").
*/
function skipOWS(header, index, len) {
while (index < len) {
const char = header.charCodeAt(index);
if (char !== SP && char !== HTAB)
break;
index++;
}
return index;
}
/**
* Trim optional whitespace (OWS) from the end of a substring.
*
* OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t").
*/
function trailingOWS(header, start, end) {
while (end > start) {
const char = header.charCodeAt(end - 1);
if (char !== SP && char !== HTAB)
break;
end--;
}
return end;
}
/**
* Serialize a parameter value.
*/
function qstring(str) {
if (TOKEN_REGEXP.test(str))
return str;
if (TEXT_REGEXP.test(str))
return `"${str.replace(QUOTE_REGEXP, "\\$&")}"`;
throw new TypeError(`Invalid parameter value: ${str}`);
}
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,52 +1,42 @@
{
"name": "content-type",
"version": "2.1.0",
"description": "Create and parse HTTP Content-Type header",
"version": "1.0.5",
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
"license": "MIT",
"keywords": [
"content-type",
"http",
"req",
"res",
"rfc7231",
"rfc9110"
"rfc7231"
],
"repository": "jshttp/content-type",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
},
"license": "MIT",
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
"type": "commonjs",
"exports": "./dist/index.js",
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",
"files": [
"dist/"
],
"scripts": {
"bench": "vitest bench",
"build": "ts-scripts build",
"format": "ts-scripts format",
"prepare": "ts-scripts install && npm run build",
"specs": "ts-scripts specs",
"test": "ts-scripts test"
},
"devDependencies": {
"@borderless/ts-scripts": "^0.15.0",
"@vitest/coverage-v8": "^3.0.5",
"typescript": "^5.7.3",
"vitest": "^3.2.4"
"deep-equal": "1.0.1",
"eslint": "8.32.0",
"eslint-config-standard": "15.0.1",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-standard": "4.1.0",
"mocha": "10.2.0",
"nyc": "15.1.0"
},
"files": [
"LICENSE",
"HISTORY.md",
"README.md",
"index.js"
],
"engines": {
"node": ">=18"
"node": ">= 0.6"
},
"ts-scripts": {
"dist": [
"dist"
],
"project": [
"tsconfig.build.json"
]
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec --check-leaks --bail test/",
"test-ci": "nyc --reporter=lcovonly --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test",
"version": "node scripts/version-history.js && git add HISTORY.md"
}
}