diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000..9594f78 Binary files /dev/null and b/bun.lockb differ diff --git a/components/AssignmentList.js b/components/AssignmentList.js index 944fb71..d3a7594 100644 --- a/components/AssignmentList.js +++ b/components/AssignmentList.js @@ -4,18 +4,17 @@ import AssignmentTags from "./AssignmentTags.js"; export default { components: { Assignment, AssignmentTags }, template: ` -
-

{{ title }} ({{ assignments.length }})

+
+

{{ title }} ({{ visibleAssignments.length }})

    - +
`, @@ -32,14 +31,11 @@ export default { }, computed: { - filteredAssignments() { - return this.assignments.filter( - (a) => a.tag === this.currentTag || this.currentTag === "all" - ); - }, - - tags() { - return new Set(this.assignments.map((a) => a.tag)); + visibleAssignments() { + if (this.currentTag === "all") { + return this.assignments; + } + return this.assignments.filter((a) => a.tag === this.currentTag); }, }, }; diff --git a/components/AssignmentTags.js b/components/AssignmentTags.js index ee4ba53..9c9a698 100644 --- a/components/AssignmentTags.js +++ b/components/AssignmentTags.js @@ -5,7 +5,7 @@ export default { class="border rounded p-1 text-xs" @click="$emit('change', tag)" v-for="tag in tags" - :class="{ 'border-blue-500 text-blue-400': tag === currentTag}" + :class="getButtonClass(tag)" > {{ tag }} @@ -22,4 +22,12 @@ export default { return ["all", ...new Set(this.initTags)]; }, }, + + methods: { + getButtonClass(tag) { + return { + "border-blue-500 text-blue-400": tag === this.currentTag, + }; + }, + }, }; diff --git a/components/Assignments.js b/components/Assignments.js index d301c28..1b92e6f 100644 --- a/components/Assignments.js +++ b/components/Assignments.js @@ -20,11 +20,7 @@ export default { data() { return { - assignments: [ - { name: "Check Project", complete: true, id: 1, tag: "math" }, - { name: "Read Books", complete: false, id: 2, tag: "science" }, - { name: "Learn Vue", complete: false, id: 3, tag: "programming" }, - ], + assignments: [], }; }, @@ -32,13 +28,19 @@ export default { filters() { return { inProgress: this.assignments.filter( - (assignment) => !assignment.complete + (assignment) => !assignment.complete, ), completed: this.assignments.filter((assignment) => assignment.complete), }; }, }, + created() { + fetch("http://localhost:3001/assignments") + .then((res) => res.json()) + .then((data) => (this.assignments = data)); + }, + methods: { add(name) { this.assignments.push({ diff --git a/db.json b/db.json new file mode 100644 index 0000000..6668816 --- /dev/null +++ b/db.json @@ -0,0 +1,15 @@ +{ + "assignments": [ + { "name": "Check Project", "complete": true, "id": 1, "tag": "math" }, + { "name": "Read Books", "complete": false, "id": 2, "tag": "science" }, + { "name": "Learn Vue", "complete": false, "id": 3, "tag": "programming" }, + { "name": "Learn React", "complete": false, "id": 4, "tag": "programming" }, + { + "name": "Complete Laravel", + "complete": true, + "id": 5, + "tag": "programming" + }, + { "name": "Do Algebra", "complete": false, "id": 6, "tag": "math" } + ] +} diff --git a/node_modules/.bin/json-server b/node_modules/.bin/json-server new file mode 120000 index 0000000..666af44 --- /dev/null +++ b/node_modules/.bin/json-server @@ -0,0 +1 @@ +../json-server/lib/bin.js \ No newline at end of file diff --git a/node_modules/.bin/json5 b/node_modules/.bin/json5 new file mode 120000 index 0000000..217f379 --- /dev/null +++ b/node_modules/.bin/json5 @@ -0,0 +1 @@ +../json5/lib/cli.js \ No newline at end of file diff --git a/node_modules/.bin/mime b/node_modules/.bin/mime new file mode 120000 index 0000000..163a60a --- /dev/null +++ b/node_modules/.bin/mime @@ -0,0 +1 @@ +../mime/bin/cli.js \ No newline at end of file diff --git a/node_modules/@polka/url/build.js b/node_modules/@polka/url/build.js new file mode 100644 index 0000000..33dfc56 --- /dev/null +++ b/node_modules/@polka/url/build.js @@ -0,0 +1,42 @@ +const qs = require('querystring'); + +/** + * @typedef ParsedURL + * @type {import('.').ParsedURL} + */ + +/** + * @typedef Request + * @property {string} url + * @property {ParsedURL} _parsedUrl + */ + +/** + * @param {Request} req + * @returns {ParsedURL|void} + */ +function parse(req) { + let raw = req.url; + if (raw == null) return; + + let prev = req._parsedUrl; + if (prev && prev.raw === raw) return prev; + + let pathname=raw, search='', query; + + if (raw.length > 1) { + let idx = raw.indexOf('?', 1); + + if (idx !== -1) { + search = raw.substring(idx); + pathname = raw.substring(0, idx); + if (search.length > 1) { + query = qs.parse(search.substring(1)); + } + } + } + + return req._parsedUrl = { pathname, search, query, raw }; +} + +exports.parse = parse; \ No newline at end of file diff --git a/node_modules/@polka/url/build.mjs b/node_modules/@polka/url/build.mjs new file mode 100644 index 0000000..9d5e7b9 --- /dev/null +++ b/node_modules/@polka/url/build.mjs @@ -0,0 +1,40 @@ +import * as qs from 'querystring'; + +/** + * @typedef ParsedURL + * @type {import('.').ParsedURL} + */ + +/** + * @typedef Request + * @property {string} url + * @property {ParsedURL} _parsedUrl + */ + +/** + * @param {Request} req + * @returns {ParsedURL|void} + */ +export function parse(req) { + let raw = req.url; + if (raw == null) return; + + let prev = req._parsedUrl; + if (prev && prev.raw === raw) return prev; + + let pathname=raw, search='', query; + + if (raw.length > 1) { + let idx = raw.indexOf('?', 1); + + if (idx !== -1) { + search = raw.substring(idx); + pathname = raw.substring(0, idx); + if (search.length > 1) { + query = qs.parse(search.substring(1)); + } + } + } + + return req._parsedUrl = { pathname, search, query, raw }; +} diff --git a/node_modules/@polka/url/index.d.ts b/node_modules/@polka/url/index.d.ts new file mode 100644 index 0000000..9b27c04 --- /dev/null +++ b/node_modules/@polka/url/index.d.ts @@ -0,0 +1,10 @@ +import type { IncomingMessage } from 'http'; + +export interface ParsedURL { + pathname: string; + search: string; + query: Record | void; + raw: string; +} + +export function parse(req: IncomingMessage): ParsedURL; diff --git a/node_modules/@polka/url/package.json b/node_modules/@polka/url/package.json new file mode 100644 index 0000000..bd673c1 --- /dev/null +++ b/node_modules/@polka/url/package.json @@ -0,0 +1,30 @@ +{ + "version": "1.0.0-next.25", + "name": "@polka/url", + "repository": "lukeed/polka", + "description": "Super fast, memoized `req.url` parser", + "module": "build.mjs", + "types": "index.d.ts", + "main": "build.js", + "license": "MIT", + "exports": { + ".": { + "types": "./index.d.ts", + "import": "./build.mjs", + "require": "./build.js" + }, + "./package.json": "./package.json" + }, + "files": [ + "build.*", + "index.d.*" + ], + "author": { + "name": "Luke Edwards", + "email": "luke@lukeed.com", + "url": "https://lukeed.com" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/node_modules/@polka/url/readme.md b/node_modules/@polka/url/readme.md new file mode 100644 index 0000000..e47645c --- /dev/null +++ b/node_modules/@polka/url/readme.md @@ -0,0 +1,68 @@ +# @polka/url [![npm](https://badgen.now.sh/npm/v/@polka/url)](https://npmjs.org/package/@polka/url) [![licenses](https://licenses.dev/b/npm/%40polka%2Furl)](https://licenses.dev/npm/%40polka%2Furl) + +> Super fast, memoized `req.url` parser; _not_ limited to [Polka][polka]! + +Parses the `url` from a [`IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) request. The returned object will always only contain the following keys: `search`, `query`, `pathname`, and `raw`. + +> **Note:** This library does not process `protocol`, `hostname`, `port`, etc.
This is because the incoming `req.url` value only begins with the path information. + +Parsed requests will be mutated with a `_parsedUrl` key, containing the returned output. This is used for future memoization, avoiding the need to fully parse the same `url` value multiple times. + +## Install + +``` +$ npm install --save @polka/url +``` + +## Usage + +```js +const parse = require('@polka/url'); + +let req = { + url: '/foo/bar?fizz=buzz' +}; +let output = parse(req); +//=> { +//=> pathname: '/foo/bar', +//=> raw: '/foo/bar?fizz=buzz', +//=> search: '?fizz=buzz', +//=> query: { +//=> fizz: 'buzz' +//=> }, +//=> } + +// Attaches result for future memoization +assert.deepEqual(output, req._parsedUrl); //=> true +``` + +## API + +### url(req) +Returns: `Object` or `undefined` + +> **Important:** The `req` must have a `url` key, otherwise `undefined` will be returned.
If no input is provided at all, a `TypeError` will be thrown. + +#### req +Type: `IncomingMessage` or `{ url: string }` + +The incoming HTTP request (`req`) or a plain `Object` with a `url` key. + +> **Note:** In Node.js servers, the [`req.url`](https://nodejs.org/api/http.html#http_message_url) begins with a pathname & does not include a `hash`. + + +## Benchmarks + +Check out the [`bench`](/bench) directory for in-depth benchmark results and comparisons. + + +## Support + +Any issues or questions can be sent to the [Polka][polka] repository.
However, please specify that your inquiry is about `@polka/url` specifically. + + +## License + +MIT © [Luke Edwards](https://lukeed.com) + +[polka]: https://github.com/lukeed/polka diff --git a/node_modules/@tinyhttp/accepts/LICENSE b/node_modules/@tinyhttp/accepts/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/accepts/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/accepts/README.md b/node_modules/@tinyhttp/accepts/README.md new file mode 100644 index 0000000..21c9818 --- /dev/null +++ b/node_modules/@tinyhttp/accepts/README.md @@ -0,0 +1,117 @@ +# @tinyhttp/accepts + +> [`accepts`](https://github.com/jshttp/accepts) rewrite in TypeScript. + +Higher level content negotiation based on +[negotiator](https://www.npmjs.com/package/negotiator). Extracted from +[koa](https://www.npmjs.com/package/koa) for general use. + +In addition to negotiator, it allows: + +- Allows types as an array or arguments list, ie + `(['text/html', 'application/json'])` as well as + `('text/html', 'application/json')`. +- Allows type shorthands such as `json`. +- Returns `false` when no types match +- Treats non-existent headers as `*` + +## Install + +```sh +pnpm i @tinyhttp/accepts +``` + +## API + +```ts +import { Accepts } from '@tinyhttp/accepts' +``` + +### accepts(req) + +Create a new `Accepts` object for the given `req`. + +#### `.charset(charsets)` + +Return the first accepted charset. If nothing in `charsets` is accepted, then +`false` is returned. + +#### `.charsets()` + +Return the charsets that the request accepts, in the order of the client's +preference (most preferred first). + +#### `.encoding(encodings)` + +Return the first accepted encoding. If nothing in `encodings` is accepted, then +`false` is returned. + +#### `.encodings()` + +Return the encodings that the request accepts, in the order of the client's +preference (most preferred first). + +#### `.language(languages)` + +Return the first accepted language. If nothing in `languages` is accepted, then +`false` is returned. + +#### `.languages()` + +Return the languages that the request accepts, in the order of the client's +preference (most preferred first). + +#### `.type(types)` + +Return the first accepted type (and it is returned as the same text as what +appears in the `types` array). If nothing in `types` is accepted, then `false` +is returned. + +The `types` array can contain full MIME types or file extensions. Any value that +is not a full MIME types is passed to `require('mime-types').lookup`. + +#### `.types()` + +Return the types that the request accepts, in the order of the client's +preference (most preferred first). + +## Example + +This simple example shows how to use `accepts` to return a different typed +respond body based on what the client wants to accept. The server lists it's +preferences in order and will get back the best match between the client and +server. + +```ts +import Accepts from '@tinyhttp/accepts' +import { createServer } from 'node:http' + +createServer((req, res) => { + const accept = new Accepts(req) + + // the order of this list is significant; should be server preferred order + switch (accept.type(['json', 'html'])) { + case 'json': + res.setHeader('Content-Type', 'application/json') + res.write('{"hello":"world!"}') + break + case 'html': + res.setHeader('Content-Type', 'text/html') + res.write('hello, world!') + break + default: + // the fallback is text/plain, so no need to specify it above + res.setHeader('Content-Type', 'text/plain') + res.write('hello, world!') + break + } + + res.end() +}).listen(3000) +``` + +You can test this out with the cURL program: + +```sh +curl -I -H 'Accept: text/html' http://localhost:3000/ +``` diff --git a/node_modules/@tinyhttp/accepts/dist/index.d.ts b/node_modules/@tinyhttp/accepts/dist/index.d.ts new file mode 100644 index 0000000..9759b94 --- /dev/null +++ b/node_modules/@tinyhttp/accepts/dist/index.d.ts @@ -0,0 +1,49 @@ +/// +import Negotiator from 'negotiator'; +import { IncomingMessage as I, IncomingHttpHeaders } from 'node:http'; +export declare class Accepts { + headers: IncomingHttpHeaders; + negotiator: Negotiator; + constructor(req: Pick); + /** + * Check if the given `type(s)` is acceptable, returning the best match when true, otherwise `false`, in which case you should respond with 406 "Not Acceptable". + * + * The `type` value may be a single mime type string such as "application/json", the extension name such as "json" or an array `["json", "html", "text/plain"]`. When a list or array is given the _best_ match, if any is returned. When no types are given as arguments, returns all types accepted by the client in the preference order. + */ + types(types: string | string[], ...args: string[]): string[] | string | false; + get type(): (types: string | string[], ...args: string[]) => string[] | string | false; + /** + * Return accepted encodings or best fit based on `encodings`. + * + * Given `Accept-Encoding: gzip, deflate` + * an array sorted by quality is returned: + * + * ['gzip', 'deflate'] + */ + encodings(encodings: string | string[], ...args: string[]): string | string[] | boolean; + get encoding(): (encodings: string | string[], ...args: string[]) => string | string[] | boolean; + /** + * Return accepted charsets or best fit based on `charsets`. + * + * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5` + * an array sorted by quality is returned: + * + * ['utf-8', 'utf-7', 'iso-8859-1'] + */ + charsets(charsets?: string | string[], ...args: string[]): string | string[] | boolean; + get charset(): (charsets: string | string[], ...args: string[]) => string | string[] | boolean; + /** + * Return accepted languages or best fit based on `langs`. + * + * Given `Accept-Language: en;q=0.8, es, pt` + * an array sorted by quality is returned: + * + * ['es', 'pt', 'en'] + * + */ + languages(languages: string | string[], ...args: string[]): string | string[] | boolean; + get lang(): (languages: string | string[], ...args: string[]) => string | string[] | boolean; + get langs(): (languages: string | string[], ...args: string[]) => string | string[] | boolean; + get language(): (languages: string | string[], ...args: string[]) => string | string[] | boolean; +} +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/accepts/dist/index.d.ts.map b/node_modules/@tinyhttp/accepts/dist/index.d.ts.map new file mode 100644 index 0000000..87156eb --- /dev/null +++ b/node_modules/@tinyhttp/accepts/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AACnC,OAAO,EAAE,eAAe,IAAI,CAAC,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAOrE,qBAAa,OAAO;IAClB,OAAO,EAAE,mBAAmB,CAAA;IAC5B,UAAU,EAAE,UAAU,CAAA;gBACV,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC;IAInC;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,KAAK;IA0B7E,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,GAAG,MAAM,GAAG,KAAK,CAErF;IACD;;;;;;;OAOG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO;IAevF,IAAI,QAAQ,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAE/F;IACD;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO;IAetF,IAAI,OAAO,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAE7F;IACD;;;;;;;;OAQG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO;IAevF,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAE3F;IACD,IAAI,KAAK,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAE5F;IACD,IAAI,QAAQ,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAE/F;CACF"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/accepts/dist/index.js b/node_modules/@tinyhttp/accepts/dist/index.js new file mode 100644 index 0000000..91d082a --- /dev/null +++ b/node_modules/@tinyhttp/accepts/dist/index.js @@ -0,0 +1,110 @@ +import Negotiator from "negotiator"; +import mime from "mime"; +const extToMime = (type) => type.indexOf("/") == -1 ? mime.getType(type) : type; +const validMime = (type) => typeof type == "string"; +class Accepts { + constructor(req) { + this.headers = req.headers; + this.negotiator = new Negotiator(req); + } + /** + * Check if the given `type(s)` is acceptable, returning the best match when true, otherwise `false`, in which case you should respond with 406 "Not Acceptable". + * + * The `type` value may be a single mime type string such as "application/json", the extension name such as "json" or an array `["json", "html", "text/plain"]`. When a list or array is given the _best_ match, if any is returned. When no types are given as arguments, returns all types accepted by the client in the preference order. + */ + types(types, ...args) { + let mimeTypes = []; + if (types && !Array.isArray(types)) { + mimeTypes = [types, ...args]; + } else if (types) { + mimeTypes = [...types, ...args]; + } + if (!mimeTypes || mimeTypes.length == 0) { + return this.negotiator.mediaTypes(); + } + if (!this.headers["accept"]) { + return mimeTypes[0]; + } + const mimes = mimeTypes.map(extToMime); + const accepts = this.negotiator.mediaTypes(mimes.filter(validMime)); + const [first] = accepts; + return first ? mimeTypes[mimes.indexOf(first)] : false; + } + get type() { + return this.types; + } + /** + * Return accepted encodings or best fit based on `encodings`. + * + * Given `Accept-Encoding: gzip, deflate` + * an array sorted by quality is returned: + * + * ['gzip', 'deflate'] + */ + encodings(encodings, ...args) { + let _encodings = encodings; + if (_encodings && !Array.isArray(_encodings)) { + _encodings = [_encodings, ...args]; + } + if (!_encodings || _encodings.length == 0) { + return this.negotiator.encodings(); + } + return this.negotiator.encodings(_encodings)[0] || false; + } + get encoding() { + return this.encodings; + } + /** + * Return accepted charsets or best fit based on `charsets`. + * + * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5` + * an array sorted by quality is returned: + * + * ['utf-8', 'utf-7', 'iso-8859-1'] + */ + charsets(charsets, ...args) { + let _charsets = charsets; + if (_charsets && !Array.isArray(_charsets)) { + _charsets = [_charsets, ...args]; + } + if (!_charsets || _charsets.length == 0) { + return this.negotiator.charsets(); + } + return this.negotiator.charsets(_charsets)[0] || false; + } + get charset() { + return this.charsets; + } + /** + * Return accepted languages or best fit based on `langs`. + * + * Given `Accept-Language: en;q=0.8, es, pt` + * an array sorted by quality is returned: + * + * ['es', 'pt', 'en'] + * + */ + languages(languages, ...args) { + let _languages = languages; + if (_languages && !Array.isArray(_languages)) { + _languages = [_languages, ...args]; + } + if (!_languages || _languages.length == 0) { + return this.negotiator.languages(); + } + return this.negotiator.languages(_languages)[0] || false; + } + get lang() { + return this.languages; + } + get langs() { + return this.languages; + } + get language() { + return this.languages; + } +} +export { + Accepts +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/accepts/dist/index.js.map b/node_modules/@tinyhttp/accepts/dist/index.js.map new file mode 100644 index 0000000..e39a1c1 --- /dev/null +++ b/node_modules/@tinyhttp/accepts/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import Negotiator from 'negotiator'\nimport { IncomingMessage as I, IncomingHttpHeaders } from 'node:http'\nimport mime from 'mime'\n\nconst extToMime = (type: string) => (type.indexOf('/') == -1 ? mime.getType(type) : type)\n\nconst validMime = (type: unknown): boolean => typeof type == 'string'\n\nexport class Accepts {\n headers: IncomingHttpHeaders\n negotiator: Negotiator\n constructor(req: Pick) {\n this.headers = req.headers\n this.negotiator = new Negotiator(req)\n }\n /**\n * Check if the given `type(s)` is acceptable, returning the best match when true, otherwise `false`, in which case you should respond with 406 \"Not Acceptable\".\n *\n * The `type` value may be a single mime type string such as \"application/json\", the extension name such as \"json\" or an array `[\"json\", \"html\", \"text/plain\"]`. When a list or array is given the _best_ match, if any is returned. When no types are given as arguments, returns all types accepted by the client in the preference order.\n */\n types(types: string | string[], ...args: string[]): string[] | string | false {\n let mimeTypes: string[] = []\n\n // support flattened arguments\n if (types && !Array.isArray(types)) {\n mimeTypes = [types, ...args]\n } else if (types) {\n mimeTypes = [...types, ...args]\n }\n\n // no types, return all requested types\n if (!mimeTypes || mimeTypes.length == 0) {\n return this.negotiator.mediaTypes()\n }\n\n // no accept header, return first given type\n if (!this.headers['accept']) {\n return mimeTypes[0]\n }\n\n const mimes = mimeTypes.map(extToMime)\n const accepts = this.negotiator.mediaTypes(mimes.filter(validMime) as string[])\n const [first] = accepts\n\n return first ? mimeTypes[mimes.indexOf(first)] : false\n }\n get type(): (types: string | string[], ...args: string[]) => string[] | string | false {\n return this.types\n }\n /**\n * Return accepted encodings or best fit based on `encodings`.\n *\n * Given `Accept-Encoding: gzip, deflate`\n * an array sorted by quality is returned:\n *\n * ['gzip', 'deflate']\n */\n encodings(encodings: string | string[], ...args: string[]): string | string[] | boolean {\n let _encodings: string[] = encodings as string[]\n\n // support flattened arguments\n if (_encodings && !Array.isArray(_encodings)) {\n _encodings = [_encodings, ...args]\n }\n\n // no encodings, return all requested encodings\n if (!_encodings || _encodings.length == 0) {\n return this.negotiator.encodings()\n }\n\n return this.negotiator.encodings(_encodings)[0] || false\n }\n get encoding(): (encodings: string | string[], ...args: string[]) => string | string[] | boolean {\n return this.encodings\n }\n /**\n * Return accepted charsets or best fit based on `charsets`.\n *\n * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`\n * an array sorted by quality is returned:\n *\n * ['utf-8', 'utf-7', 'iso-8859-1']\n */\n charsets(charsets?: string | string[], ...args: string[]): string | string[] | boolean {\n let _charsets: string[] = charsets as string[]\n\n // support flattened arguments\n if (_charsets && !Array.isArray(_charsets)) {\n _charsets = [_charsets, ...args]\n }\n\n // no charsets, return all requested charsets\n if (!_charsets || _charsets.length == 0) {\n return this.negotiator.charsets()\n }\n\n return this.negotiator.charsets(_charsets)[0] || false\n }\n get charset(): (charsets: string | string[], ...args: string[]) => string | string[] | boolean {\n return this.charsets\n }\n /**\n * Return accepted languages or best fit based on `langs`.\n *\n * Given `Accept-Language: en;q=0.8, es, pt`\n * an array sorted by quality is returned:\n *\n * ['es', 'pt', 'en']\n *\n */\n languages(languages: string | string[], ...args: string[]): string | string[] | boolean {\n let _languages: string[] = languages as string[]\n\n // support flattened arguments\n if (_languages && !Array.isArray(_languages)) {\n _languages = [_languages, ...args]\n }\n\n // no languages, return all requested languages\n if (!_languages || _languages.length == 0) {\n return this.negotiator.languages()\n }\n\n return this.negotiator.languages(_languages)[0] || false\n }\n get lang(): (languages: string | string[], ...args: string[]) => string | string[] | boolean {\n return this.languages\n }\n get langs(): (languages: string | string[], ...args: string[]) => string | string[] | boolean {\n return this.languages\n }\n get language(): (languages: string | string[], ...args: string[]) => string | string[] | boolean {\n return this.languages\n }\n}\n"],"names":[],"mappings":";;AAIA,MAAM,YAAY,CAAC,SAAkB,KAAK,QAAQ,GAAG,KAAK,KAAK,KAAK,QAAQ,IAAI,IAAI;AAEpF,MAAM,YAAY,CAAC,SAA2B,OAAO,QAAQ;AAEtD,MAAM,QAAQ;AAAA,EAGnB,YAAY,KAAyB;AACnC,SAAK,UAAU,IAAI;AACd,SAAA,aAAa,IAAI,WAAW,GAAG;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAA6B,MAA2C;AAC5E,QAAI,YAAsB,CAAA;AAG1B,QAAI,SAAS,CAAC,MAAM,QAAQ,KAAK,GAAG;AACtB,kBAAA,CAAC,OAAO,GAAG,IAAI;AAAA,eAClB,OAAO;AAChB,kBAAY,CAAC,GAAG,OAAO,GAAG,IAAI;AAAA,IAChC;AAGA,QAAI,CAAC,aAAa,UAAU,UAAU,GAAG;AAChC,aAAA,KAAK,WAAW;IACzB;AAGA,QAAI,CAAC,KAAK,QAAQ,QAAQ,GAAG;AAC3B,aAAO,UAAU,CAAC;AAAA,IACpB;AAEM,UAAA,QAAQ,UAAU,IAAI,SAAS;AACrC,UAAM,UAAU,KAAK,WAAW,WAAW,MAAM,OAAO,SAAS,CAAa;AACxE,UAAA,CAAC,KAAK,IAAI;AAEhB,WAAO,QAAQ,UAAU,MAAM,QAAQ,KAAK,CAAC,IAAI;AAAA,EACnD;AAAA,EACA,IAAI,OAAmF;AACrF,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,UAAU,cAAiC,MAA6C;AACtF,QAAI,aAAuB;AAG3B,QAAI,cAAc,CAAC,MAAM,QAAQ,UAAU,GAAG;AAC/B,mBAAA,CAAC,YAAY,GAAG,IAAI;AAAA,IACnC;AAGA,QAAI,CAAC,cAAc,WAAW,UAAU,GAAG;AAClC,aAAA,KAAK,WAAW;IACzB;AAEA,WAAO,KAAK,WAAW,UAAU,UAAU,EAAE,CAAC,KAAK;AAAA,EACrD;AAAA,EACA,IAAI,WAA6F;AAC/F,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,SAAS,aAAiC,MAA6C;AACrF,QAAI,YAAsB;AAG1B,QAAI,aAAa,CAAC,MAAM,QAAQ,SAAS,GAAG;AAC9B,kBAAA,CAAC,WAAW,GAAG,IAAI;AAAA,IACjC;AAGA,QAAI,CAAC,aAAa,UAAU,UAAU,GAAG;AAChC,aAAA,KAAK,WAAW;IACzB;AAEA,WAAO,KAAK,WAAW,SAAS,SAAS,EAAE,CAAC,KAAK;AAAA,EACnD;AAAA,EACA,IAAI,UAA2F;AAC7F,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,UAAU,cAAiC,MAA6C;AACtF,QAAI,aAAuB;AAG3B,QAAI,cAAc,CAAC,MAAM,QAAQ,UAAU,GAAG;AAC/B,mBAAA,CAAC,YAAY,GAAG,IAAI;AAAA,IACnC;AAGA,QAAI,CAAC,cAAc,WAAW,UAAU,GAAG;AAClC,aAAA,KAAK,WAAW;IACzB;AAEA,WAAO,KAAK,WAAW,UAAU,UAAU,EAAE,CAAC,KAAK;AAAA,EACrD;AAAA,EACA,IAAI,OAAyF;AAC3F,WAAO,KAAK;AAAA,EACd;AAAA,EACA,IAAI,QAA0F;AAC5F,WAAO,KAAK;AAAA,EACd;AAAA,EACA,IAAI,WAA6F;AAC/F,WAAO,KAAK;AAAA,EACd;AACF;"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/accepts/package.json b/node_modules/@tinyhttp/accepts/package.json new file mode 100644 index 0000000..89f98f5 --- /dev/null +++ b/node_modules/@tinyhttp/accepts/package.json @@ -0,0 +1,36 @@ +{ + "name": "@tinyhttp/accepts", + "description": "accepts rewrite in TypeScript", + "version": "2.2.1", + "license": "MIT", + "homepage": "https://tinyhttp.v1rtl.site", + "funding": { + "type": "individual", + "url": "https://github.com/tinyhttp/tinyhttp?sponsor=1" + }, + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/cookie-signature" + }, + "engines": { + "node": ">=12.20.0" + }, + "type": "module", + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "files": [ + "dist" + ], + "devDependencies": { + "@types/negotiator": "^0.6.3" + }, + "dependencies": { + "mime": "4.0.1", + "negotiator": "^0.6.3" + }, + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/LICENSE b/node_modules/@tinyhttp/app/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/app/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/app/README.md b/node_modules/@tinyhttp/app/README.md new file mode 100644 index 0000000..361e1ad --- /dev/null +++ b/node_modules/@tinyhttp/app/README.md @@ -0,0 +1,25 @@ +# @tinyhttp/app + +The core of tinyhttp. Contains the `App`, `Request` and `Response`. Additionally, it provides special tinyhttp-specific types. + +## Install + +```sh +pnpm i @tinyhttp/app +``` + +## Example + +```ts +import { App } from '@tinyhttp/app' +import type { Request, Response, NextFunction } from '@tinyhttp/app' + +new App() + .use((req: Request, res: Response, next: NextFunction) => { + console.log('Did a request') + next() + }) + .get('/', (_, res) => res.send('

Hello World

')) + .get('/page/:page', (req, res) => res.send(`You opened ${req.params.page}`)) + .listen(3000) +``` diff --git a/node_modules/@tinyhttp/app/dist/app.d.ts b/node_modules/@tinyhttp/app/dist/app.d.ts new file mode 100644 index 0000000..6be93bf --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/app.d.ts @@ -0,0 +1,106 @@ +/// +import { Server } from 'node:http'; +import type { Request } from './request.js'; +import type { Response } from './response.js'; +import type { ErrorHandler } from './onError.js'; +import type { Middleware, Handler, NextFunction, UseMethodParams } from '@tinyhttp/router'; +import { Router } from '@tinyhttp/router'; +import { AppConstructor, AppRenderOptions, AppSettings, TemplateEngine } from './types.js'; +import { TemplateEngineOptions } from './index.js'; +/** + * `App` class - the starting point of tinyhttp app. + * + * With the `App` you can: + * * use routing methods and `.use(...)` + * * set no match (404) and error (500) handlers + * * configure template engines + * * store data in locals + * * listen the http server on a specified port + * + * In case you use TypeScript, you can pass custom types to this class because it is also a generic class. + * + * Example: + * + * ```ts + * interface CoolReq extends Request { + * genericsAreDope: boolean + * } + * + * const app = App() + * ``` + */ +export declare class App extends Router { + #private; + middleware: Middleware[]; + locals: Record; + noMatchHandler: Handler; + onError: ErrorHandler; + settings: AppSettings; + engines: Record; + applyExtensions: (req: Request, res: Response, next: NextFunction) => void; + attach: (req: Req, res: Res) => void; + cache: Record; + constructor(options?: AppConstructor); + /** + * Set app setting + * @param setting setting name + * @param value setting value + */ + set(setting: K, value: AppSettings[K]): this; + /** + * Enable app setting + * @param setting Setting name + */ + enable(setting: K): this; + /** + * Check if setting is enabled + * @param setting Setting name + * @returns + */ + enabled(setting: K): boolean; + /** + * Disable app setting + * @param setting Setting name + */ + disable(setting: K): this; + /** + * Return the app's absolute pathname + * based on the parent(s) that have + * mounted it. + * + * For example if the application was + * mounted as `"/admin"`, which itself + * was mounted as `"/blog"` then the + * return value would be `"/blog/admin"`. + * + */ + path(): string; + /** + * Register a template engine with extension + */ + engine(ext: string, fn: TemplateEngine): this; + /** + * Render a template + * @param file What to render + * @param data data that is passed to a template + * @param options Template engine options + * @param cb Callback that consumes error and html + */ + render(name: string, data: Record, options: AppRenderOptions, cb: (err: unknown, html?: unknown) => void): void; + use(...args: UseMethodParams): this; + route(path: string): App; + /** + * Extends Req / Res objects, pushes 404 and 500 handlers, dispatches middleware + * @param req Req object + * @param res Res object + */ + handler(req: Req, res: Res, next?: NextFunction): void; + /** + * Creates HTTP server and dispatches middleware + * @param port server listening port + * @param Server callback after server starts listening + * @param host server listening host + */ + listen(port?: number, cb?: () => void, host?: string): Server; +} +//# sourceMappingURL=app.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/app.d.ts.map b/node_modules/@tinyhttp/app/dist/app.d.ts.map new file mode 100644 index 0000000..1392d2e --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/app.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/extend.d.ts b/node_modules/@tinyhttp/app/dist/extend.d.ts new file mode 100644 index 0000000..38fcd03 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/extend.d.ts @@ -0,0 +1,10 @@ +import { Request } from './request.js'; +import type { NextFunction } from '@tinyhttp/router'; +import type { Response } from './response.js'; +import { App } from './app.js'; +import { TemplateEngineOptions } from './types.js'; +/** + * Extends Request and Response objects with custom properties and methods + */ +export declare const extendMiddleware: (app: App) => (req: Request, res: Response, next: NextFunction) => void; +//# sourceMappingURL=extend.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/extend.d.ts.map b/node_modules/@tinyhttp/app/dist/extend.d.ts.map new file mode 100644 index 0000000..16d36d9 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/extend.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"extend.d.ts","sourceRoot":"","sources":["../src/extend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,OAAO,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAkC7C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAElD;;GAEG;AACH,eAAO,MAAM,gBAAgB,6EACgD,GAAG,WACxE,OAAO,sCAAsC,YAAY,KAAG,IAsDjE,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/index.d.ts b/node_modules/@tinyhttp/app/dist/index.d.ts new file mode 100644 index 0000000..8110d36 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/index.d.ts @@ -0,0 +1,15 @@ +export { App } from './app.js'; +export * from './request.js'; +export * from './response.js'; +export { extendMiddleware } from './extend.js'; +export { onErrorHandler, type ErrorHandler } from './onError.js'; +export { View } from './view.js'; +export type { AppSettings, TemplateEngineOptions, TemplateEngine, AppConstructor } from './types.js'; +import type { Request } from './request.js'; +import type { Response } from './response.js'; +import type { NextFunction, Handler as RHandler, AsyncHandler as RAsyncHandler, SyncHandler as RSyncHandler, Middleware } from '@tinyhttp/router'; +export type Handler = RHandler; +export type AsyncHandler = RAsyncHandler; +export type SyncHandler = RSyncHandler; +export type { NextFunction, Middleware, Request, Response }; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/index.d.ts.map b/node_modules/@tinyhttp/app/dist/index.d.ts.map new file mode 100644 index 0000000..7088148 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEpG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EACV,YAAY,EACZ,OAAO,IAAI,QAAQ,EACnB,YAAY,IAAI,aAAa,EAC7B,WAAW,IAAI,YAAY,EAC3B,UAAU,EACX,MAAM,kBAAkB,CAAA;AAEzB,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;AACjD,MAAM,MAAM,YAAY,GAAG,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;AAC3D,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;AACzD,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/index.js b/node_modules/@tinyhttp/app/dist/index.js new file mode 100644 index 0000000..71e9914 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/index.js @@ -0,0 +1,464 @@ +import { STATUS_CODES, createServer } from "node:http"; +import { proxyaddr, all, compile } from "@tinyhttp/proxy-addr"; +import { isIP } from "node:net"; +import { getRequestHeader, getQueryParams, getRangeFromHeader, getAccepts, getAcceptsCharsets, getAcceptsEncodings, getAcceptsLanguages, checkIfXMLHttpRequest, getFreshOrStale, getPathname, getURLParams } from "@tinyhttp/req"; +import { getURLParams as getURLParams2 } from "@tinyhttp/req"; +import { Router, pushMiddleware } from "@tinyhttp/router"; +import { getResponseHeader, setHeader, send, json, status, sendStatus, sendFile, setContentType, setLocationHeader, setLinksHeader, setVaryHeader, setCookie, clearCookie, formatResponse, redirect, attachment, download, append } from "@tinyhttp/res"; +import { parse } from "regexparam"; +import { extname, resolve, dirname, basename, join } from "node:path"; +import { statSync } from "node:fs"; +const trustRemoteAddress = ({ socket }) => { + const val = socket.remoteAddress; + if (typeof val === "string") + return compile(val.split(",").map((x) => x.trim())); + return compile(val || []); +}; +const getProtocol = (req) => { + const proto = `http${req.secure ? "s" : ""}`; + if (!trustRemoteAddress(req)) + return proto; + const header = req.headers["X-Forwarded-Proto"] || proto; + const index = header.indexOf(","); + return index !== -1 ? header.substring(0, index).trim() : header.trim(); +}; +const getHostname = (req) => { + let host = req.get("X-Forwarded-Host"); + if (!host || !trustRemoteAddress(req)) + host = req.get("Host"); + if (!host) + return; + const index = host.indexOf(":", host[0] === "[" ? host.indexOf("]") + 1 : 0); + return index !== -1 ? host.substring(0, index) : host; +}; +const getIP = (req) => proxyaddr(req, trustRemoteAddress(req)).replace(/^.*:/, ""); +const getIPs = (req) => all(req, trustRemoteAddress(req)); +const getSubdomains = (req, subdomainOffset = 2) => { + const hostname = getHostname(req); + if (!hostname) + return []; + const subdomains = isIP(hostname) ? [hostname] : hostname.split(".").reverse(); + return subdomains.slice(subdomainOffset); +}; +const onErrorHandler = function(err, _req, res) { + if (this.onError === onErrorHandler && this.parent) + return this.parent.onError(err, _req, res); + if (err instanceof Error) + console.error(err); + const code = err.code in STATUS_CODES ? err.code : err.status; + if (typeof err === "string" || Buffer.isBuffer(err)) + res.writeHead(500).end(err); + else if (code in STATUS_CODES) + res.writeHead(code).end(STATUS_CODES[code]); + else + res.writeHead(500).end(err.message); +}; +const renderTemplate = (_req, res, app) => (file, data, options) => { + app.render(file, data ? { ...res.locals, ...data } : res.locals, options, (err, html) => { + if (err) + throw err; + res.send(html); + }); + return res; +}; +const extendMiddleware = (app) => (req, res, next) => { + const { settings } = app; + res.get = getResponseHeader(res); + req.get = getRequestHeader(req); + if (settings == null ? void 0 : settings.bindAppToReqRes) { + req.app = app; + res.app = app; + } + if (settings == null ? void 0 : settings.networkExtensions) { + req.protocol = getProtocol(req); + req.secure = req.protocol === "https"; + req.hostname = getHostname(req); + req.subdomains = getSubdomains(req, settings.subdomainOffset); + req.ip = getIP(req); + req.ips = getIPs(req); + } + req.query = getQueryParams(req.url); + req.range = getRangeFromHeader(req); + req.accepts = getAccepts(req); + req.acceptsCharsets = getAcceptsCharsets(req); + req.acceptsEncodings = getAcceptsEncodings(req); + req.acceptsLanguages = getAcceptsLanguages(req); + req.xhr = checkIfXMLHttpRequest(req); + res.header = res.set = setHeader(res); + res.send = send(req, res); + res.json = json(res); + res.status = status(res); + res.sendStatus = sendStatus(req, res); + res.sendFile = sendFile(req, res); + res.type = setContentType(res); + res.location = setLocationHeader(req, res); + res.links = setLinksHeader(res); + res.vary = setVaryHeader(res); + res.cookie = setCookie(req, res); + res.clearCookie = clearCookie(req, res); + res.render = renderTemplate(req, res, app); + res.format = formatResponse(req, res, next); + res.redirect = redirect(req, res, next); + res.attachment = attachment(res); + res.download = download(req, res); + res.append = append(res); + res.locals = res.locals || /* @__PURE__ */ Object.create(null); + Object.defineProperty(req, "fresh", { get: getFreshOrStale.bind(null, req, res), configurable: true }); + req.stale = !req.fresh; + next(); +}; +function tryStat(path) { + try { + return statSync(path); + } catch (e) { + return void 0; + } +} +class View { + constructor(name, opts = {}) { + this.ext = extname(name); + this.name = name; + this.root = opts.root; + this.defaultEngine = opts.defaultEngine; + if (!this.ext && !this.defaultEngine) + throw new Error("No default engine was specified and no extension was provided."); + let fileName = name; + if (!this.ext) { + this.ext = this.defaultEngine[0] !== "." ? "." + this.defaultEngine : this.defaultEngine; + fileName += this.ext; + } + if (!opts.engines[this.ext]) + throw new Error(`No engine was found for ${this.ext}`); + this.engine = opts.engines[this.ext]; + this.path = this.#lookup(fileName); + } + #lookup(name) { + let path; + const roots = [].concat(this.root); + for (let i = 0; i < roots.length && !path; i++) { + const root = roots[i]; + const loc = resolve(root, name); + const dir = dirname(loc); + const file = basename(loc); + path = this.#resolve(dir, file); + } + return path; + } + #resolve(dir, file) { + const ext = this.ext; + let path = join(dir, file); + let stat = tryStat(path); + if (stat && stat.isFile()) { + return path; + } + path = join(dir, basename(file, ext), "index" + ext); + stat = tryStat(path); + if (stat && stat.isFile()) { + return path; + } + } + render(options, data, cb) { + this.engine(this.path, data, options, cb); + } +} +const lead = (x) => x.charCodeAt(0) === 47 ? x : "/" + x; +const mount = (fn) => fn instanceof App ? fn.attach : fn; +const applyHandler = (h) => async (req, res, next) => { + try { + if (h[Symbol.toStringTag] === "AsyncFunction") { + await h(req, res, next); + } else + h(req, res, next); + } catch (e) { + next(e); + } +}; +class App extends Router { + constructor(options = {}) { + super(); + this.middleware = []; + this.locals = {}; + this.engines = {}; + this.onError = (options == null ? void 0 : options.onError) || onErrorHandler; + this.noMatchHandler = (options == null ? void 0 : options.noMatchHandler) || this.onError.bind(this, { code: 404 }); + this.settings = { + view: View, + xPoweredBy: true, + views: `${process.cwd()}/views`, + "view cache": process.env.NODE_ENV === "production", + ...options.settings + }; + this.applyExtensions = options == null ? void 0 : options.applyExtensions; + this.attach = (req, res) => setImmediate(this.handler.bind(this, req, res, void 0), req, res); + this.cache = {}; + } + /** + * Set app setting + * @param setting setting name + * @param value setting value + */ + set(setting, value) { + this.settings[setting] = value; + return this; + } + /** + * Enable app setting + * @param setting Setting name + */ + enable(setting) { + this.settings[setting] = true; + return this; + } + /** + * Check if setting is enabled + * @param setting Setting name + * @returns + */ + enabled(setting) { + return Boolean(this.settings[setting]); + } + /** + * Disable app setting + * @param setting Setting name + */ + disable(setting) { + this.settings[setting] = false; + return this; + } + /** + * Return the app's absolute pathname + * based on the parent(s) that have + * mounted it. + * + * For example if the application was + * mounted as `"/admin"`, which itself + * was mounted as `"/blog"` then the + * return value would be `"/blog/admin"`. + * + */ + path() { + return this.parent ? this.parent.path() + this.mountpath : ""; + } + /** + * Register a template engine with extension + */ + engine(ext, fn) { + this.engines[ext[0] === "." ? ext : `.${ext}`] = fn; + return this; + } + /** + * Render a template + * @param file What to render + * @param data data that is passed to a template + * @param options Template engine options + * @param cb Callback that consumes error and html + */ + render(name, data = {}, options = {}, cb) { + let view; + const { _locals, ...opts } = options; + let locals = this.locals; + if (_locals) + locals = { ...locals, ..._locals }; + locals = { ...locals, ...data }; + if (opts.cache == null) + opts.cache = this.enabled("view cache"); + if (opts.cache) { + view = this.cache[name]; + } + if (!view) { + const View2 = this.settings["view"]; + view = new View2(name, { + defaultEngine: this.settings["view engine"], + root: this.settings.views, + engines: this.engines + }); + if (!view.path) { + const dirs = Array.isArray(view.root) && view.root.length > 1 ? 'directories "' + view.root.slice(0, -1).join('", "') + '" or "' + view.root[view.root.length - 1] + '"' : 'directory "' + view.root + '"'; + const err = new Error('Failed to lookup view "' + name + '" in views ' + dirs); + return cb(err); + } + if (opts.cache) { + this.cache[name] = view; + } + } + try { + view.render(opts, locals, cb); + } catch (err) { + cb(err); + } + } + use(...args) { + const base = args[0]; + const fns = args.slice(1).flat(); + let pathArray = []; + if (typeof base === "function" || base instanceof App) { + fns.unshift(base); + } else { + let basePaths = []; + if (Array.isArray(base)) + basePaths = [...base]; + else if (typeof base === "string") + basePaths = [base]; + basePaths = basePaths.filter((element) => { + if (typeof element === "string") { + pathArray.push(element); + return false; + } + return true; + }); + fns.unshift(...basePaths); + } + pathArray = pathArray.length ? pathArray.map((path) => lead(path)) : ["/"]; + const mountpath = pathArray.join(", "); + let regex; + for (const fn of fns) { + if (fn instanceof App) { + pathArray.forEach((path) => { + regex = parse(path, true); + fn.mountpath = mountpath; + this.apps[path] = fn; + fn.parent = this; + }); + } + } + pathArray.forEach((path) => { + var _a; + const handlerPaths = []; + const handlerFunctions = []; + const handlerPathBase = path === "/" ? "" : lead(path); + for (const fn of fns) { + if (fn instanceof App && ((_a = fn.middleware) == null ? void 0 : _a.length)) { + for (const mw of fn.middleware) { + handlerPaths.push(handlerPathBase + lead(mw.path)); + handlerFunctions.push(fn); + } + } else { + handlerPaths.push(""); + handlerFunctions.push(fn); + } + } + pushMiddleware(this.middleware)({ + path, + regex, + type: "mw", + handler: mount(handlerFunctions[0]), + handlers: handlerFunctions.slice(1).map(mount), + fullPaths: handlerPaths + }); + }); + return this; + } + route(path) { + const app = new App({ settings: this.settings }); + this.use(path, app); + return app; + } + #find(url) { + return this.middleware.filter((m) => { + m.regex = m.regex || parse(m.path, m.type === "mw"); + let fullPathRegex; + m.fullPath && typeof m.fullPath === "string" ? fullPathRegex = parse(m.fullPath, m.type === "mw") : fullPathRegex = null; + return m.regex.pattern.test(url) && (m.type === "mw" && fullPathRegex ? fullPathRegex.pattern.test(url) : true); + }); + } + /** + * Extends Req / Res objects, pushes 404 and 500 handlers, dispatches middleware + * @param req Req object + * @param res Res object + */ + handler(req, res, next) { + const { xPoweredBy } = this.settings; + if (xPoweredBy) + res.setHeader("X-Powered-By", typeof xPoweredBy === "string" ? xPoweredBy : "tinyhttp"); + const exts = this.applyExtensions || extendMiddleware(this); + req.originalUrl = req.url || req.originalUrl; + const pathname = getPathname(req.originalUrl); + const matched = this.#find(pathname); + const mw = [ + { + handler: exts, + type: "mw", + path: "/" + }, + ...matched.filter((x) => req.method === "HEAD" || (x.method ? x.method === req.method : true)) + ]; + if (matched[0] != null) { + mw.push({ + type: "mw", + handler: (req2, res2, next2) => { + if (req2.method === "HEAD") { + res2.statusCode = 204; + return res2.end(""); + } + next2(); + }, + path: "/" + }); + } + mw.push({ + handler: this.noMatchHandler, + type: "mw", + path: "/" + }); + const handle = (mw2) => async (req2, res2, next2) => { + var _a; + const { path, handler, regex } = mw2; + let params; + try { + params = regex ? getURLParams(regex, pathname) : {}; + } catch (e) { + console.error(e); + if (e instanceof URIError) + return res2.sendStatus(400); + else + throw e; + } + let prefix = path; + if (regex) { + for (const key of regex.keys) { + if (key === "wild") { + prefix = prefix.replace("*", params.wild); + } else { + prefix = prefix.replace(`:${key}`, params[key]); + } + } + } + req2.params = { ...req2.params, ...params }; + if (mw2.type === "mw") { + req2.url = lead(req2.originalUrl.substring(prefix.length)); + } + if (!req2.path) + req2.path = getPathname(req2.url); + if ((_a = this.settings) == null ? void 0 : _a.enableReqRoute) + req2.route = mw2; + await applyHandler(handler)(req2, res2, next2); + }; + let idx = 0; + const loop = () => res.writableEnded || idx < mw.length && handle(mw[idx++])(req, res, next); + next = next || ((err) => err ? this.onError(err, req, res) : loop()); + loop(); + } + /** + * Creates HTTP server and dispatches middleware + * @param port server listening port + * @param Server callback after server starts listening + * @param host server listening host + */ + listen(port, cb, host) { + return createServer().on("request", this.attach).listen(port, host, cb); + } +} +export { + App, + View, + extendMiddleware, + getHostname, + getIP, + getIPs, + getProtocol, + getSubdomains, + getURLParams2 as getURLParams, + onErrorHandler, + renderTemplate +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/app/dist/index.js.map b/node_modules/@tinyhttp/app/dist/index.js.map new file mode 100644 index 0000000..42aa6ad --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/request.ts","../src/onError.ts","../src/response.ts","../src/extend.ts","../src/view.ts","../src/app.ts"],"sourcesContent":["import { IncomingMessage } from 'node:http'\nimport type { ParsedUrlQuery } from 'node:querystring'\n\nimport { Options, Ranges } from 'header-range-parser'\nimport { proxyaddr as proxyAddr, all, compile } from '@tinyhttp/proxy-addr'\n\nimport { App } from './app.js'\nimport type { Middleware } from '@tinyhttp/router'\n\nimport type { URLParams } from '@tinyhttp/req'\nimport { isIP } from 'node:net'\nimport type { Socket } from 'node:net'\nimport type { TLSSocket } from 'node:tls'\n\nexport { getURLParams } from '@tinyhttp/req'\n\nconst trustRemoteAddress = ({ socket }: Pick) => {\n const val = socket.remoteAddress\n if (typeof val === 'string') return compile(val.split(',').map((x) => x.trim()))\n return compile(val || [])\n}\n\nexport const getProtocol = (req: Request): Protocol => {\n const proto = `http${req.secure ? 's' : ''}`\n\n if (!trustRemoteAddress(req)) return proto\n\n const header = (req.headers['X-Forwarded-Proto'] as string) || proto\n\n const index = header.indexOf(',')\n\n return index !== -1 ? header.substring(0, index).trim() : header.trim()\n}\n\nexport const getHostname = (req: Request): string | undefined => {\n let host: string = req.get('X-Forwarded-Host') as string\n\n if (!host || !trustRemoteAddress(req)) host = req.get('Host') as string\n\n if (!host) return\n\n // IPv6 literal support\n const index = host.indexOf(':', host[0] === '[' ? host.indexOf(']') + 1 : 0)\n\n return index !== -1 ? host.substring(0, index) : host\n}\n\nexport const getIP = (req: Pick): string | undefined =>\n proxyAddr(req, trustRemoteAddress(req)).replace(/^.*:/, '') // striping the redundant prefix addeded by OS to IPv4 address\n\nexport const getIPs = (req: Pick): string[] | undefined =>\n all(req, trustRemoteAddress(req))\n\nexport const getSubdomains = (req: Request, subdomainOffset = 2): string[] => {\n const hostname = getHostname(req)\n\n if (!hostname) return []\n\n const subdomains = isIP(hostname) ? [hostname] : hostname.split('.').reverse()\n\n return subdomains.slice(subdomainOffset)\n}\n\nexport type Connection = IncomingMessage['socket'] & {\n encrypted: boolean\n}\n\nexport type Protocol = 'http' | 'https' | string\n\nexport type { URLParams }\n\ntype AcceptsReturns = string | boolean | string[]\n\nexport interface Request extends IncomingMessage {\n originalUrl: string\n path: string\n url: string\n query: ParsedUrlQuery\n params: URLParams\n connection: Connection\n socket: TLSSocket | Socket\n route?: Middleware\n protocol: Protocol\n secure: boolean\n xhr: boolean\n hostname?: string\n ip?: string\n ips?: string[]\n subdomains?: string[]\n get: (header: string) => string | string[] | undefined\n range: (size: number, options?: Options) => -1 | -2 | -3 | Ranges | undefined\n accepts: (...types: string[]) => AcceptsReturns\n acceptsEncodings: (...encodings: string[]) => AcceptsReturns\n acceptsCharsets: (...charsets: string[]) => AcceptsReturns\n acceptsLanguages: (...languages: string[]) => AcceptsReturns\n is: (...types: string[]) => boolean\n cookies?: any\n signedCookies?: any\n secret?: string | string[]\n fresh?: boolean\n stale?: boolean\n body?: any\n app?: App\n}\n","import type { NextFunction } from '@tinyhttp/router'\nimport { STATUS_CODES } from 'node:http'\nimport type { Request } from './request.js'\nimport type { Response } from './response.js'\nimport type { App } from './app.js'\n\nexport type ErrorHandler = (this: App, err: any, req: Request, res: Response, next?: NextFunction) => void\n\nexport const onErrorHandler: ErrorHandler = function (this: App, err: any, _req: Request, res: Response) {\n if (this.onError === onErrorHandler && this.parent) return this.parent.onError(err, _req, res)\n\n if (err instanceof Error) console.error(err)\n\n const code = err.code in STATUS_CODES ? err.code : err.status\n\n if (typeof err === 'string' || Buffer.isBuffer(err)) res.writeHead(500).end(err)\n else if (code in STATUS_CODES) res.writeHead(code).end(STATUS_CODES[code])\n else res.writeHead(500).end(err.message)\n}\n","import { ServerResponse } from 'node:http'\nimport type { SerializeOptions } from '@tinyhttp/cookie'\nimport { Request } from './request.js'\nimport { App } from './app.js'\nimport type { ReadStreamOptions, FormatProps, DownloadOptions } from '@tinyhttp/res'\nimport type { AppRenderOptions, TemplateEngineOptions } from './types.js'\n\nexport const renderTemplate =\n (_req: Request, res: Response, app: App) =>\n (file: string, data?: Record, options?: AppRenderOptions): Response => {\n app.render(file, data ? { ...res.locals, ...data } : res.locals, options, (err: unknown, html: unknown) => {\n if (err) throw err\n res.send(html)\n })\n return res\n }\n\nexport interface Response extends ServerResponse {\n header(field: string | Record, val?: string | any[]): Response\n set(field: string | Record, val?: string | any[]): Response\n get(field: string): string | number | string[]\n send(body: B): Response\n sendFile(path: string, options?: ReadStreamOptions, cb?: (err?: unknown) => void): Response\n json(body: B): Response\n status(status: number): Response\n sendStatus(statusCode: number): Response\n cookie(\n name: string,\n value: string | Record,\n options?: SerializeOptions & Partial<{ signed: boolean }>\n ): Response\n clearCookie(name: string, options?: SerializeOptions): Response\n location(url: string): Response\n links(links: { [key: string]: string }): Response\n render(\n file: string,\n data?: Record,\n options?: AppRenderOptions\n ): Response\n vary(field: string): Response\n format(obj: FormatProps): Response\n redirect(url: string, status?: number): Response\n type(type: string): Response\n download(path: string, filename: string, options?: DownloadOptions, cb?: (err?: unknown) => void): Response\n attachment(filename?: string): Response\n app?: App\n locals: Record\n /**\n * Send JSON response with JSONP callback support.\n *\n * To enable this method, install the `@tinyhttp/jsonp` package and attach the method to `res.jsonp` property.\n *\n * @param obj Response object\n */\n jsonp(obj: any): Response\n\n append(field: string, value: any): Response\n}\n","import { getSubdomains, Request } from './request.js'\nimport type { NextFunction } from '@tinyhttp/router'\nimport type { Response } from './response.js'\nimport {\n getFreshOrStale,\n getRangeFromHeader,\n getRequestHeader,\n checkIfXMLHttpRequest,\n getQueryParams,\n getAccepts,\n getAcceptsCharsets,\n getAcceptsEncodings,\n getAcceptsLanguages\n} from '@tinyhttp/req'\nimport { getProtocol, getHostname, getIP, getIPs } from './request.js'\nimport {\n send,\n json,\n status,\n setCookie,\n clearCookie,\n setHeader,\n getResponseHeader,\n setLocationHeader,\n setLinksHeader,\n sendStatus,\n setVaryHeader,\n sendFile,\n formatResponse,\n redirect,\n setContentType,\n attachment,\n download,\n append\n} from '@tinyhttp/res'\nimport { renderTemplate } from './response.js'\nimport { App } from './app.js'\nimport { TemplateEngineOptions } from './types.js'\n\n/**\n * Extends Request and Response objects with custom properties and methods\n */\nexport const extendMiddleware =\n (app: App) =>\n (req: Request, res: Response, next: NextFunction): void => {\n const { settings } = app\n\n res.get = getResponseHeader(res)\n req.get = getRequestHeader(req)\n\n if (settings?.bindAppToReqRes) {\n req.app = app\n res.app = app\n }\n\n if (settings?.networkExtensions) {\n req.protocol = getProtocol(req)\n req.secure = req.protocol === 'https'\n req.hostname = getHostname(req)\n req.subdomains = getSubdomains(req, settings.subdomainOffset)\n req.ip = getIP(req)\n req.ips = getIPs(req)\n }\n\n req.query = getQueryParams(req.url)\n\n req.range = getRangeFromHeader(req)\n req.accepts = getAccepts(req)\n req.acceptsCharsets = getAcceptsCharsets(req)\n req.acceptsEncodings = getAcceptsEncodings(req)\n req.acceptsLanguages = getAcceptsLanguages(req)\n\n req.xhr = checkIfXMLHttpRequest(req)\n\n res.header = res.set = setHeader(res)\n res.send = send(req, res)\n res.json = json(res)\n res.status = status(res)\n res.sendStatus = sendStatus(req, res)\n res.sendFile = sendFile(req, res)\n res.type = setContentType(res)\n res.location = setLocationHeader(req, res)\n res.links = setLinksHeader(res)\n res.vary = setVaryHeader(res)\n res.cookie = setCookie(req, res)\n res.clearCookie = clearCookie(req, res)\n res.render = renderTemplate(req, res, app)\n res.format = formatResponse(req, res, next)\n res.redirect = redirect(req, res, next)\n res.attachment = attachment(res)\n res.download = download(req, res)\n res.append = append(res)\n res.locals = res.locals || Object.create(null)\n\n Object.defineProperty(req, 'fresh', { get: getFreshOrStale.bind(null, req, res), configurable: true })\n req.stale = !req.fresh\n\n next()\n }\n","/*!\n * Ported from https://github.com/expressjs/express/blob/master/lib/view.js\n * express\n * Copyright(c) 2009-2013 TJ Holowaychuk\n * Copyright(c) 2013 Roman Shtylman\n * Copyright(c) 2014-2015 Douglas Christopher Wilson\n * MIT Licensed\n */\n\nimport { extname, resolve, dirname, basename, join } from 'node:path'\nimport { TemplateEngineOptions, TemplateEngine } from './types.js'\nimport { statSync } from 'node:fs'\n\nfunction tryStat(path: string) {\n try {\n return statSync(path)\n } catch (e) {\n return undefined\n }\n}\n\n/**\n * Initialize a new `View` with the given `name`.\n *\n * Options:\n *\n * - `defaultEngine` the default template engine name\n * - `engines` template engine require() cache\n * - `root` root path for view lookup\n *\n * @param name\n * @param options\n * @public\n */\n\nexport class View {\n ext: string\n defaultEngine: string\n name: string\n engine: TemplateEngine\n path: string\n root: string | string[]\n constructor(\n name: string,\n opts: Partial<{\n defaultEngine: string\n root: string | string[]\n engines: Record>\n }> = {}\n ) {\n this.ext = extname(name)\n this.name = name\n this.root = opts.root\n this.defaultEngine = opts.defaultEngine\n\n if (!this.ext && !this.defaultEngine)\n throw new Error('No default engine was specified and no extension was provided.')\n\n let fileName = name\n\n if (!this.ext) {\n // get extension from default engine name\n this.ext = this.defaultEngine[0] !== '.' ? '.' + this.defaultEngine : this.defaultEngine\n\n fileName += this.ext\n }\n\n if (!opts.engines[this.ext]) throw new Error(`No engine was found for ${this.ext}`)\n\n this.engine = opts.engines[this.ext]\n this.path = this.#lookup(fileName)\n }\n #lookup(name: string) {\n let path: string\n const roots = [].concat(this.root)\n\n for (let i = 0; i < roots.length && !path; i++) {\n const root = roots[i]\n // resolve the path\n const loc = resolve(root, name)\n const dir = dirname(loc)\n const file = basename(loc)\n\n // resolve the file\n path = this.#resolve(dir, file)\n }\n\n return path\n }\n #resolve(dir: string, file: string) {\n const ext = this.ext\n\n // .\n let path = join(dir, file)\n let stat = tryStat(path)\n\n if (stat && stat.isFile()) {\n return path\n }\n\n // /index.\n path = join(dir, basename(file, ext), 'index' + ext)\n stat = tryStat(path)\n\n if (stat && stat.isFile()) {\n return path\n }\n }\n render(options: RenderOptions, data: Record, cb: (err: Error | null, html: unknown) => void) {\n this.engine(this.path, data, options, cb)\n }\n}\n","import { createServer, Server } from 'node:http'\nimport { getURLParams } from './request.js'\nimport type { Request, URLParams } from './request.js'\nimport type { Response } from './response.js'\nimport type { ErrorHandler } from './onError.js'\nimport { onErrorHandler } from './onError.js'\nimport type { Middleware, Handler, NextFunction, UseMethodParams } from '@tinyhttp/router'\nimport { Router, pushMiddleware } from '@tinyhttp/router'\nimport { extendMiddleware } from './extend.js'\nimport { parse as rg } from 'regexparam'\nimport { getPathname } from '@tinyhttp/req'\nimport { AppConstructor, AppRenderOptions, AppSettings, TemplateEngine } from './types.js'\nimport { TemplateEngineOptions } from './index.js'\nimport { View } from './view.js'\n\n/**\n * Add leading slash if not present (e.g. path -> /path, /path -> /path)\n * @param x\n */\nconst lead = (x: string) => (x.charCodeAt(0) === 47 ? x : '/' + x)\n\nconst mount = (fn: App | Handler) => (fn instanceof App ? fn.attach : fn)\n\nconst applyHandler =\n (h: Handler) =>\n async (req: Req, res: Res, next?: NextFunction) => {\n try {\n if (h[Symbol.toStringTag] === 'AsyncFunction') {\n await h(req, res, next)\n } else h(req, res, next)\n } catch (e) {\n next(e)\n }\n }\n\n/**\n * `App` class - the starting point of tinyhttp app.\n *\n * With the `App` you can:\n * * use routing methods and `.use(...)`\n * * set no match (404) and error (500) handlers\n * * configure template engines\n * * store data in locals\n * * listen the http server on a specified port\n *\n * In case you use TypeScript, you can pass custom types to this class because it is also a generic class.\n *\n * Example:\n *\n * ```ts\n * interface CoolReq extends Request {\n * genericsAreDope: boolean\n * }\n *\n * const app = App()\n * ```\n */\nexport class App extends Router {\n middleware: Middleware[] = []\n locals: Record = {}\n noMatchHandler: Handler\n onError: ErrorHandler\n settings: AppSettings\n engines: Record = {}\n applyExtensions: (req: Request, res: Response, next: NextFunction) => void\n attach: (req: Req, res: Res) => void\n cache: Record\n\n constructor(options: AppConstructor = {}) {\n super()\n this.onError = options?.onError || onErrorHandler\n this.noMatchHandler = options?.noMatchHandler || this.onError.bind(this, { code: 404 })\n this.settings = {\n view: View,\n xPoweredBy: true,\n views: `${process.cwd()}/views`,\n 'view cache': process.env.NODE_ENV === 'production',\n ...options.settings\n }\n this.applyExtensions = options?.applyExtensions\n this.attach = (req, res) => setImmediate(this.handler.bind(this, req, res, undefined), req, res)\n this.cache = {}\n }\n\n /**\n * Set app setting\n * @param setting setting name\n * @param value setting value\n */\n set(setting: K, value: AppSettings[K]): this {\n this.settings[setting] = value\n\n return this\n }\n\n /**\n * Enable app setting\n * @param setting Setting name\n */\n enable(setting: K): this {\n this.settings[setting] = true as AppSettings[K]\n\n return this\n }\n\n /**\n * Check if setting is enabled\n * @param setting Setting name\n * @returns\n */\n enabled(setting: K): boolean {\n return Boolean(this.settings[setting])\n }\n\n /**\n * Disable app setting\n * @param setting Setting name\n */\n disable(setting: K): this {\n this.settings[setting] = false as AppSettings[K]\n\n return this\n }\n\n /**\n * Return the app's absolute pathname\n * based on the parent(s) that have\n * mounted it.\n *\n * For example if the application was\n * mounted as `\"/admin\"`, which itself\n * was mounted as `\"/blog\"` then the\n * return value would be `\"/blog/admin\"`.\n *\n */\n path(): string {\n return this.parent ? this.parent.path() + this.mountpath : ''\n }\n\n /**\n * Register a template engine with extension\n */\n engine(\n ext: string,\n fn: TemplateEngine\n ): this {\n this.engines[ext[0] === '.' ? ext : `.${ext}`] = fn\n\n return this\n }\n\n /**\n * Render a template\n * @param file What to render\n * @param data data that is passed to a template\n * @param options Template engine options\n * @param cb Callback that consumes error and html\n */\n render(\n name: string,\n data: Record = {},\n options: AppRenderOptions = {} as AppRenderOptions,\n cb: (err: unknown, html?: unknown) => void\n ): void {\n let view: View | undefined\n\n const { _locals, ...opts } = options\n\n let locals = this.locals\n\n if (_locals) locals = { ...locals, ..._locals }\n\n locals = { ...locals, ...data }\n\n if (opts.cache == null) (opts.cache as boolean) = this.enabled('view cache')\n\n if (opts.cache) {\n view = this.cache[name] as View\n }\n\n if (!view) {\n const View = this.settings['view']\n view = new View(name, {\n defaultEngine: this.settings['view engine'],\n root: this.settings.views,\n engines: this.engines\n })\n\n if (!view.path) {\n const dirs =\n Array.isArray(view.root) && view.root.length > 1\n ? 'directories \"' + view.root.slice(0, -1).join('\", \"') + '\" or \"' + view.root[view.root.length - 1] + '\"'\n : 'directory \"' + view.root + '\"'\n const err = new Error('Failed to lookup view \"' + name + '\" in views ' + dirs)\n\n return cb(err)\n }\n\n if (opts.cache) {\n this.cache[name] = view\n }\n }\n\n try {\n view.render(opts, locals, cb)\n } catch (err) {\n cb(err)\n }\n }\n use(...args: UseMethodParams): this {\n const base = args[0]\n\n const fns = args.slice(1).flat()\n\n let pathArray = []\n if (typeof base === 'function' || base instanceof App) {\n fns.unshift(base)\n } else {\n // if base is not an array of paths, then convert it to an array.\n let basePaths = []\n if (Array.isArray(base)) basePaths = [...base]\n else if (typeof base === 'string') basePaths = [base]\n\n basePaths = basePaths.filter((element) => {\n if (typeof element === 'string') {\n pathArray.push(element)\n return false\n }\n return true\n })\n fns.unshift(...basePaths)\n }\n pathArray = pathArray.length ? pathArray.map((path) => lead(path)) : ['/']\n\n const mountpath = pathArray.join(', ')\n let regex: { keys: string[]; pattern: RegExp }\n\n for (const fn of fns) {\n if (fn instanceof App) {\n pathArray.forEach((path) => {\n regex = rg(path, true)\n fn.mountpath = mountpath\n this.apps[path] = fn\n fn.parent = this\n })\n }\n }\n pathArray.forEach((path) => {\n const handlerPaths = []\n const handlerFunctions = []\n const handlerPathBase = path === '/' ? '' : lead(path)\n for (const fn of fns) {\n if (fn instanceof App && fn.middleware?.length) {\n for (const mw of fn.middleware) {\n handlerPaths.push(handlerPathBase + lead(mw.path))\n handlerFunctions.push(fn)\n }\n } else {\n handlerPaths.push('')\n handlerFunctions.push(fn)\n }\n }\n pushMiddleware(this.middleware)({\n path,\n regex,\n type: 'mw',\n handler: mount(handlerFunctions[0] as Handler),\n handlers: handlerFunctions.slice(1).map(mount),\n fullPaths: handlerPaths\n })\n })\n return this\n }\n\n route(path: string): App {\n const app = new App({ settings: this.settings })\n\n this.use(path, app)\n\n return app\n }\n\n #find(url: string): Middleware[] {\n return this.middleware.filter((m) => {\n m.regex = m.regex || rg(m.path, m.type === 'mw')\n\n let fullPathRegex: { keys: string[]; pattern: RegExp }\n\n m.fullPath && typeof m.fullPath === 'string'\n ? (fullPathRegex = rg(m.fullPath, m.type === 'mw'))\n : (fullPathRegex = null)\n\n return m.regex.pattern.test(url) && (m.type === 'mw' && fullPathRegex ? fullPathRegex.pattern.test(url) : true)\n })\n }\n\n /**\n * Extends Req / Res objects, pushes 404 and 500 handlers, dispatches middleware\n * @param req Req object\n * @param res Res object\n */\n handler(\n req: Req,\n res: Res,\n next?: NextFunction\n ): void {\n /* Set X-Powered-By header */\n const { xPoweredBy } = this.settings\n if (xPoweredBy) res.setHeader('X-Powered-By', typeof xPoweredBy === 'string' ? xPoweredBy : 'tinyhttp')\n\n const exts = this.applyExtensions || extendMiddleware(this)\n\n req.originalUrl = req.url || req.originalUrl\n\n const pathname = getPathname(req.originalUrl)\n\n const matched = this.#find(pathname)\n\n const mw: Middleware[] = [\n {\n handler: exts,\n type: 'mw',\n path: '/'\n },\n ...matched.filter((x) => req.method === 'HEAD' || (x.method ? x.method === req.method : true))\n ]\n\n if (matched[0] != null) {\n mw.push({\n type: 'mw',\n handler: (req, res, next) => {\n if (req.method === 'HEAD') {\n res.statusCode = 204\n return res.end('')\n }\n next()\n },\n path: '/'\n })\n }\n\n mw.push({\n handler: this.noMatchHandler,\n type: 'mw',\n path: '/'\n })\n\n const handle = (mw: Middleware) => async (req: Req, res: Res, next?: NextFunction) => {\n const { path, handler, regex } = mw\n\n let params: URLParams\n\n try {\n params = regex ? getURLParams(regex, pathname) : {}\n } catch (e) {\n console.error(e)\n if (e instanceof URIError) return res.sendStatus(400) // Handle malformed URI\n else throw e\n }\n\n // Warning: users should not use :wild as a pattern\n let prefix = path\n if (regex) {\n for (const key of regex.keys) {\n if (key === 'wild') {\n prefix = prefix.replace('*', params.wild)\n } else {\n prefix = prefix.replace(`:${key}`, params[key])\n }\n }\n }\n\n req.params = { ...req.params, ...params }\n\n if (mw.type === 'mw') {\n req.url = lead(req.originalUrl.substring(prefix.length))\n }\n\n if (!req.path) req.path = getPathname(req.url)\n\n if (this.settings?.enableReqRoute) req.route = mw\n\n await applyHandler(handler as unknown as Handler)(req, res, next)\n }\n\n let idx = 0\n\n const loop = () => res.writableEnded || (idx < mw.length && handle(mw[idx++])(req, res, next))\n\n next = next || ((err) => (err ? this.onError(err, req, res) : loop()))\n\n loop()\n }\n\n /**\n * Creates HTTP server and dispatches middleware\n * @param port server listening port\n * @param Server callback after server starts listening\n * @param host server listening host\n */\n listen(port?: number, cb?: () => void, host?: string): Server {\n return createServer().on('request', this.attach).listen(port, host, cb)\n }\n}\n"],"names":["proxyAddr","View","rg","req","res","next","mw"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/onError.d.ts b/node_modules/@tinyhttp/app/dist/onError.d.ts new file mode 100644 index 0000000..660cfc9 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/onError.d.ts @@ -0,0 +1,7 @@ +import type { NextFunction } from '@tinyhttp/router'; +import type { Request } from './request.js'; +import type { Response } from './response.js'; +import type { App } from './app.js'; +export type ErrorHandler = (this: App, err: any, req: Request, res: Response, next?: NextFunction) => void; +export declare const onErrorHandler: ErrorHandler; +//# sourceMappingURL=onError.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/onError.d.ts.map b/node_modules/@tinyhttp/app/dist/onError.d.ts.map new file mode 100644 index 0000000..52025d3 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/onError.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"onError.d.ts","sourceRoot":"","sources":["../src/onError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAEnC,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,YAAY,KAAK,IAAI,CAAA;AAE1G,eAAO,MAAM,cAAc,EAAE,YAU5B,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/request.d.ts b/node_modules/@tinyhttp/app/dist/request.d.ts new file mode 100644 index 0000000..3edd7d7 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/request.d.ts @@ -0,0 +1,56 @@ +/// +/// +/// +/// +import { IncomingMessage } from 'node:http'; +import type { ParsedUrlQuery } from 'node:querystring'; +import { Options, Ranges } from 'header-range-parser'; +import { App } from './app.js'; +import type { Middleware } from '@tinyhttp/router'; +import type { URLParams } from '@tinyhttp/req'; +import type { Socket } from 'node:net'; +import type { TLSSocket } from 'node:tls'; +export { getURLParams } from '@tinyhttp/req'; +export declare const getProtocol: (req: Request) => Protocol; +export declare const getHostname: (req: Request) => string | undefined; +export declare const getIP: (req: Pick) => string | undefined; +export declare const getIPs: (req: Pick) => string[] | undefined; +export declare const getSubdomains: (req: Request, subdomainOffset?: number) => string[]; +export type Connection = IncomingMessage['socket'] & { + encrypted: boolean; +}; +export type Protocol = 'http' | 'https' | string; +export type { URLParams }; +type AcceptsReturns = string | boolean | string[]; +export interface Request extends IncomingMessage { + originalUrl: string; + path: string; + url: string; + query: ParsedUrlQuery; + params: URLParams; + connection: Connection; + socket: TLSSocket | Socket; + route?: Middleware; + protocol: Protocol; + secure: boolean; + xhr: boolean; + hostname?: string; + ip?: string; + ips?: string[]; + subdomains?: string[]; + get: (header: string) => string | string[] | undefined; + range: (size: number, options?: Options) => -1 | -2 | -3 | Ranges | undefined; + accepts: (...types: string[]) => AcceptsReturns; + acceptsEncodings: (...encodings: string[]) => AcceptsReturns; + acceptsCharsets: (...charsets: string[]) => AcceptsReturns; + acceptsLanguages: (...languages: string[]) => AcceptsReturns; + is: (...types: string[]) => boolean; + cookies?: any; + signedCookies?: any; + secret?: string | string[]; + fresh?: boolean; + stale?: boolean; + body?: any; + app?: App; +} +//# sourceMappingURL=request.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/request.d.ts.map b/node_modules/@tinyhttp/app/dist/request.d.ts.map new file mode 100644 index 0000000..309959f --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/request.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/response.d.ts b/node_modules/@tinyhttp/app/dist/response.d.ts new file mode 100644 index 0000000..7a1a5a5 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/response.d.ts @@ -0,0 +1,45 @@ +/// +import { ServerResponse } from 'node:http'; +import type { SerializeOptions } from '@tinyhttp/cookie'; +import { Request } from './request.js'; +import { App } from './app.js'; +import type { ReadStreamOptions, FormatProps, DownloadOptions } from '@tinyhttp/res'; +import type { AppRenderOptions, TemplateEngineOptions } from './types.js'; +export declare const renderTemplate: (_req: Request, res: Response, app: App) => (file: string, data?: Record, options?: AppRenderOptions) => Response; +export interface Response extends ServerResponse { + header(field: string | Record, val?: string | any[]): Response; + set(field: string | Record, val?: string | any[]): Response; + get(field: string): string | number | string[]; + send(body: B): Response; + sendFile(path: string, options?: ReadStreamOptions, cb?: (err?: unknown) => void): Response; + json(body: B): Response; + status(status: number): Response; + sendStatus(statusCode: number): Response; + cookie(name: string, value: string | Record, options?: SerializeOptions & Partial<{ + signed: boolean; + }>): Response; + clearCookie(name: string, options?: SerializeOptions): Response; + location(url: string): Response; + links(links: { + [key: string]: string; + }): Response; + render(file: string, data?: Record, options?: AppRenderOptions): Response; + vary(field: string): Response; + format(obj: FormatProps): Response; + redirect(url: string, status?: number): Response; + type(type: string): Response; + download(path: string, filename: string, options?: DownloadOptions, cb?: (err?: unknown) => void): Response; + attachment(filename?: string): Response; + app?: App; + locals: Record; + /** + * Send JSON response with JSONP callback support. + * + * To enable this method, install the `@tinyhttp/jsonp` package and attach the method to `res.jsonp` property. + * + * @param obj Response object + */ + jsonp(obj: any): Response; + append(field: string, value: any): Response; +} +//# sourceMappingURL=response.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/response.d.ts.map b/node_modules/@tinyhttp/app/dist/response.d.ts.map new file mode 100644 index 0000000..27345cf --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/response.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/types.d.ts b/node_modules/@tinyhttp/app/dist/types.d.ts new file mode 100644 index 0000000..4be740d --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/types.d.ts @@ -0,0 +1,39 @@ +import type { Handler, NextFunction } from '@tinyhttp/router'; +import type { ErrorHandler } from './onError.js'; +import type { Request } from './request.js'; +import type { Response } from './response.js'; +import type { View } from './view.js'; +/** + * tinyhttp App has a few settings for toggling features + */ +export type AppSettings = Partial<{ + networkExtensions: boolean; + subdomainOffset: number; + bindAppToReqRes: boolean; + xPoweredBy: string | boolean; + enableReqRoute: boolean; + views: string | string[]; + view: typeof View; + 'view cache': boolean; + 'view engine': string; +}>; +export type TemplateEngineOptions = { + [key: string]: unknown; +}; +/** + * Function that processes the template + */ +export type TemplateEngine = (path: string, locals: Record, opts: AppRenderOptions, cb: (err: Error | null, html: unknown) => void) => void; +export type AppRenderOptions = O & Partial<{ + cache: boolean; + ext: string; + viewsFolder: string; + _locals: Record; +}>; +export type AppConstructor = Partial<{ + noMatchHandler: Handler; + onError: ErrorHandler; + settings: AppSettings; + applyExtensions: (req: Request, res: Response, next: NextFunction) => void; +}>; +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/types.d.ts.map b/node_modules/@tinyhttp/app/dist/types.d.ts.map new file mode 100644 index 0000000..258c289 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAErC;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC;IAChC,iBAAiB,EAAE,OAAO,CAAA;IAC1B,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,OAAO,CAAA;IACxB,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;IAC5B,cAAc,EAAE,OAAO,CAAA;IACvB,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACxB,IAAI,EAAE,OAAO,IAAI,CAAA;IACjB,YAAY,EAAE,OAAO,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;CACtB,CAAC,CAAA;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,qBAAqB,GAAG,qBAAqB,IAAI,CACpF,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,EACzB,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,KAC3C,IAAI,CAAA;AAET,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,qBAAqB,GAAG,qBAAqB,IAAI,CAAC,GACvF,OAAO,CAAC;IACN,KAAK,EAAE,OAAO,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC,CAAC,CAAA;AAEJ,MAAM,MAAM,cAAc,CAAC,GAAG,SAAS,OAAO,GAAG,OAAO,EAAE,GAAG,SAAS,QAAQ,GAAG,QAAQ,IAAI,OAAO,CAAC;IACnG,cAAc,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACjC,OAAO,EAAE,YAAY,CAAA;IACrB,QAAQ,EAAE,WAAW,CAAA;IACrB,eAAe,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;CAC3E,CAAC,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/view.d.ts b/node_modules/@tinyhttp/app/dist/view.d.ts new file mode 100644 index 0000000..37c5312 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/view.d.ts @@ -0,0 +1,38 @@ +/*! + * Ported from https://github.com/expressjs/express/blob/master/lib/view.js + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ +import { TemplateEngineOptions, TemplateEngine } from './types.js'; +/** + * Initialize a new `View` with the given `name`. + * + * Options: + * + * - `defaultEngine` the default template engine name + * - `engines` template engine require() cache + * - `root` root path for view lookup + * + * @param name + * @param options + * @public + */ +export declare class View { + #private; + ext: string; + defaultEngine: string; + name: string; + engine: TemplateEngine; + path: string; + root: string | string[]; + constructor(name: string, opts?: Partial<{ + defaultEngine: string; + root: string | string[]; + engines: Record>; + }>); + render(options: RenderOptions, data: Record, cb: (err: Error | null, html: unknown) => void): void; +} +//# sourceMappingURL=view.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/dist/view.d.ts.map b/node_modules/@tinyhttp/app/dist/view.d.ts.map new file mode 100644 index 0000000..a8b73a6 --- /dev/null +++ b/node_modules/@tinyhttp/app/dist/view.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAWlE;;;;;;;;;;;;GAYG;AAEH,qBAAa,IAAI,CAAC,aAAa,SAAS,qBAAqB,GAAG,qBAAqB;;IACnF,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,EAAE,MAAM,CAAA;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,cAAc,CAAC,aAAa,CAAC,CAAA;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;gBAErB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,OAAO,CAAC;QACZ,aAAa,EAAE,MAAM,CAAA;QACrB,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;QACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC,CAAA;KACvD,CAAM;IA4DT,MAAM,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI;CAG7G"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/app/package.json b/node_modules/@tinyhttp/app/package.json new file mode 100644 index 0000000..21e540a --- /dev/null +++ b/node_modules/@tinyhttp/app/package.json @@ -0,0 +1,47 @@ +{ + "name": "@tinyhttp/app", + "version": "2.2.3", + "description": "0-legacy, tiny & fast web framework as a replacement of Express", + "type": "module", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/app" + }, + "funding": { + "type": "individual", + "url": "https://github.com/tinyhttp/tinyhttp?sponsor=1" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "files": [ + "dist" + ], + "engines": { + "node": ">=14.21.3" + }, + "keywords": [ + "tinyhttp", + "router", + "backend", + "http", + "framework", + "api" + ], + "author": "v1rtl", + "license": "MIT", + "dependencies": { + "header-range-parser": "1.1.3", + "regexparam": "^2.0.1", + "@tinyhttp/cookie": "2.1.0", + "@tinyhttp/res": "2.2.2", + "@tinyhttp/proxy-addr": "2.1.3", + "@tinyhttp/req": "2.2.2", + "@tinyhttp/router": "2.2.2" + }, + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/content-disposition/LICENSE b/node_modules/@tinyhttp/content-disposition/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/content-disposition/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/content-disposition/README.md b/node_modules/@tinyhttp/content-disposition/README.md new file mode 100644 index 0000000..b90b76e --- /dev/null +++ b/node_modules/@tinyhttp/content-disposition/README.md @@ -0,0 +1,107 @@ +# @tinyhttp/content-disposition + +> [`content-disposition`](https://github.com/jshttp/content-disposition) rewrite +> in TypeScript. + +Create and parse HTTP `Content-Disposition` header + +## Install + +```sh +pnpm i @tinyhttp/content-disposition +``` + +## API + +```ts +import { contentDisposition, parse } from '@tinyhttp/content-disposition' +``` + +### `contentDisposition(filename)` + +Create an attachment `Content-Disposition` header value using the given file +name, if supplied. The `filename` is optional and if no file name is desired, +but you want to specify `options`, set `filename` to `undefined`. + +```js +res.setHeader('Content-Disposition', contentDisposition('∫ maths.pdf')) +``` + +**note** HTTP headers are of the ISO-8859-1 character set. If you are writing +this header through a means different from `setHeader` in Node.js, you'll want +to specify the `'binary'` encoding in Node.js. + +#### Options + +`contentDisposition` accepts these properties in the options object. + +##### `fallback` + +If the `filename` option is outside ISO-8859-1, then the file name is actually +stored in a supplemental field for clients that support Unicode file names and a +ISO-8859-1 version of the file name is automatically generated. + +This specifies the ISO-8859-1 file name to override the automatic generation or +disables the generation all together, defaults to `true`. + +- A string will specify the ISO-8859-1 file name to use in place of automatic + generation. +- `false` will disable including a ISO-8859-1 file name and only include the + Unicode version (unless the file name is already ISO-8859-1). +- `true` will enable automatic generation if the file name is outside + ISO-8859-1. + +If the `filename` option is ISO-8859-1 and this option is specified and has a +different value, then the `filename` option is encoded in the extended field and +this set as the fallback field, even though they are both ISO-8859-1. + +##### `type` + +Specifies the disposition type, defaults to `"attachment"`. This can also be +`"inline"`, or any other value (all values except inline are treated like +`attachment`, but can convey additional information if both parties agree to +it). The type is normalized to lower-case. + +### `contentDisposition.parse(string)` + +```js +contentDisposition.parse('attachment; filename="EURO rates.txt"; filename*=UTF-8\'\'%e2%82%ac%20rates.txt') +``` + +Parse a `Content-Disposition` header string. This automatically handles extended +("Unicode") parameters by decoding them and providing them under the standard +parameter name. This will return an object with the following properties +(examples are shown for the string +`'attachment; filename="EURO rates.txt"; filename*=UTF-8\'\'%e2%82%ac%20rates.txt'`): + +- `type`: The disposition type (always lower case). Example: `'attachment'` + +- `parameters`: An object of the parameters in the disposition (name of + parameter always lower case and extended versions replace non-extended + versions). Example: `{filename: "€ rates.txt"}` + +## Example + +This simple example shows how to use `accepts` to return a different typed +respond body based on what the client wants to accept. The server lists it's +preferences in order and will get back the best match between the client and +server. + +```ts +import { contentDisposition } from '@tinyhttp/content-disposition' +import destroy from 'destroy' +import fs from 'node:fs' +import { createServer } from 'node:http' +import onFinished from 'on-finished' + +const filePath = '/path/to/public/plans.pdf' + +createServer((req, res) => { + res.setHeader('Content-Type', 'application/pdf') + res.setHeader('Content-Disposition', contentDisposition(filePath)) + + const stream = fs.createReadStream(filePath) + stream.pipe(res) + onFinished(res, () => destroy(stream)) +}) +``` diff --git a/node_modules/@tinyhttp/content-disposition/dist/index.d.ts b/node_modules/@tinyhttp/content-disposition/dist/index.d.ts new file mode 100644 index 0000000..7efdf3f --- /dev/null +++ b/node_modules/@tinyhttp/content-disposition/dist/index.d.ts @@ -0,0 +1,20 @@ +export declare class ContentDisposition { + type: string; + parameters: Record; + constructor(type: string, parameters: Record); +} +/** + * Create an attachment Content-Disposition header. + * + * @param filename file name + * @param options + */ +export declare function contentDisposition(filename?: string, options?: Partial<{ + type: string; + fallback: string | boolean; +}>): string; +/** + * Parse Content-Disposition header string. + * @param header string + */ +export declare function parse(header: string): ContentDisposition; diff --git a/node_modules/@tinyhttp/content-disposition/dist/index.js b/node_modules/@tinyhttp/content-disposition/dist/index.js new file mode 100644 index 0000000..2bd788e --- /dev/null +++ b/node_modules/@tinyhttp/content-disposition/dist/index.js @@ -0,0 +1,138 @@ +const ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g; +const HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/; +const HEX_ESCAPE_REPLACE_REGEXP = /%([0-9A-Fa-f]{2})/g; +const NON_LATIN1_REGEXP = /[^\x20-\x7e\xa0-\xff]/g; +const QESC_REGEXP = /\\([\u0000-\u007f])/g; +const QUOTE_REGEXP = /([\\"])/g; +const PARAM_REGEXP = /;[\x09\x20]*([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*=[\x09\x20]*("(?:[\x20!\x23-\x5b\x5d-\x7e\x80-\xff]|\\[\x20-\x7e])*"|[!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*/g; +const TEXT_REGEXP = /^[\x20-\x7e\x80-\xff]+$/; +const TOKEN_REGEXP = /^[!#$%&'*+.0-9A-Z^_`a-z|~-]+$/; +const EXT_VALUE_REGEXP = /^([A-Za-z0-9!#$%&+\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+.^_`|~-])+)$/; +const DISPOSITION_TYPE_REGEXP = /^([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*(?:$|;)/; +const getlatin1 = (val) => { + return String(val).replace(NON_LATIN1_REGEXP, "?"); +}; +class ContentDisposition { + constructor(type, parameters) { + this.type = type; + this.parameters = parameters; + } +} +const qstring = (val) => '"' + String(val).replace(QUOTE_REGEXP, "\\$1") + '"'; +const pencode = (char) => "%" + String(char).charCodeAt(0).toString(16).toUpperCase(); +function ustring(val) { + const str = String(val); + const encoded = encodeURIComponent(str).replace(ENCODE_URL_ATTR_CHAR_REGEXP, pencode); + return "UTF-8''" + encoded; +} +const basename = (str) => str.slice(str.lastIndexOf("/") + 1); +function format({ + parameters, + type +}) { + if (!type || typeof type !== "string" || !TOKEN_REGEXP.test(type)) { + throw new TypeError("invalid type"); + } + let string = String(type).toLowerCase(); + if (parameters && typeof parameters === "object") { + const params = Object.keys(parameters).sort(); + for (const param of params) { + const val = param.slice(-1) === "*" ? ustring(parameters[param]) : qstring(parameters[param]); + string += "; " + param + "=" + val; + } + } + return string; +} +function createParams(filename, fallback) { + if (filename === void 0) + return; + const params = {}; + if (fallback === void 0) + fallback = true; + if (typeof fallback === "string" && NON_LATIN1_REGEXP.test(fallback)) { + throw new TypeError("fallback must be ISO-8859-1 string"); + } + const name = basename(filename); + const isQuotedString = TEXT_REGEXP.test(name); + const fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) : basename(fallback); + const hasFallback = typeof fallbackName === "string" && fallbackName !== name; + if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) { + params["filename*"] = name; + } + if (isQuotedString || hasFallback) { + params.filename = hasFallback ? fallbackName : name; + } + return params; +} +const pdecode = (_str, hex) => String.fromCharCode(parseInt(hex, 16)); +function contentDisposition(filename, options = {}) { + return format(new ContentDisposition(options.type || "attachment", createParams(filename, options.fallback))); +} +function decodefield(str) { + const match = EXT_VALUE_REGEXP.exec(str); + if (!match) + throw new TypeError("invalid extended field value"); + const charset = match[1].toLowerCase(); + const encoded = match[2]; + let value; + switch (charset) { + case "iso-8859-1": + value = getlatin1(encoded.replace(HEX_ESCAPE_REPLACE_REGEXP, pdecode)); + break; + case "utf-8": + try { + value = decodeURIComponent(encoded); + } catch { + throw new TypeError("invalid encoded utf-8"); + } + break; + default: + throw new TypeError("unsupported charset in extended field"); + } + return value; +} +function parse(header) { + let match = DISPOSITION_TYPE_REGEXP.exec(header); + if (!match) + throw new TypeError("invalid type format"); + let index = match[0].length; + const type = match[1].toLowerCase(); + let key; + const names = []; + const params = {}; + let value; + index = PARAM_REGEXP.lastIndex = match[0].slice(-1) === ";" ? index - 1 : index; + while (match = PARAM_REGEXP.exec(header)) { + if (match.index !== index) + throw new TypeError("invalid parameter format"); + index += match[0].length; + key = match[1].toLowerCase(); + value = match[2]; + if (names.indexOf(key) !== -1) { + throw new TypeError("invalid duplicate parameter"); + } + names.push(key); + if (key.indexOf("*") + 1 === key.length) { + key = key.slice(0, -1); + value = decodefield(value); + params[key] = value; + continue; + } + if (typeof params[key] === "string") + continue; + if (value[0] === '"') { + value = value.slice(1, value.length - 1).replace(QESC_REGEXP, "$1"); + } + params[key] = value; + } + if (index !== -1 && index !== header.length) { + throw new TypeError("invalid parameter format"); + } + return new ContentDisposition(type, params); +} +export { + ContentDisposition, + contentDisposition, + parse +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/content-disposition/dist/index.js.map b/node_modules/@tinyhttp/content-disposition/dist/index.js.map new file mode 100644 index 0000000..1037485 --- /dev/null +++ b/node_modules/@tinyhttp/content-disposition/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["// eslint-disable-next-line no-control-regex\nconst ENCODE_URL_ATTR_CHAR_REGEXP = /[\\x00-\\x20\"'()*,/:;<=>?@[\\\\\\]{}\\x7f]/g\n\nconst HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/\nconst HEX_ESCAPE_REPLACE_REGEXP = /%([0-9A-Fa-f]{2})/g\n\nconst NON_LATIN1_REGEXP = /[^\\x20-\\x7e\\xa0-\\xff]/g\n\n// eslint-disable-next-line no-control-regex\nconst QESC_REGEXP = /\\\\([\\u0000-\\u007f])/g\n\nconst QUOTE_REGEXP = /([\\\\\"])/g\n\nconst PARAM_REGEXP =\n /;[\\x09\\x20]*([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\\x09\\x20]*=[\\x09\\x20]*(\"(?:[\\x20!\\x23-\\x5b\\x5d-\\x7e\\x80-\\xff]|\\\\[\\x20-\\x7e])*\"|[!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\\x09\\x20]*/g // eslint-disable-line no-control-regex\nconst TEXT_REGEXP = /^[\\x20-\\x7e\\x80-\\xff]+$/\nconst TOKEN_REGEXP = /^[!#$%&'*+.0-9A-Z^_`a-z|~-]+$/\n\nconst EXT_VALUE_REGEXP =\n /^([A-Za-z0-9!#$%&+\\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+.^_`|~-])+)$/\n\n// eslint-disable-next-line no-control-regex\nconst DISPOSITION_TYPE_REGEXP = /^([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\\x09\\x20]*(?:$|;)/\n\nconst getlatin1 = (val: unknown) => {\n // simple Unicode -> ISO-8859-1 transformation\n return String(val).replace(NON_LATIN1_REGEXP, '?')\n}\n\nexport class ContentDisposition {\n type: string\n parameters: Record\n constructor(type: string, parameters: Record) {\n this.type = type\n this.parameters = parameters\n }\n}\n\nconst qstring = (val: unknown) => '\"' + String(val).replace(QUOTE_REGEXP, '\\\\$1') + '\"'\n\nconst pencode = (char: string) => '%' + String(char).charCodeAt(0).toString(16).toUpperCase()\n\nfunction ustring(val: unknown): string {\n const str = String(val)\n\n // percent encode as UTF-8\n const encoded = encodeURIComponent(str).replace(ENCODE_URL_ATTR_CHAR_REGEXP, pencode)\n\n return \"UTF-8''\" + encoded\n}\n\nconst basename = (str: string) => str.slice(str.lastIndexOf('/') + 1)\n\nfunction format({\n parameters,\n type\n}: Partial<{\n parameters: Record\n type: string | boolean | undefined\n}>) {\n if (!type || typeof type !== 'string' || !TOKEN_REGEXP.test(type)) {\n throw new TypeError('invalid type')\n }\n\n // start with normalized type\n let string = String(type).toLowerCase()\n\n // append parameters\n if (parameters && typeof parameters === 'object') {\n const params = Object.keys(parameters).sort()\n\n for (const param of params) {\n const val = param.slice(-1) === '*' ? ustring(parameters[param]) : qstring(parameters[param])\n\n string += '; ' + param + '=' + val\n }\n }\n\n return string\n}\n\nfunction createParams(filename?: string, fallback?: string | boolean) {\n if (filename === undefined) return\n\n const params: Partial<\n Record & {\n filename: string\n }\n > = {}\n\n // fallback defaults to true\n if (fallback === undefined) fallback = true\n\n if (typeof fallback === 'string' && NON_LATIN1_REGEXP.test(fallback)) {\n throw new TypeError('fallback must be ISO-8859-1 string')\n }\n\n // restrict to file base name\n const name = basename(filename)\n\n // determine if name is suitable for quoted string\n const isQuotedString = TEXT_REGEXP.test(name)\n\n // generate fallback name\n const fallbackName = typeof fallback !== 'string' ? fallback && getlatin1(name) : basename(fallback)\n const hasFallback = typeof fallbackName === 'string' && fallbackName !== name\n\n // set extended filename parameter\n if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) {\n params['filename*'] = name\n }\n\n // set filename parameter\n if (isQuotedString || hasFallback) {\n params.filename = hasFallback ? fallbackName : name\n }\n\n return params\n}\n\nconst pdecode = (_str: string, hex: string) => String.fromCharCode(parseInt(hex, 16))\n\n/**\n * Create an attachment Content-Disposition header.\n *\n * @param filename file name\n * @param options\n */\n\nexport function contentDisposition(\n filename?: string,\n options: Partial<{\n type: string\n fallback: string | boolean\n }> = {}\n): string {\n // format into string\n return format(new ContentDisposition(options.type || 'attachment', createParams(filename, options.fallback)))\n}\n\nfunction decodefield(str: string) {\n const match = EXT_VALUE_REGEXP.exec(str)\n\n if (!match) throw new TypeError('invalid extended field value')\n\n const charset = match[1].toLowerCase()\n const encoded = match[2]\n let value: string\n\n switch (charset) {\n case 'iso-8859-1':\n value = getlatin1(encoded.replace(HEX_ESCAPE_REPLACE_REGEXP, pdecode))\n break\n case 'utf-8':\n try {\n value = decodeURIComponent(encoded)\n } catch {\n throw new TypeError('invalid encoded utf-8')\n }\n break\n default:\n throw new TypeError('unsupported charset in extended field')\n }\n\n return value\n}\n\n/**\n * Parse Content-Disposition header string.\n * @param header string\n */\nexport function parse(header: string): ContentDisposition {\n let match = DISPOSITION_TYPE_REGEXP.exec(header)\n\n if (!match) throw new TypeError('invalid type format')\n\n // normalize type\n let index = match[0].length\n const type = match[1].toLowerCase()\n\n let key: string\n const names = []\n const params = {}\n let value: string | string[]\n\n // calculate index to start at\n index = PARAM_REGEXP.lastIndex = match[0].slice(-1) === ';' ? index - 1 : index\n\n // match parameters\n while ((match = PARAM_REGEXP.exec(header))) {\n if (match.index !== index) throw new TypeError('invalid parameter format')\n\n index += match[0].length\n key = match[1].toLowerCase()\n value = match[2]\n\n if (names.indexOf(key) !== -1) {\n throw new TypeError('invalid duplicate parameter')\n }\n\n names.push(key)\n\n if (key.indexOf('*') + 1 === key.length) {\n // decode extended value\n key = key.slice(0, -1)\n value = decodefield(value)\n\n // overwrite existing value\n params[key] = value\n continue\n }\n\n if (typeof params[key] === 'string') continue\n\n if (value[0] === '\"') {\n value = value.slice(1, value.length - 1).replace(QESC_REGEXP, '$1')\n }\n\n params[key] = value\n }\n\n if (index !== -1 && index !== header.length) {\n throw new TypeError('invalid parameter format')\n }\n\n return new ContentDisposition(type, params)\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/content-disposition/package.json b/node_modules/@tinyhttp/content-disposition/package.json new file mode 100644 index 0000000..899c47c --- /dev/null +++ b/node_modules/@tinyhttp/content-disposition/package.json @@ -0,0 +1,30 @@ +{ + "name": "@tinyhttp/content-disposition", + "description": "content-disposition rewrite in TypeScript", + "version": "2.2.0", + "license": "MIT", + "homepage": "https://tinyhttp.v1rtl.site", + "funding": { + "type": "individual", + "url": "https://github.com/tinyhttp/tinyhttp?sponsor=1" + }, + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/content-disposition" + }, + "engines": { + "node": ">=12.20.0" + }, + "type": "module", + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "files": [ + "dist" + ], + "dependencies": {}, + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/content-type/LICENSE b/node_modules/@tinyhttp/content-type/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/content-type/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/content-type/README.md b/node_modules/@tinyhttp/content-type/README.md new file mode 100644 index 0000000..d68508c --- /dev/null +++ b/node_modules/@tinyhttp/content-type/README.md @@ -0,0 +1,82 @@ +# @tinyhttp/content-type + +[![Version][v-badge-url]][npm-url] [![Downloads][dl-badge-url]][npm-url] [![GitHub Workflow Status][gh-actions-img]][github-actions] [![Codecov][cov-badge-url]][cov-url] + +> [`content-type`](https://github.com/jshttp/content-type) rewrite in TypeScript and ESM. + +Create and parse HTTP Content-Type header according to RFC 7231 + +## Install + +```sh +pnpm i @tinyhttp/content-type +``` + +## API + +```ts +import { parse, format } from '@tinyhttp/content-type' +``` + +### `parse(string: string | Request | Response)` + +```ts +const obj = 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'`): + +- `type`: The media type (the type and subtype, always lower case). + Example: `'image/svg+xml'` + +- `parameters`: An object of the parameters in the media type (name of parameter + always lower case). Example: `{charset: 'utf-8'}` + +Throws a `TypeError` if the string is missing or invalid. + +```ts +const 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. + +```js +const 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. + +### `format(obj)` + +```ts +const 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'`): + +- `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. + +[v-badge-url]: https://img.shields.io/npm/v/@tinyhttp/content-type.svg?style=for-the-badge&color=FF69B4&label=&logo=npm +[npm-url]: https://www.npmjs.com/package/@tinyhttp/content-type +[cov-badge-url]: https://img.shields.io/coveralls/github/tinyhttp/content-type?style=for-the-badge&color=FF69B4 +[cov-url]: https://coveralls.io/github/tinyhttp/@tinyhttp/content-type +[dl-badge-url]: https://img.shields.io/npm/dt/@tinyhttp/content-type?style=for-the-badge&color=FF69B4 +[github-actions]: https://github.com/tinyhttp/content-type/actions +[gh-actions-img]: https://img.shields.io/github/actions/workflow/status/tinyhttp/content-type/ci.yml?branch=master&style=for-the-badge&color=FF69B4&label=&logo=github diff --git a/node_modules/@tinyhttp/content-type/dist/index.d.ts b/node_modules/@tinyhttp/content-type/dist/index.d.ts new file mode 100644 index 0000000..5fea39e --- /dev/null +++ b/node_modules/@tinyhttp/content-type/dist/index.d.ts @@ -0,0 +1,24 @@ +import { IncomingHttpHeaders, ServerResponse } from 'node:http'; + +type Request = { + headers: IncomingHttpHeaders; +}; +type Response = Pick; +/** + * Class to represent a content type. + */ +declare class ContentType { + parameters?: Record; + type: string; + constructor(type: string); +} +/** + * Format object to media type. + */ +declare function format(obj: ContentType): string; +/** + * Parse media type to object. + */ +declare function parse(string: string | Request | Response): ContentType; + +export { format, parse }; diff --git a/node_modules/@tinyhttp/content-type/dist/index.js b/node_modules/@tinyhttp/content-type/dist/index.js new file mode 100644 index 0000000..c38f0fc --- /dev/null +++ b/node_modules/@tinyhttp/content-type/dist/index.js @@ -0,0 +1,89 @@ +// src/index.ts +var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g; +var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/; +var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; +var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g; +var QUOTE_REGEXP = /([\\"])/g; +var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; +function qstring(val) { + const str = String(val); + if (TOKEN_REGEXP.test(str)) + return str; + if (str.length > 0 && !TEXT_REGEXP.test(str)) + throw new TypeError("invalid parameter value"); + return '"' + str.replace(QUOTE_REGEXP, "\\$1") + '"'; +} +function getcontenttype(obj) { + let header; + if ("getHeader" in obj && typeof obj.getHeader === "function") { + header = obj.getHeader("content-type"); + } else if ("headers" in obj && typeof obj.headers === "object") { + const h = obj.headers; + header = h && h["content-type"]; + } + if (typeof header !== "string") { + throw new TypeError("content-type header is missing from object"); + } + return header; +} +var ContentType = class { + parameters; + type; + constructor(type) { + this.parameters = {}; + this.type = type; + } +}; +function format(obj) { + if (!obj || typeof obj !== "object") + throw new TypeError("argument obj is required"); + const { parameters, type } = obj; + if (!type || !TYPE_REGEXP.test(type)) + throw new TypeError("invalid type"); + let string = type; + if (parameters && typeof parameters == "object") { + const params = Object.keys(parameters).sort(); + for (const param of params) { + if (!TOKEN_REGEXP.test(param)) + throw new TypeError("invalid parameter name"); + string += "; " + param + "=" + qstring(parameters[param]); + } + } + return string; +} +function parse(string) { + if (!string) + throw new TypeError("argument string is required"); + const header = typeof string == "object" ? getcontenttype(string) : string; + if (typeof header !== "string") + throw new TypeError("argument string is required to be a string"); + let index = header.indexOf(";"); + const type = index != -1 ? header.slice(0, index).trim() : header.trim(); + if (!TYPE_REGEXP.test(type)) + throw new TypeError("invalid media type"); + const obj = new ContentType(type.toLowerCase()); + if (index != -1) { + let key; + let match; + let value; + PARAM_REGEXP.lastIndex = index; + while (match = PARAM_REGEXP.exec(header)) { + if (match.index !== index) + throw new TypeError("invalid parameter format"); + index += match[0].length; + key = match[1].toLowerCase(); + value = match[2]; + if (value[0] == '"') { + value = value.slice(1, value.length - 1).replace(QESC_REGEXP, "$1"); + } + obj.parameters[key] = value; + } + if (index != header.length) + throw new TypeError("invalid parameter format"); + } + return obj; +} +export { + format, + parse +}; diff --git a/node_modules/@tinyhttp/content-type/package.json b/node_modules/@tinyhttp/content-type/package.json new file mode 100644 index 0000000..a6da4b5 --- /dev/null +++ b/node_modules/@tinyhttp/content-type/package.json @@ -0,0 +1,37 @@ +{ + "name": "@tinyhttp/content-type", + "description": "content-type rewrite in TypeScript and ESM", + "version": "0.1.4", + "repository": "https://github.com/tinyhttp/content-type.git", + "engines": { + "node": ">=12.4" + }, + "files": [ + "dist" + ], + "author": "v1rtl ", + "license": "MIT", + "type": "module", + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "devDependencies": { + "@types/node": "^20.6.4", + "@typescript-eslint/eslint-plugin": "^6.7.2", + "@typescript-eslint/parser": "^6.7.2", + "c8": "^8.0.1", + "eslint": "^8.50.0", + "tsm": "^2.3.0", + "tsup": "^7.2.0", + "typescript": "^5.2.2", + "uvu": "^0.5.6" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "tsup src/index.ts --format esm --dts", + "test": "uvu -r tsm test", + "test:coverage": "c8 --include=src pnpm test", + "test:report": "c8 report --reporter=text-lcov > coverage.lcov" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/cookie-signature/LICENSE b/node_modules/@tinyhttp/cookie-signature/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/cookie-signature/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/cookie-signature/README.md b/node_modules/@tinyhttp/cookie-signature/README.md new file mode 100644 index 0000000..0a50801 --- /dev/null +++ b/node_modules/@tinyhttp/cookie-signature/README.md @@ -0,0 +1,25 @@ +# @tinyhttp/cookie-signature + +[![npm (scoped)](https://img.shields.io/npm/v/@tinyhttp/cookie-signature?style=flat-square)](https://npmjs.com/package/@tinyhttp/cookie-signature) [![npm](https://img.shields.io/npm/dt/@tinyhttp/cookie-signature?style=flat-square)](https://npmjs.com/package/@tinyhttp/cookie-signature) + +HTTP cookie signing and unsigning. A rewrite of [cookie-signature](https://github.com/tj/node-cookie-signature) module. + +## Install + +```sh +pnpm i @tinyhttp/cookie-signature +``` + +## API + +```js +import { sign, unsign } from '@tinyhttp/cookie-signature' +``` + +### `sign(val, secret)` + +Signd the given `val` with `secret`. + +### `unsign(val, secret)` + +Unsign and decode the given `val` with `secret`, returning `false` if the signature is invalid. diff --git a/node_modules/@tinyhttp/cookie-signature/dist/index.d.ts b/node_modules/@tinyhttp/cookie-signature/dist/index.d.ts new file mode 100644 index 0000000..4203dc7 --- /dev/null +++ b/node_modules/@tinyhttp/cookie-signature/dist/index.d.ts @@ -0,0 +1,10 @@ +/** + * Sign the given `val` with `secret`. + */ +export declare const sign: (val: string, secret: string) => string; +/** + * Unsign and decode the given `val` with `secret`, + * returning `false` if the signature is invalid. + */ +export declare const unsign: (val: string, secret: string) => string | false; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/cookie-signature/dist/index.d.ts.map b/node_modules/@tinyhttp/cookie-signature/dist/index.d.ts.map new file mode 100644 index 0000000..0bf5cc6 --- /dev/null +++ b/node_modules/@tinyhttp/cookie-signature/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,IAAI,QAAS,MAAM,UAAU,MAAM,KAAG,MACuC,CAAA;AAE1F;;;GAGG;AACH,eAAO,MAAM,MAAM,QAAS,MAAM,UAAU,MAAM,KAAG,MAAM,GAAG,KAQ7D,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/cookie-signature/dist/index.js b/node_modules/@tinyhttp/cookie-signature/dist/index.js new file mode 100644 index 0000000..cc995c8 --- /dev/null +++ b/node_modules/@tinyhttp/cookie-signature/dist/index.js @@ -0,0 +1,11 @@ +import { createHmac, timingSafeEqual } from "node:crypto"; +const sign = (val, secret) => `${val}.${createHmac("sha256", secret).update(val).digest("base64").replace(/=+$/, "")}`; +const unsign = (val, secret) => { + const str = val.slice(0, val.lastIndexOf(".")), mac = sign(str, secret), macBuffer = Buffer.from(mac), valBuffer = Buffer.alloc(macBuffer.length); + valBuffer.write(val); + return timingSafeEqual(macBuffer, valBuffer) ? str : false; +}; +export { + sign, + unsign +}; diff --git a/node_modules/@tinyhttp/cookie-signature/package.json b/node_modules/@tinyhttp/cookie-signature/package.json new file mode 100644 index 0000000..e76dc1b --- /dev/null +++ b/node_modules/@tinyhttp/cookie-signature/package.json @@ -0,0 +1,36 @@ +{ + "name": "@tinyhttp/cookie-signature", + "version": "2.1.0", + "description": "HTTP cookie signing and unsigning", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/cookie-signature" + }, + "engines": { + "node": ">=12.20.0" + }, + "type": "module", + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "static", + "cookie" + ], + "files": [ + "dist" + ], + "author": "v1rtl", + "license": "MIT", + "dependencies": {}, + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/cookie/LICENSE b/node_modules/@tinyhttp/cookie/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/cookie/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/cookie/README.md b/node_modules/@tinyhttp/cookie/README.md new file mode 100644 index 0000000..7b63823 --- /dev/null +++ b/node_modules/@tinyhttp/cookie/README.md @@ -0,0 +1,176 @@ +# @tinyhttp/cookie + +[![npm (scoped)](https://img.shields.io/npm/v/@tinyhttp/cookie?style=flat-square)](https://npmjs.com/package/@tinyhttp/cookie) [![npm](https://img.shields.io/npm/dt/@tinyhttp/cookie?style=flat-square)](https://npmjs.com/package/@tinyhttp/cookie) + +> A rewrite of [cookie](https://github.com/jshttp/cookie) module. + +HTTP cookie parser and serializer for Node.js. + +## Install + +```sh +pnpm i @tinyhttp/cookie +``` + +## API + +```js +import { parse, serialize } from '@tinyhttp/cookie' +``` + +### `parse(str, options)` + +Parse an HTTP `Cookie` header string and returning an object of all cookie name-value pairs. +The `str` argument is the string representing a `Cookie` header value and `options` is an +optional object containing additional parsing options. + +```js +import { parse } from '@tinyhttp/cookie' + +parse('foo=bar; equation=E%3Dmc%5E2') +// { foo: 'bar', equation: 'E=mc^2' } +``` + +#### Options + +`parse` accepts these properties in the options object. + +##### `decode` + +Specifies a function that will be used to decode a cookie's value. Since the value of a cookie +has a limited character set (and must be a simple string), this function can be used to decode +a previously-encoded cookie value into a JavaScript string or other object. + +The default function is the global `decodeURIComponent`, which will decode any URL-encoded +sequences into their byte representations. + +**note** if an error is thrown from this function, the original, non-decoded cookie value will +be returned as the cookie's value. + +### `serialize(name, value, options)` + +Serialize a cookie name-value pair into a `Set-Cookie` header string. The `name` argument is the +name for the cookie, the `value` argument is the value to set the cookie to, and the `options` +argument is an optional object containing additional serialization options. + +```js +import { serialize } from '@tinyhttp/cookie' + +serialize('foo', 'bar') +// foo=bar +``` + +#### Options + +`serialize` accepts these properties in the options object. + +##### `domain` + +Specifies the value for the [`Domain` `Set-Cookie` attribute][rfc-6265-5.2.3]. By default, no +domain is set, and most clients will consider the cookie to apply to only the current domain. + +##### `encode` + +Specifies a function that will be used to encode a cookie's value. Since value of a cookie +has a limited character set (and must be a simple string), this function can be used to encode +a value into a string suited for a cookie's value. + +The default function is the global `encodeURIComponent`, which will encode a JavaScript string +into UTF-8 byte sequences and then URL-encode any that fall outside of the cookie range. + +##### `expires` + +Specifies the `Date` object to be the value for the [`Expires` `Set-Cookie` attribute][rfc-6265-5.2.1]. +By default, no expiration is set, and most clients will consider this a "non-persistent cookie" and +will delete it on a condition like exiting a web browser application. + +**note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and +`maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this, +so if both are set, they should point to the same date and time. + +##### `httpOnly` + +Specifies the `boolean` value for the [`HttpOnly` `Set-Cookie` attribute][rfc-6265-5.2.6]. When truthy, +the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly` attribute is not set. + +**note** be careful when setting this to `true`, as compliant clients will not allow client-side +JavaScript to see the cookie in `document.cookie`. + +##### `maxAge` + +Specifies the `number` (in seconds) to be the value for the [`Max-Age` `Set-Cookie` attribute][rfc-6265-5.2.2]. +The given number will be converted to an integer by rounding down. By default, no maximum age is set. + +**note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and +`maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this, +so if both are set, they should point to the same date and time. + +##### `path` + +Specifies the value for the [`Path` `Set-Cookie` attribute][rfc-6265-5.2.4]. By default, the path +is considered the ["default path"][rfc-6265-5.1.4]. + +##### `sameSite` + +Specifies the `boolean` or `string` to be the value for the [`SameSite` `Set-Cookie` attribute][rfc-6265bis-03-4.1.2.7]. + +- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement. +- `false` will not set the `SameSite` attribute. +- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement. +- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie. +- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement. + +More information about the different enforcement levels can be found in +[the specification][rfc-6265bis-03-4.1.2.7]. + +**note** This is an attribute that has not yet been fully standardized, and may change in the future. +This also means many clients may ignore this attribute until they understand it. + +##### `secure` + +Specifies the `boolean` value for the [`Secure` `Set-Cookie` attribute][rfc-6265-5.2.5]. When truthy, +the `Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set. + +**note** be careful when setting this to `true`, as compliant clients will not send the cookie back to +the server in the future if the browser does not have an HTTPS connection. + +## Example + +```ts +import { App } from '@tinyhttp/app' +import { parse, serialize } from '@tinyhttp/cookie' +import { escapeHTML } from 'es-escape-html' + +new App() + .use((req, res) => { + if (req.query?.name) { + // Set a new cookie with the name + res.set( + 'Set-Cookie', + serialize('name', String(query.name), { + httpOnly: true, + maxAge: 60 * 60 * 24 * 7 // 1 week + }) + ) + + // Redirect back after setting cookie + res + .status(302) + .set('Location', req.headers.referer || '/') + .end() + } + + const cookie = parse(req.headers.cookie || '') + + const { name } = cookie + + res.set('Content-Type', 'text/html; charset=UTF-8') + + res.write(name ? `

Welcome back, ${escapeHTML(name)}!

` : '

Hello, new visitor!

') + + res.write('
') + res.write('') + res.end('
') + }) + .listen(3000) +``` diff --git a/node_modules/@tinyhttp/cookie/dist/index.d.ts b/node_modules/@tinyhttp/cookie/dist/index.d.ts new file mode 100644 index 0000000..a6cd714 --- /dev/null +++ b/node_modules/@tinyhttp/cookie/dist/index.d.ts @@ -0,0 +1,22 @@ +/** + * Parse a cookie header. + * + * Parse the given cookie header string into an object + * The object has the various cookies as keys(names) => values + * + */ +export declare function parse(str: string, options?: { + decode: (str: string) => string; +}): Record; +export type SerializeOptions = Partial<{ + encode: (str: string) => string; + maxAge: number; + domain: string; + path: string; + httpOnly: boolean; + secure: boolean; + sameSite: boolean | 'Strict' | 'strict' | 'Lax' | 'lax' | 'None' | 'none' | string; + expires: Date; +}>; +export declare function serialize(name: string, val: string, opt?: SerializeOptions): string; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/cookie/dist/index.d.ts.map b/node_modules/@tinyhttp/cookie/dist/index.d.ts.map new file mode 100644 index 0000000..e306817 --- /dev/null +++ b/node_modules/@tinyhttp/cookie/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAqBA;;;;;;GAMG;AACH,wBAAgB,KAAK,CACnB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IACP,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;CAGhC,GACA,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBxB;AAED,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC;IACrC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;IAClF,OAAO,EAAE,IAAI,CAAA;CACd,CAAC,CAAA;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,gBAAqB,GAAG,MAAM,CAyDvF"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/cookie/dist/index.js b/node_modules/@tinyhttp/cookie/dist/index.js new file mode 100644 index 0000000..fab2d3f --- /dev/null +++ b/node_modules/@tinyhttp/cookie/dist/index.js @@ -0,0 +1,81 @@ +const pairSplitRegExp = /; */; +const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/; +function tryDecode(str, decode) { + try { + return decode(str); + } catch (e) { + return str; + } +} +function parse(str, options = { + decode: decodeURIComponent +}) { + const obj = {}; + const pairs = str.split(pairSplitRegExp); + for (const pair of pairs) { + let eqIdx = pair.indexOf("="); + if (eqIdx < 0) + continue; + const key = pair.substr(0, eqIdx).trim(); + let val = pair.substr(++eqIdx, pair.length).trim(); + if ('"' == val[0]) + val = val.slice(1, -1); + if (obj[key] == null) + obj[key] = tryDecode(val, options.decode); + } + return obj; +} +function serialize(name, val, opt = {}) { + if (!opt.encode) + opt.encode = encodeURIComponent; + if (!fieldContentRegExp.test(name)) + throw new TypeError("argument name is invalid"); + const value = opt.encode(val); + if (value && !fieldContentRegExp.test(value)) + throw new TypeError("argument val is invalid"); + let str = name + "=" + value; + if (null != opt.maxAge) { + const maxAge = opt.maxAge - 0; + if (isNaN(maxAge) || !isFinite(maxAge)) + throw new TypeError("option maxAge is invalid"); + str += "; Max-Age=" + Math.floor(maxAge); + } + if (opt.domain) { + if (!fieldContentRegExp.test(opt.domain)) + throw new TypeError("option domain is invalid"); + str += "; Domain=" + opt.domain; + } + if (opt.path) { + if (!fieldContentRegExp.test(opt.path)) + throw new TypeError("option path is invalid"); + str += "; Path=" + opt.path; + } + if (opt.expires) + str += "; Expires=" + opt.expires.toUTCString(); + if (opt.httpOnly) + str += "; HttpOnly"; + if (opt.secure) + str += "; Secure"; + if (opt.sameSite) { + const sameSite = typeof opt.sameSite === "string" ? opt.sameSite.toLowerCase() : opt.sameSite; + switch (sameSite) { + case true: + case "strict": + str += "; SameSite=Strict"; + break; + case "lax": + str += "; SameSite=Lax"; + break; + case "none": + str += "; SameSite=None"; + break; + default: + throw new TypeError("option sameSite is invalid"); + } + } + return str; +} +export { + parse, + serialize +}; diff --git a/node_modules/@tinyhttp/cookie/package.json b/node_modules/@tinyhttp/cookie/package.json new file mode 100644 index 0000000..5807e79 --- /dev/null +++ b/node_modules/@tinyhttp/cookie/package.json @@ -0,0 +1,39 @@ +{ + "name": "@tinyhttp/cookie", + "version": "2.1.0", + "type": "module", + "description": "HTTP cookie parser and serializer for Node.js", + "homepage": "https://github.com/tinyhttp/tinyhttp/tree/master/packages/cookie#readme", + "engines": { + "node": ">=12.20.0" + }, + "funding": { + "type": "individual", + "url": "https://github.com/tinyhttp/tinyhttp?sponsor=1" + }, + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/cookie" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "cookie" + ], + "files": [ + "dist" + ], + "author": "v1rtl", + "license": "MIT", + "dependencies": {}, + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/cors/LICENSE b/node_modules/@tinyhttp/cors/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/cors/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/cors/README.md b/node_modules/@tinyhttp/cors/README.md new file mode 100644 index 0000000..4ef0c03 --- /dev/null +++ b/node_modules/@tinyhttp/cors/README.md @@ -0,0 +1,73 @@ +
+ +# @tinyhttp/cors + +[![npm][npm-img]][npm-url] [![GitHub Workflow Status][gh-actions-img]][github-actions] [![Coverage][cov-img]][cov-url] + +
+ +> A rewrite of [expressjs/cors](https://github.com/expressjs/cors) module. + +HTTP cors header middleware. + +## Install + +```sh +pnpm i @tinyhttp/cors +``` + +## API + +```ts +import { cors } from '@tinyhttp/cors' +``` + +### `cors(options)` + +Returns the CORS middleware with the settings specified in the parameters + +#### Options + +- `origin`: Can be a string defining the `Access-Control-Allow-Origin` value, a boolean which if set to true sets the header to `'*'`, a Regex type, an array (for multiple origins) or a function which contains the request and response as parameters and must return the value for the `Access-Control-Allow-Origin` header +- `methods`: Array of method names which define the `Access-Control-Allow-Methods` header, default to all the most common methods (`GET`, `HEAD`, `PUT`, `PATCH`, `POST`, `DELETE`) +- `allowedHeaders`: Configures the `Access-Control-Allow-Headers` CORS header. Expects an array (ex: [`'Content-Type'`, `'Authorization'`]). +- `exposedHeaders`: Configures the `Access-Control-Expose-Headers` CORS header. If not specified, no custom headers are exposed +- `credentials`: Configures the `Access-Control-Allow-Credentials` CORS header. Set to true to pass the header, otherwise it is omitted. +- `maxAge`: Configures the `Access-Control-Max-Age` CORS header. Set to an integer to pass the header, otherwise it is omitted. +- `optionsSuccessStatus`: Provides a status code to use for successful OPTIONS requests, since some legacy browsers (IE11, various SmartTVs) choke on 204. +- `preflightContinue`: Set 204 and finish response if `true`, call `next` if false. + +The default configuration is: + +```json +{ + "origin": "*", + "methods": ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"], + "optionsSuccessStatus": 204, + "preflightContinue": false +} +``` + +## Example + +```ts +import { App } from '@tinyhttp/app' +import { cors } from '@tinyhttp/cors' + +const app = new App() + +app + .use(cors({ origin: 'https://myfantastic.site/' })) + .options('*', cors()) + .get('/', (req, res) => { + res.send('The headers contained in my response are defined in the cors middleware') + }) + .listen(3000) +``` + +[npm-url]: https://npmjs.com/package/@tinyhttp/cors +[github-actions]: https://github.com/tinyhttp/cors/actions +[gh-actions-img]: https://img.shields.io/github/workflow/status/tinyhttp/cors/CI?style=for-the-badge&logo=github&label=&color=hotpink +[cov-img]: https://img.shields.io/coveralls/github/tinyhttp/cors?style=for-the-badge&color=hotpink +[cov-url]: https://coveralls.io/github/tinyhttp/cors +[npm-img]: https://img.shields.io/npm/dt/@tinyhttp/cors?style=for-the-badge&color=hotpink diff --git a/node_modules/@tinyhttp/cors/dist/index.d.ts b/node_modules/@tinyhttp/cors/dist/index.d.ts new file mode 100644 index 0000000..53d0521 --- /dev/null +++ b/node_modules/@tinyhttp/cors/dist/index.d.ts @@ -0,0 +1,16 @@ +/// +import { IncomingMessage as Request, ServerResponse as Response } from 'http'; +export interface AccessControlOptions { + origin?: string | boolean | ((req: Request, res: Response) => string) | Array | RegExp; + methods?: string[]; + allowedHeaders?: string[]; + exposedHeaders?: string[]; + credentials?: boolean; + maxAge?: number; + optionsSuccessStatus?: number; + preflightContinue?: boolean; +} +/** + * CORS Middleware + */ +export declare const cors: (opts?: AccessControlOptions) => (req: Request, res: Response, next?: () => void) => void; diff --git a/node_modules/@tinyhttp/cors/dist/index.js b/node_modules/@tinyhttp/cors/dist/index.js new file mode 100644 index 0000000..7417981 --- /dev/null +++ b/node_modules/@tinyhttp/cors/dist/index.js @@ -0,0 +1,63 @@ +import { vary } from 'es-vary'; + +/** + * CORS Middleware + */ +const cors = (opts = {}) => { + const { origin = '*', methods = ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'], allowedHeaders = ['content-type'], exposedHeaders, credentials, maxAge, optionsSuccessStatus = 204, preflightContinue = false } = opts; + return (req, res, next) => { + var _a, _b; + // Checking the type of the origin property + if (typeof origin === 'boolean' && origin === true) { + res.setHeader('Access-Control-Allow-Origin', '*'); + } + else if (typeof origin === 'string') { + res.setHeader('Access-Control-Allow-Origin', origin); + } + else if (typeof origin === 'function') { + res.setHeader('Access-Control-Allow-Origin', origin(req, res)); + } + else if (typeof origin === 'object') { + if (Array.isArray(origin) && (origin.indexOf(req.headers.origin) !== -1 || origin.indexOf('*') !== -1)) { + res.setHeader('Access-Control-Allow-Origin', req.headers.origin); + } + else if (origin instanceof RegExp && origin.test(req.headers.origin)) { + res.setHeader('Access-Control-Allow-Origin', req.headers.origin); + } + else { + throw new TypeError('No other objects allowed. Allowed types is array of strings or RegExp'); + } + } + if ((typeof origin === 'string' && origin !== '*') || typeof origin === 'function') + vary(res, 'Origin'); + // Setting the Access-Control-Allow-Methods header from the methods array + res.setHeader('Access-Control-Allow-Methods', methods.join(', ').toUpperCase()); + // Setting the Access-Control-Allow-Headers header + if (allowedHeaders) + res.setHeader('Access-Control-Allow-Headers', allowedHeaders); + // Setting the Access-Control-Expose-Headers header + if (exposedHeaders) + res.setHeader('Access-Control-Expose-Headers', exposedHeaders); + // Setting the Access-Control-Allow-Credentials header + if (credentials) + res.setHeader('Access-Control-Allow-Credentials', 'true'); + // Setting the Access-Control-Max-Age header + if (maxAge) + res.setHeader('Access-Control-Max-Age', maxAge); + if (((_b = (_a = req.method) === null || _a === void 0 ? void 0 : _a.toUpperCase) === null || _b === void 0 ? void 0 : _b.call(_a)) === 'OPTIONS') { + if (preflightContinue) { + next === null || next === void 0 ? void 0 : next(); + } + else { + res.statusCode = optionsSuccessStatus; + res.setHeader('Content-Length', '0'); + res.end(); + } + } + else { + next === null || next === void 0 ? void 0 : next(); + } + }; +}; + +export { cors }; diff --git a/node_modules/@tinyhttp/cors/package.json b/node_modules/@tinyhttp/cors/package.json new file mode 100644 index 0000000..0d8decb --- /dev/null +++ b/node_modules/@tinyhttp/cors/package.json @@ -0,0 +1,61 @@ +{ + "name": "@tinyhttp/cors", + "version": "2.0.0", + "type": "module", + "description": "CORS middleware for modern Node.js ", + "homepage": "https://github.com/tinyhttp/cors#readme", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/cors.git" + }, + "engines": { + "node": ">=12.4 || 14.x || >=16" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend" + ], + "author": "v1rtl", + "license": "MIT", + "files": [ + "dist" + ], + "dependencies": { + "es-vary": "^0.1.1" + }, + "devDependencies": { + "@commitlint/cli": "13.1.0", + "@commitlint/config-conventional": "13.1.0", + "@rollup/plugin-typescript": "^8.2.5", + "@tinyhttp/app": "1.3.15", + "@types/node": "^16.7.1", + "@typescript-eslint/eslint-plugin": "^4.29.2", + "@typescript-eslint/parser": "^4.29.2", + "c8": "^7.8.0", + "esbuild-node-loader": "^0.3.1", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-prettier": "^3.4.1", + "expect": "^27.0.6", + "husky": "^7.0.1", + "prettier": "^2.3.2", + "rollup": "^2.56.2", + "supertest-fetch": "^1.4.3", + "typescript": "^4.3.5", + "uvu": "^0.5.1" + }, + "scripts": { + "build": "rollup -c", + "test": "node --experimental-loader esbuild-node-loader node_modules/uvu/bin.js tests", + "test:coverage": "c8 --include=src pnpm test", + "test:report": "c8 report --reporter=text-lcov > coverage.lcov", + "lint": "eslint . --ext=ts", + "format": "prettier --check \"./**/*.{ts,md}\"", + "format:fix": "prettier --write \"./**/*.{ts,md}\"" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/encode-url/LICENSE b/node_modules/@tinyhttp/encode-url/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/encode-url/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/encode-url/README.md b/node_modules/@tinyhttp/encode-url/README.md new file mode 100644 index 0000000..5893598 --- /dev/null +++ b/node_modules/@tinyhttp/encode-url/README.md @@ -0,0 +1,15 @@ +# @tinyhttp/encode-url + +> [`encode-url`](https://github.com/pillarjs/encodeurl) rewrite in TypeScript. + +Encode a URL to a percent-encoded form, excluding already-encoded sequences + +## Install + +```sh +pnpm i @tinyhttp/encode-url +``` + +## API + +## Example diff --git a/node_modules/@tinyhttp/encode-url/dist/index.d.ts b/node_modules/@tinyhttp/encode-url/dist/index.d.ts new file mode 100644 index 0000000..6bec93d --- /dev/null +++ b/node_modules/@tinyhttp/encode-url/dist/index.d.ts @@ -0,0 +1,2 @@ +export declare const encodeUrl: (url: string) => string; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/encode-url/dist/index.d.ts.map b/node_modules/@tinyhttp/encode-url/dist/index.d.ts.map new file mode 100644 index 0000000..d266b06 --- /dev/null +++ b/node_modules/@tinyhttp/encode-url/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,SAAS,QAAS,MAAM,KAAG,MAIvC,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/encode-url/dist/index.js b/node_modules/@tinyhttp/encode-url/dist/index.js new file mode 100644 index 0000000..e3b92cc --- /dev/null +++ b/node_modules/@tinyhttp/encode-url/dist/index.js @@ -0,0 +1,10 @@ +const ENCODE_CHARS_REGEXP = /(?:[^\x21\x25\x26-\x3B\x3D\x3F-\x5B\x5D\x5F\x61-\x7A\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]|$))+/g; +const UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g; +const UNMATCHED_SURROGATE_PAIR_REPLACE = "$1�$2"; +const encodeUrl = (url) => { + return String(url).replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE).replace(ENCODE_CHARS_REGEXP, encodeURI); +}; +export { + encodeUrl +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/encode-url/dist/index.js.map b/node_modules/@tinyhttp/encode-url/dist/index.js.map new file mode 100644 index 0000000..9baf55d --- /dev/null +++ b/node_modules/@tinyhttp/encode-url/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["const ENCODE_CHARS_REGEXP =\n /(?:[^\\x21\\x25\\x26-\\x3B\\x3D\\x3F-\\x5B\\x5D\\x5F\\x61-\\x7A\\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]|$))+/g\n\nconst UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF]([^\\uDC00-\\uDFFF]|$)/g\n\nconst UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\\uFFFD$2'\n\nexport const encodeUrl = (url: string): string => {\n return String(url)\n .replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE)\n .replace(ENCODE_CHARS_REGEXP, encodeURI)\n}\n"],"names":[],"mappings":"AAAA,MAAM,sBACJ;AAEF,MAAM,kCAAkC;AAExC,MAAM,mCAAmC;AAE5B,MAAA,YAAY,CAAC,QAAwB;AACzC,SAAA,OAAO,GAAG,EACd,QAAQ,iCAAiC,gCAAgC,EACzE,QAAQ,qBAAqB,SAAS;AAC3C;"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/encode-url/package.json b/node_modules/@tinyhttp/encode-url/package.json new file mode 100644 index 0000000..4956cb2 --- /dev/null +++ b/node_modules/@tinyhttp/encode-url/package.json @@ -0,0 +1,34 @@ +{ + "name": "@tinyhttp/encode-url", + "version": "2.1.1", + "description": "encode-url rewrite in TypeScript", + "type": "module", + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/cors" + }, + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "cors" + ], + "engines": { + "node": ">=12.20.0" + }, + "author": "v1rtl", + "license": "MIT", + "files": [ + "dist" + ], + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/etag/LICENSE b/node_modules/@tinyhttp/etag/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/etag/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/etag/README.md b/node_modules/@tinyhttp/etag/README.md new file mode 100644 index 0000000..f77fe99 --- /dev/null +++ b/node_modules/@tinyhttp/etag/README.md @@ -0,0 +1,35 @@ +# @tinyhttp/etag + +[![npm (scoped)](https://img.shields.io/npm/v/@tinyhttp/etag?style=flat-square)](https://npmjs.com/package/@tinyhttp/etag) [![npm](https://img.shields.io/npm/dt/@tinyhttp/etag?style=flat-square)](https://npmjs.com/package/@tinyhttp/etag) [![](https://img.shields.io/badge/website-visit-hotpink?style=flat-square)](https://tinyhttp.v1rtl.site/mw/etag) + +> A rewrite of [etag](https://www.npmjs.com/package/etag) module. + +This module generates HTTP ETags (as defined in RFC 7232) for use in HTTP responses. + +## Install + +```sh +pnpm i @tinyhttp/etag +``` + +## API + +```ts +import { eTag } from '@tinyhttp/etag' +``` + +`eTag(entity, [options])` + +Generate a strong ETag for the given entity. This should be the complete body of the entity. Strings, `Buffer`s, and `fs.Stats` are accepted. By default, a strong ETag is generated except for `fs.Stats`, which will generate a weak ETag (this can be overwritten by options.weak). + +```ts +res.setHeader('ETag', eTag(body)) +``` + +### Options + +`eTag` accepts these properties in the options object. + +#### `weak` + +Specifies if the generated ETag will include the weak validator mark (that is, the leading `W/`). The actual entity tag is the same. The default value is `false`, unless the entity is `fs.Stats`, in which case it is `true`. diff --git a/node_modules/@tinyhttp/etag/dist/index.d.ts b/node_modules/@tinyhttp/etag/dist/index.d.ts new file mode 100644 index 0000000..8c3f39c --- /dev/null +++ b/node_modules/@tinyhttp/etag/dist/index.d.ts @@ -0,0 +1,7 @@ +/// +/// +import { Stats } from 'node:fs'; +export declare const eTag: (entity: string | Buffer | Stats, options?: { + weak: boolean; +}) => string; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/etag/dist/index.d.ts.map b/node_modules/@tinyhttp/etag/dist/index.d.ts.map new file mode 100644 index 0000000..34ec615 --- /dev/null +++ b/node_modules/@tinyhttp/etag/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAuB/B,eAAO,MAAM,IAAI,WAAY,MAAM,GAAG,MAAM,GAAG,KAAK,YAAY;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,KAAG,MAUnF,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/etag/dist/index.js b/node_modules/@tinyhttp/etag/dist/index.js new file mode 100644 index 0000000..a6862aa --- /dev/null +++ b/node_modules/@tinyhttp/etag/dist/index.js @@ -0,0 +1,25 @@ +import { createHash } from "node:crypto"; +import { Stats } from "node:fs"; +const entityTag = (entity) => { + if (entity.length === 0) { + return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"'; + } else { + const hash = createHash("sha1").update(entity, "utf8").digest("base64").substring(0, 27); + const len = typeof entity === "string" ? Buffer.byteLength(entity, "utf8") : entity.length; + return '"' + len.toString(16) + "-" + hash + '"'; + } +}; +const statTag = ({ mtime, size }) => { + return '"' + mtime.getTime().toString(16) + "-" + size.toString(16) + '"'; +}; +const eTag = (entity, options) => { + if (entity == null) + throw new TypeError("argument entity is required"); + const weak = (options == null ? void 0 : options.weak) || entity instanceof Stats; + const tag = entity instanceof Stats ? statTag(entity) : entityTag(entity); + return weak ? "W/" + tag : tag; +}; +export { + eTag +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/etag/dist/index.js.map b/node_modules/@tinyhttp/etag/dist/index.js.map new file mode 100644 index 0000000..a5ac920 --- /dev/null +++ b/node_modules/@tinyhttp/etag/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["// Original module: https://github.com/jshttp/etag/blob/master/index.js\n\nimport { createHash } from 'node:crypto'\nimport { Stats } from 'node:fs'\n\nconst entityTag = (entity: string | Buffer): string => {\n if (entity.length === 0) {\n // fast-path empty\n return '\"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk\"'\n } else {\n // generate hash\n const hash = createHash('sha1')\n .update(entity as string, 'utf8')\n .digest('base64')\n .substring(0, 27)\n\n const len = typeof entity === 'string' ? Buffer.byteLength(entity, 'utf8') : entity.length\n\n return '\"' + len.toString(16) + '-' + hash + '\"'\n }\n}\n\nconst statTag = ({ mtime, size }: Stats): string => {\n return '\"' + mtime.getTime().toString(16) + '-' + size.toString(16) + '\"'\n}\n\nexport const eTag = (entity: string | Buffer | Stats, options?: { weak: boolean }): string => {\n if (entity == null) throw new TypeError('argument entity is required')\n\n const weak = options?.weak || entity instanceof Stats\n\n // generate entity tag\n\n const tag = entity instanceof Stats ? statTag(entity) : entityTag(entity)\n\n return weak ? 'W/' + tag : tag\n}\n"],"names":[],"mappings":";;AAKA,MAAM,YAAY,CAAC,WAAoC;AACjD,MAAA,OAAO,WAAW,GAAG;AAEhB,WAAA;AAAA,EAAA,OACF;AAEL,UAAM,OAAO,WAAW,MAAM,EAC3B,OAAO,QAAkB,MAAM,EAC/B,OAAO,QAAQ,EACf,UAAU,GAAG,EAAE;AAEZ,UAAA,MAAM,OAAO,WAAW,WAAW,OAAO,WAAW,QAAQ,MAAM,IAAI,OAAO;AAEpF,WAAO,MAAM,IAAI,SAAS,EAAE,IAAI,MAAM,OAAO;AAAA,EAC/C;AACF;AAEA,MAAM,UAAU,CAAC,EAAE,OAAO,WAA0B;AAC3C,SAAA,MAAM,MAAM,QAAA,EAAU,SAAS,EAAE,IAAI,MAAM,KAAK,SAAS,EAAE,IAAI;AACxE;AAEa,MAAA,OAAO,CAAC,QAAiC,YAAwC;AAC5F,MAAI,UAAU;AAAY,UAAA,IAAI,UAAU,6BAA6B;AAE/D,QAAA,QAAO,mCAAS,SAAQ,kBAAkB;AAIhD,QAAM,MAAM,kBAAkB,QAAQ,QAAQ,MAAM,IAAI,UAAU,MAAM;AAEjE,SAAA,OAAO,OAAO,MAAM;AAC7B;"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/etag/package.json b/node_modules/@tinyhttp/etag/package.json new file mode 100644 index 0000000..18c1cbb --- /dev/null +++ b/node_modules/@tinyhttp/etag/package.json @@ -0,0 +1,37 @@ +{ + "name": "@tinyhttp/etag", + "version": "2.1.1", + "type": "module", + "description": "entity tag module", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/etag" + }, + "bugs": { + "url": "https://github.com/tinyhttp/tinyhttp/issues" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "etag" + ], + "engines": { + "node": ">=12.20.0" + }, + "author": "v1rtl", + "license": "MIT", + "files": [ + "dist" + ], + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/forwarded/LICENSE b/node_modules/@tinyhttp/forwarded/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/forwarded/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/forwarded/README.md b/node_modules/@tinyhttp/forwarded/README.md new file mode 100644 index 0000000..a44d3eb --- /dev/null +++ b/node_modules/@tinyhttp/forwarded/README.md @@ -0,0 +1,17 @@ +# @tinyhttp/forwarded + +> [`forwarded`](https://github.com/jshttp/forwarded) rewrite in TypeScript + +Determine address of a proxied request + +## Install + +```sh +pnpm i @tinyhttp/forwarded +``` + +## API + +```ts +import { forwarded } from '@tinyhttp/forwarded' +``` diff --git a/node_modules/@tinyhttp/forwarded/dist/index.d.ts b/node_modules/@tinyhttp/forwarded/dist/index.d.ts new file mode 100644 index 0000000..839a848 --- /dev/null +++ b/node_modules/@tinyhttp/forwarded/dist/index.d.ts @@ -0,0 +1,11 @@ +/// +import { IncomingMessage } from 'node:http'; +/** + * Get all addresses in the request, using the `X-Forwarded-For` header. + */ +export declare function forwarded(req: Pick): string[]; +/** + * Parse the X-Forwarded-For header. + */ +export declare function parse(header: string): string[]; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/forwarded/dist/index.d.ts.map b/node_modules/@tinyhttp/forwarded/dist/index.d.ts.map new file mode 100644 index 0000000..150d8b9 --- /dev/null +++ b/node_modules/@tinyhttp/forwarded/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAE3C;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,QAAQ,CAAC,GAAG,MAAM,EAAE,CAOpF;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA6B9C"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/forwarded/dist/index.js b/node_modules/@tinyhttp/forwarded/dist/index.js new file mode 100644 index 0000000..cc61b4e --- /dev/null +++ b/node_modules/@tinyhttp/forwarded/dist/index.js @@ -0,0 +1,36 @@ +function forwarded(req) { + const proxyAddrs = parse(req.headers["x-forwarded-for"] || ""); + const socketAddr = req.socket.remoteAddress; + return [socketAddr].concat(proxyAddrs); +} +function parse(header) { + let end = header.length; + const list = []; + let start = header.length; + for (let i = header.length - 1; i >= 0; i--) { + switch (header.charCodeAt(i)) { + case 32: + if (start === end) { + start = end = i; + } + break; + case 44: + if (start !== end) { + list.push(header.substring(start, end)); + } + start = end = i; + break; + default: + start = i; + break; + } + } + if (start !== end) + list.push(header.substring(start, end)); + return list; +} +export { + forwarded, + parse +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/forwarded/dist/index.js.map b/node_modules/@tinyhttp/forwarded/dist/index.js.map new file mode 100644 index 0000000..986530e --- /dev/null +++ b/node_modules/@tinyhttp/forwarded/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { IncomingMessage } from 'node:http'\n\n/**\n * Get all addresses in the request, using the `X-Forwarded-For` header.\n */\nexport function forwarded(req: Pick): string[] {\n // simple header parsing\n const proxyAddrs = parse((req.headers['x-forwarded-for'] as string) || '')\n const socketAddr = req.socket.remoteAddress\n\n // return all addresses\n return [socketAddr].concat(proxyAddrs)\n}\n\n/**\n * Parse the X-Forwarded-For header.\n */\nexport function parse(header: string): string[] {\n let end = header.length\n const list: string[] = []\n let start = header.length\n\n // gather addresses, backwards\n for (let i = header.length - 1; i >= 0; i--) {\n switch (header.charCodeAt(i)) {\n case 0x20 /* */:\n if (start === end) {\n start = end = i\n }\n break\n case 0x2c /* , */:\n if (start !== end) {\n list.push(header.substring(start, end))\n }\n start = end = i\n break\n default:\n start = i\n break\n }\n }\n\n // final address\n if (start !== end) list.push(header.substring(start, end))\n\n return list\n}\n"],"names":[],"mappings":"AAKO,SAAS,UAAU,KAA4D;AAEpF,QAAM,aAAa,MAAO,IAAI,QAAQ,iBAAiB,KAAgB,EAAE;AACnE,QAAA,aAAa,IAAI,OAAO;AAG9B,SAAO,CAAC,UAAU,EAAE,OAAO,UAAU;AACvC;AAKO,SAAS,MAAM,QAA0B;AAC9C,MAAI,MAAM,OAAO;AACjB,QAAM,OAAiB,CAAA;AACvB,MAAI,QAAQ,OAAO;AAGnB,WAAS,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AACnC,YAAA,OAAO,WAAW,CAAC,GAAG;AAAA,MAC5B,KAAK;AACH,YAAI,UAAU,KAAK;AACjB,kBAAQ,MAAM;AAAA,QAChB;AACA;AAAA,MACF,KAAK;AACH,YAAI,UAAU,KAAK;AACjB,eAAK,KAAK,OAAO,UAAU,OAAO,GAAG,CAAC;AAAA,QACxC;AACA,gBAAQ,MAAM;AACd;AAAA,MACF;AACU,gBAAA;AACR;AAAA,IACJ;AAAA,EACF;AAGA,MAAI,UAAU;AAAK,SAAK,KAAK,OAAO,UAAU,OAAO,GAAG,CAAC;AAElD,SAAA;AACT;"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/forwarded/package.json b/node_modules/@tinyhttp/forwarded/package.json new file mode 100644 index 0000000..aefdff8 --- /dev/null +++ b/node_modules/@tinyhttp/forwarded/package.json @@ -0,0 +1,36 @@ +{ + "name": "@tinyhttp/forwarded", + "version": "2.1.2", + "type": "module", + "description": "forwarded rewrite with TypeScript and ESM support", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/forwarded" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "files": [ + "dist" + ], + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "forwarded", + "headers", + "header" + ], + "engines": { + "node": ">=12.20.0" + }, + "author": "v1rtl", + "license": "MIT", + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/proxy-addr/LICENSE b/node_modules/@tinyhttp/proxy-addr/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/proxy-addr/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/proxy-addr/README.md b/node_modules/@tinyhttp/proxy-addr/README.md new file mode 100644 index 0000000..d920897 --- /dev/null +++ b/node_modules/@tinyhttp/proxy-addr/README.md @@ -0,0 +1,17 @@ +# @tinyhttp/proxyaddr + +> [`proxy-addr`](https://github.com/jshttp/proxy-addr) rewrite in TypeScript + +Determine address of a proxied request + +## Install + +```sh +pnpm i @tinyhttp/proxy-addr +``` + +## API + +```ts +import { proxyaddr, all } from '@tinyhttp/proxy-addr' +``` diff --git a/node_modules/@tinyhttp/proxy-addr/dist/index.d.ts b/node_modules/@tinyhttp/proxy-addr/dist/index.d.ts new file mode 100644 index 0000000..4e201cc --- /dev/null +++ b/node_modules/@tinyhttp/proxy-addr/dist/index.d.ts @@ -0,0 +1,37 @@ +/// +import type { IncomingMessage } from 'node:http'; +import { IPv6, IPv4 } from 'ipaddr.js'; +type Req = Pick; +type Trust = ((addr: string, i: number) => boolean) | number[] | string[] | string; +/** + * Get all addresses in the request, optionally stopping + * at the first untrusted. + * + * @param request + * @param trust + */ +declare function alladdrs(req: Req, trust: Trust): string[]; +/** + * Compile argument into trust function. + * + * @param val + */ +declare function compile(val: string | string[] | number[]): (addr: string) => boolean; +/** + * Parse IP notation string into range subnet. + * + * @param {String} note + * @private + */ +export declare function parseIPNotation(note: string): [IPv4 | IPv6, string | number]; +/** + * Determine address of proxied request. + * + * @param request + * @param trust + * @public + */ +export declare function proxyaddr(req: Req, trust: Trust): string; +export { alladdrs as all }; +export { compile }; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/proxy-addr/dist/index.d.ts.map b/node_modules/@tinyhttp/proxy-addr/dist/index.d.ts.map new file mode 100644 index 0000000..bac7f60 --- /dev/null +++ b/node_modules/@tinyhttp/proxy-addr/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAChD,OAAe,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAE9C,KAAK,GAAG,GAAG,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAA;AAEtD,KAAK,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,CAAA;AAmBlF;;;;;;GAMG;AACH,iBAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CAclD;AACD;;;;GAIG;AACH,iBAAS,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAiB7E;AAoBD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,IAAI,GAAG,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,CA0B5E;AAWD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAIxD;AAoDD,OAAO,EAAE,QAAQ,IAAI,GAAG,EAAE,CAAA;AAC1B,OAAO,EAAE,OAAO,EAAE,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/proxy-addr/dist/index.js b/node_modules/@tinyhttp/proxy-addr/dist/index.js new file mode 100644 index 0000000..a9e335b --- /dev/null +++ b/node_modules/@tinyhttp/proxy-addr/dist/index.js @@ -0,0 +1,136 @@ +import { forwarded } from "@tinyhttp/forwarded"; +import ipaddr from "ipaddr.js"; +const DIGIT_REGEXP = /^[0-9]+$/; +const isip = ipaddr.isValid; +const parseip = ipaddr.parse; +const IP_RANGES = { + linklocal: ["169.254.0.0/16", "fe80::/10"], + loopback: ["127.0.0.1/8", "::1/128"], + uniquelocal: ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fc00::/7"] +}; +const trustNone = () => false; +function alladdrs(req, trust) { + const addrs = forwarded(req); + if (!trust) + return addrs; + if (typeof trust !== "function") + trust = compile(trust); + for (let i = 0; i < addrs.length - 1; i++) { + if (trust(addrs[i], i)) + continue; + addrs.length = i + 1; + } + return addrs; +} +function compile(val) { + let trust; + if (typeof val === "string") + trust = [val]; + else if (Array.isArray(val)) + trust = val.slice(); + else + throw new TypeError("unsupported trust argument"); + for (let i = 0; i < trust.length; i++) { + val = trust[i]; + if (!Object.prototype.hasOwnProperty.call(IP_RANGES, val)) + continue; + val = IP_RANGES[val]; + trust.splice.apply(trust, [i, 1].concat(val)); + i += val.length - 1; + } + return compileTrust(compileRangeSubnets(trust)); +} +function compileRangeSubnets(arr) { + const rangeSubnets = new Array(arr.length); + for (let i = 0; i < arr.length; i++) + rangeSubnets[i] = parseIPNotation(arr[i]); + return rangeSubnets; +} +function compileTrust(rangeSubnets) { + const len = rangeSubnets.length; + return len === 0 ? trustNone : len === 1 ? trustSingle(rangeSubnets[0]) : trustMulti(rangeSubnets); +} +function parseIPNotation(note) { + const pos = note.lastIndexOf("/"); + const str = pos !== -1 ? note.substring(0, pos) : note; + if (!isip(str)) + throw new TypeError("invalid IP address: " + str); + let ip = parseip(str); + if (pos === -1 && ip.kind() === "ipv6") { + ip = ip; + if (ip.isIPv4MappedAddress()) + ip = ip.toIPv4Address(); + } + const max = ip.kind() === "ipv6" ? 128 : 32; + let range = pos !== -1 ? note.substring(pos + 1, note.length) : null; + if (range === null) + range = max; + else if (DIGIT_REGEXP.test(range)) + range = parseInt(range, 10); + else if (ip.kind() === "ipv4" && isip(range)) + range = parseNetmask(range); + else + range = null; + if (typeof range === "number" && (range <= 0 || range > max)) + throw new TypeError("invalid range on address: " + note); + return [ip, range]; +} +function parseNetmask(netmask) { + const ip = parseip(netmask); + return ip.kind() === "ipv4" ? ip.prefixLengthFromSubnetMask() : null; +} +function proxyaddr(req, trust) { + const addrs = alladdrs(req, trust); + return addrs[addrs.length - 1]; +} +function trustMulti(subnets) { + return function trust(addr) { + if (!isip(addr)) + return false; + const ip = parseip(addr); + let ipconv; + const kind = ip.kind(); + for (let i = 0; i < subnets.length; i++) { + const subnet = subnets[i]; + const subnetip = subnet[0]; + const subnetkind = subnetip.kind(); + const subnetrange = subnet[1]; + let trusted = ip; + if (kind !== subnetkind) { + if (subnetkind === "ipv4" && !ip.isIPv4MappedAddress()) + continue; + if (!ipconv) + ipconv = subnetkind === "ipv4" ? ip.toIPv4Address() : ip.toIPv4MappedAddress(); + trusted = ipconv; + } + if (trusted.match(subnetip, subnetrange)) + return true; + } + return false; + }; +} +function trustSingle(subnet) { + const subnetip = subnet[0]; + const subnetkind = subnetip.kind(); + const subnetisipv4 = subnetkind === "ipv4"; + const subnetrange = subnet[1]; + return function trust(addr) { + if (!isip(addr)) + return false; + let ip = parseip(addr); + const kind = ip.kind(); + if (kind !== subnetkind) { + if (subnetisipv4 && !ip.isIPv4MappedAddress()) + return false; + ip = subnetisipv4 ? ip.toIPv4Address() : ip.toIPv4MappedAddress(); + } + return ip.match(subnetip, subnetrange); + }; +} +export { + alladdrs as all, + compile, + parseIPNotation, + proxyaddr +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/proxy-addr/dist/index.js.map b/node_modules/@tinyhttp/proxy-addr/dist/index.js.map new file mode 100644 index 0000000..60d9816 --- /dev/null +++ b/node_modules/@tinyhttp/proxy-addr/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { forwarded } from '@tinyhttp/forwarded'\nimport type { IncomingMessage } from 'node:http'\nimport ipaddr, { IPv6, IPv4 } from 'ipaddr.js'\n\ntype Req = Pick\n\ntype Trust = ((addr: string, i: number) => boolean) | number[] | string[] | string\n\nconst DIGIT_REGEXP = /^[0-9]+$/\nconst isip = ipaddr.isValid\nconst parseip = ipaddr.parse\n/**\n * Pre-defined IP ranges.\n */\nconst IP_RANGES = {\n linklocal: ['169.254.0.0/16', 'fe80::/10'],\n loopback: ['127.0.0.1/8', '::1/128'],\n uniquelocal: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7']\n}\n\n/**\n * Static trust function to trust nothing.\n */\nconst trustNone = () => false\n\n/**\n * Get all addresses in the request, optionally stopping\n * at the first untrusted.\n *\n * @param request\n * @param trust\n */\nfunction alladdrs(req: Req, trust: Trust): string[] {\n // get addresses\n\n const addrs = forwarded(req)\n\n if (!trust) return addrs\n\n if (typeof trust !== 'function') trust = compile(trust)\n\n for (let i = 0; i < addrs.length - 1; i++) {\n if (trust(addrs[i], i)) continue\n addrs.length = i + 1\n }\n return addrs\n}\n/**\n * Compile argument into trust function.\n *\n * @param val\n */\nfunction compile(val: string | string[] | number[]): (addr: string) => boolean {\n let trust: string[]\n if (typeof val === 'string') trust = [val]\n else if (Array.isArray(val)) trust = val.slice() as string[]\n else throw new TypeError('unsupported trust argument')\n\n for (let i = 0; i < trust.length; i++) {\n val = trust[i]\n if (!Object.prototype.hasOwnProperty.call(IP_RANGES, val)) continue\n\n // Splice in pre-defined range\n val = IP_RANGES[val as string]\n // eslint-disable-next-line prefer-spread\n trust.splice.apply(trust, [i, 1].concat(val as number[]))\n i += val.length - 1\n }\n return compileTrust(compileRangeSubnets(trust))\n}\n/**\n * Compile `arr` elements into range subnets.\n */\nfunction compileRangeSubnets(arr: string[]) {\n const rangeSubnets = new Array(arr.length)\n for (let i = 0; i < arr.length; i++) rangeSubnets[i] = parseIPNotation(arr[i])\n\n return rangeSubnets\n}\n/**\n * Compile range subnet array into trust function.\n *\n * @param rangeSubnets\n */\nfunction compileTrust(rangeSubnets: (IPv4 | IPv6)[]) {\n // Return optimized function based on length\n const len = rangeSubnets.length\n return len === 0 ? trustNone : len === 1 ? trustSingle(rangeSubnets[0]) : trustMulti(rangeSubnets)\n}\n/**\n * Parse IP notation string into range subnet.\n *\n * @param {String} note\n * @private\n */\nexport function parseIPNotation(note: string): [IPv4 | IPv6, string | number] {\n const pos = note.lastIndexOf('/')\n const str = pos !== -1 ? note.substring(0, pos) : note\n\n if (!isip(str)) throw new TypeError('invalid IP address: ' + str)\n\n let ip = parseip(str)\n\n if (pos === -1 && ip.kind() === 'ipv6') {\n ip = ip as IPv6\n\n if (ip.isIPv4MappedAddress()) ip = ip.toIPv4Address()\n }\n\n const max = ip.kind() === 'ipv6' ? 128 : 32\n\n let range: string | number = pos !== -1 ? note.substring(pos + 1, note.length) : null\n\n if (range === null) range = max\n else if (DIGIT_REGEXP.test(range)) range = parseInt(range, 10)\n else if (ip.kind() === 'ipv4' && isip(range)) range = parseNetmask(range)\n else range = null\n\n if (typeof range === 'number' && (range <= 0 || range > max)) throw new TypeError('invalid range on address: ' + note)\n\n return [ip, range]\n}\n/**\n * Parse netmask string into CIDR range.\n *\n * @param netmask\n * @private\n */\nfunction parseNetmask(netmask: string) {\n const ip = parseip(netmask)\n return ip.kind() === 'ipv4' ? ip.prefixLengthFromSubnetMask() : null\n}\n/**\n * Determine address of proxied request.\n *\n * @param request\n * @param trust\n * @public\n */\nexport function proxyaddr(req: Req, trust: Trust): string {\n const addrs = alladdrs(req, trust)\n\n return addrs[addrs.length - 1]\n}\n\n/**\n * Compile trust function for multiple subnets.\n */\nfunction trustMulti(subnets: (IPv4 | IPv6)[]) {\n return function trust(addr: string) {\n if (!isip(addr)) return false\n const ip = parseip(addr)\n let ipconv: IPv4 | IPv6\n const kind = ip.kind()\n for (let i = 0; i < subnets.length; i++) {\n const subnet = subnets[i]\n const subnetip = subnet[0]\n const subnetkind = subnetip.kind()\n const subnetrange = subnet[1]\n let trusted = ip\n if (kind !== subnetkind) {\n if (subnetkind === 'ipv4' && !(ip as IPv6).isIPv4MappedAddress()) continue\n\n if (!ipconv) ipconv = subnetkind === 'ipv4' ? (ip as IPv6).toIPv4Address() : (ip as IPv4).toIPv4MappedAddress()\n\n trusted = ipconv\n }\n if ((trusted as IPv4).match(subnetip, subnetrange)) return true\n }\n return false\n }\n}\n/**\n * Compile trust function for single subnet.\n *\n * @param subnet\n */\nfunction trustSingle(subnet: IPv4 | IPv6) {\n const subnetip = subnet[0]\n const subnetkind = subnetip.kind()\n const subnetisipv4 = subnetkind === 'ipv4'\n const subnetrange = subnet[1]\n return function trust(addr: string) {\n if (!isip(addr)) return false\n let ip = parseip(addr)\n const kind = ip.kind()\n if (kind !== subnetkind) {\n if (subnetisipv4 && !(ip as IPv6).isIPv4MappedAddress()) return false\n\n ip = subnetisipv4 ? (ip as IPv6).toIPv4Address() : (ip as IPv4).toIPv4MappedAddress()\n }\n return (ip as IPv6).match(subnetip, subnetrange)\n }\n}\n\nexport { alladdrs as all }\nexport { compile }\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/proxy-addr/package.json b/node_modules/@tinyhttp/proxy-addr/package.json new file mode 100644 index 0000000..acf096c --- /dev/null +++ b/node_modules/@tinyhttp/proxy-addr/package.json @@ -0,0 +1,41 @@ +{ + "name": "@tinyhttp/proxy-addr", + "version": "2.1.3", + "type": "module", + "description": "proxy-addr rewrite with TypeScript and ESM support", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/proxy-addr" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "proxy-addr", + "ip", + "net", + "network" + ], + "engines": { + "node": ">=12.20.0" + }, + "author": "v1rtl", + "license": "MIT", + "dependencies": { + "ipaddr.js": "^2.1.0", + "@tinyhttp/forwarded": "2.1.2" + }, + "files": [ + "dist" + ], + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/req/LICENSE b/node_modules/@tinyhttp/req/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/req/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/req/README.md b/node_modules/@tinyhttp/req/README.md new file mode 100644 index 0000000..01a07a9 --- /dev/null +++ b/node_modules/@tinyhttp/req/README.md @@ -0,0 +1,19 @@ +# @tinyhttp/req + +[![npm (scoped)][npm-badge]](https://npmjs.com/package/@tinyhttp/req) [![npm][dl-badge]](https://npmjs.com/package/@tinyhttp/req) [![][web-badge]](https://tinyhttp.v1rtl.site/mw/req) + +Request extensions for tinyhttp collected in one package. + +## Install + +```sh +pnpm i @tinyhttp/req +``` + +## API + +[tinyhttp Request docs](https://tinyhttp.v1rtl.site/docs#request). + +[npm-badge]: https://img.shields.io/npm/v/@tinyhttp/req?style=flat-square +[dl-badge]: https://img.shields.io/npm/dt/@tinyhttp/req?style=flat-square +[web-badge]: https://img.shields.io/badge/website-visit-hotpink?style=flat-square diff --git a/node_modules/@tinyhttp/req/dist/accepts.d.ts b/node_modules/@tinyhttp/req/dist/accepts.d.ts new file mode 100644 index 0000000..4b367e1 --- /dev/null +++ b/node_modules/@tinyhttp/req/dist/accepts.d.ts @@ -0,0 +1,10 @@ +/// +import { IncomingMessage } from 'node:http'; +type Request = Pick; +type AcceptReturns = string | boolean | string[]; +export declare const getAccepts: (req: Request) => (...types: string[]) => AcceptReturns; +export declare const getAcceptsEncodings: (req: Request) => (...encodings: string[]) => AcceptReturns; +export declare const getAcceptsCharsets: (req: Request) => (...charsets: string[]) => AcceptReturns; +export declare const getAcceptsLanguages: (req: Request) => (...languages: string[]) => AcceptReturns; +export {}; +//# sourceMappingURL=accepts.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/req/dist/accepts.d.ts.map b/node_modules/@tinyhttp/req/dist/accepts.d.ts.map new file mode 100644 index 0000000..a7c5c2e --- /dev/null +++ b/node_modules/@tinyhttp/req/dist/accepts.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"accepts.d.ts","sourceRoot":"","sources":["../src/accepts.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAG3C,KAAK,OAAO,GAAG,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,CAAA;AAE/C,KAAK,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAA;AAEhD,eAAO,MAAM,UAAU,QACf,OAAO,gBACF,MAAM,EAAE,KAAG,aACS,CAAA;AAEjC,eAAO,MAAM,mBAAmB,QACxB,OAAO,oBACE,MAAM,EAAE,KAAG,aACa,CAAA;AAEzC,eAAO,MAAM,kBAAkB,QACvB,OAAO,mBACC,MAAM,EAAE,KAAG,aACY,CAAA;AAEvC,eAAO,MAAM,mBAAmB,QACxB,OAAO,oBACE,MAAM,EAAE,KAAG,aACa,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/req/dist/fresh.d.ts b/node_modules/@tinyhttp/req/dist/fresh.d.ts new file mode 100644 index 0000000..0993d84 --- /dev/null +++ b/node_modules/@tinyhttp/req/dist/fresh.d.ts @@ -0,0 +1,7 @@ +/// +import { IncomingHttpHeaders, OutgoingHttpHeaders } from 'node:http'; +/** + * Check freshness of the response using request and response headers. + */ +export declare function fresh(reqHeaders: IncomingHttpHeaders, resHeaders: OutgoingHttpHeaders): boolean; +//# sourceMappingURL=fresh.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/req/dist/fresh.d.ts.map b/node_modules/@tinyhttp/req/dist/fresh.d.ts.map new file mode 100644 index 0000000..e647c8c --- /dev/null +++ b/node_modules/@tinyhttp/req/dist/fresh.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"fresh.d.ts","sourceRoot":"","sources":["../src/fresh.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AA8BpE;;GAEG;AACH,wBAAgB,KAAK,CAAC,UAAU,EAAE,mBAAmB,EAAE,UAAU,EAAE,mBAAmB,WAwBrF"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/req/dist/index.d.ts b/node_modules/@tinyhttp/req/dist/index.d.ts new file mode 100644 index 0000000..1fd902b --- /dev/null +++ b/node_modules/@tinyhttp/req/dist/index.d.ts @@ -0,0 +1,11 @@ +/// +import { IncomingMessage as Request, ServerResponse as Response } from 'node:http'; +import { Options, Ranges, Result } from 'header-range-parser'; +export * from './accepts.js'; +export * from '@tinyhttp/url'; +export declare const getRequestHeader: (req: Pick) => (header: string) => string | string[]; +export declare const getRangeFromHeader: (req: Pick) => (size: number, options?: Options) => Result | Ranges; +export declare const getFreshOrStale: (req: Pick, res: Pick) => boolean; +export declare const checkIfXMLHttpRequest: (req: Pick) => boolean; +export declare const reqIs: (req: Pick) => (...types: string[]) => string | false; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/req/dist/index.d.ts.map b/node_modules/@tinyhttp/req/dist/index.d.ts.map new file mode 100644 index 0000000..252db46 --- /dev/null +++ b/node_modules/@tinyhttp/req/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,IAAI,OAAO,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,WAAW,CAAA;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAc,MAAM,qBAAqB,CAAA;AAKzE,cAAc,cAAc,CAAA;AAE5B,cAAc,eAAe,CAAA;AAE7B,eAAO,MAAM,gBAAgB,QACrB,KAAK,OAAO,EAAE,SAAS,CAAC,cACrB,MAAM,KAAG,MAAM,GAAG,MAAM,EAUhC,CAAA;AAEH,eAAO,MAAM,kBAAkB,QACvB,KAAK,OAAO,EAAE,SAAS,CAAC,YACvB,MAAM,YAAY,OAAO,KAAG,MAAM,GAAG,MAM3C,CAAA;AAEH,eAAO,MAAM,eAAe,QACrB,KAAK,OAAO,EAAE,SAAS,GAAG,QAAQ,CAAC,OACnC,KAAK,QAAQ,EAAE,WAAW,GAAG,YAAY,CAAC,KAC9C,OAgBF,CAAA;AAED,eAAO,MAAM,qBAAqB,QAAS,KAAK,OAAO,EAAE,SAAS,CAAC,KAAG,OAChB,CAAA;AAEtD,eAAO,MAAM,KAAK,QACV,KAAK,OAAO,EAAE,SAAS,CAAC,gBACnB,MAAM,EAAE,mBAC4B,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/req/dist/index.js b/node_modules/@tinyhttp/req/dist/index.js new file mode 100644 index 0000000..ddd3601 --- /dev/null +++ b/node_modules/@tinyhttp/req/dist/index.js @@ -0,0 +1,96 @@ +import { parseRange } from "header-range-parser"; +import { typeIs } from "@tinyhttp/type-is"; +import { Accepts } from "@tinyhttp/accepts"; +export * from "@tinyhttp/url"; +const CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/; +const compareETags = (etag, str) => str === etag || str === `W/${etag}` || `W/${str}` === etag; +function isStale(etag, noneMatch) { + let start = 0; + let end = 0; + for (let i = 0, len = noneMatch.length; i < len; i++) { + switch (noneMatch.charCodeAt(i)) { + case 32: + if (start === end) + start = end = i + 1; + break; + case 44: + if (compareETags(etag, noneMatch.substring(start, end))) + return false; + start = end = i + 1; + break; + default: + end = i + 1; + break; + } + } + if (compareETags(etag, noneMatch.substring(start, end))) + return false; + return true; +} +function fresh(reqHeaders, resHeaders) { + const modifiedSince = reqHeaders["if-modified-since"]; + const noneMatch = reqHeaders["if-none-match"]; + if (!modifiedSince && !noneMatch) + return false; + const cacheControl = reqHeaders["cache-control"]; + if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) + return false; + if (noneMatch !== "*") { + const etag = resHeaders.etag; + if (!etag || isStale(etag, noneMatch)) + return false; + } + if (modifiedSince) { + const lastModified = resHeaders["last-modified"]; + if (!lastModified || !(Date.parse(lastModified) <= Date.parse(modifiedSince))) + return false; + } + return true; +} +const getAccepts = (req) => (...types) => new Accepts(req).types(types); +const getAcceptsEncodings = (req) => (...encodings) => new Accepts(req).encodings(encodings); +const getAcceptsCharsets = (req) => (...charsets) => new Accepts(req).charsets(charsets); +const getAcceptsLanguages = (req) => (...languages) => new Accepts(req).languages(languages); +const getRequestHeader = (req) => (header) => { + const lc = header.toLowerCase(); + switch (lc) { + case "referer": + case "referrer": + return req.headers.referrer || req.headers.referer; + default: + return req.headers[lc]; + } +}; +const getRangeFromHeader = (req) => (size, options) => { + const range = getRequestHeader(req)("Range"); + if (!range) + return; + return parseRange(size, range, options); +}; +const getFreshOrStale = (req, res) => { + const method = req.method; + const status = res.statusCode; + if (method !== "GET" && method !== "HEAD") + return false; + if (status >= 200 && status < 300 || status === 304) { + return fresh(req.headers, { + etag: res.getHeader("ETag"), + "last-modified": res.getHeader("Last-Modified") + }); + } + return false; +}; +const checkIfXMLHttpRequest = (req) => req.headers["x-requested-with"] === "XMLHttpRequest"; +const reqIs = (req) => (...types) => typeIs(req.headers["content-type"], ...types); +export { + checkIfXMLHttpRequest, + getAccepts, + getAcceptsCharsets, + getAcceptsEncodings, + getAcceptsLanguages, + getFreshOrStale, + getRangeFromHeader, + getRequestHeader, + reqIs +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/req/dist/index.js.map b/node_modules/@tinyhttp/req/dist/index.js.map new file mode 100644 index 0000000..81b2d74 --- /dev/null +++ b/node_modules/@tinyhttp/req/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/fresh.ts","../src/accepts.ts","../src/index.ts"],"sourcesContent":["import { IncomingHttpHeaders, OutgoingHttpHeaders } from 'node:http'\n\nconst CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\\s*?no-cache\\s*?(?:,|$)/\n\nconst compareETags = (etag: string, str: string) => str === etag || str === `W/${etag}` || `W/${str}` === etag\n\nfunction isStale(etag: string, noneMatch: string) {\n let start = 0\n let end = 0\n\n for (let i = 0, len = noneMatch.length; i < len; i++) {\n switch (noneMatch.charCodeAt(i)) {\n case 0x20 /* */:\n if (start === end) start = end = i + 1\n break\n case 0x2c /* , */:\n if (compareETags(etag, noneMatch.substring(start, end))) return false\n start = end = i + 1\n break\n default:\n end = i + 1\n break\n }\n }\n\n if (compareETags(etag, noneMatch.substring(start, end))) return false\n\n return true\n}\n\n/**\n * Check freshness of the response using request and response headers.\n */\nexport function fresh(reqHeaders: IncomingHttpHeaders, resHeaders: OutgoingHttpHeaders) {\n const modifiedSince = reqHeaders['if-modified-since']\n const noneMatch = reqHeaders['if-none-match']\n\n if (!modifiedSince && !noneMatch) return false\n\n const cacheControl = reqHeaders['cache-control']\n if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) return false\n\n // if-none-match\n if (noneMatch !== '*') {\n const etag = resHeaders.etag as string | undefined\n\n if (!etag || isStale(etag, noneMatch)) return false\n }\n\n // if-modified-since\n if (modifiedSince) {\n const lastModified = resHeaders['last-modified'] as string | undefined\n\n if (!lastModified || !(Date.parse(lastModified) <= Date.parse(modifiedSince))) return false\n }\n\n return true\n}\n","import { IncomingMessage } from 'node:http'\nimport { Accepts } from '@tinyhttp/accepts'\n\ntype Request = Pick\n\ntype AcceptReturns = string | boolean | string[]\n\nexport const getAccepts =\n (req: Request) =>\n (...types: string[]): AcceptReturns =>\n new Accepts(req).types(types)\n\nexport const getAcceptsEncodings =\n (req: Request) =>\n (...encodings: string[]): AcceptReturns =>\n new Accepts(req).encodings(encodings)\n\nexport const getAcceptsCharsets =\n (req: Request) =>\n (...charsets: string[]): AcceptReturns =>\n new Accepts(req).charsets(charsets)\n\nexport const getAcceptsLanguages =\n (req: Request) =>\n (...languages: string[]): AcceptReturns =>\n new Accepts(req).languages(languages)\n","import { IncomingMessage as Request, ServerResponse as Response } from 'node:http'\nimport { Options, Ranges, Result, parseRange } from 'header-range-parser'\n\nimport { typeIs } from '@tinyhttp/type-is'\nimport { fresh } from './fresh.js'\n\nexport * from './accepts.js'\n\nexport * from '@tinyhttp/url'\n\nexport const getRequestHeader =\n (req: Pick) =>\n (header: string): string | string[] => {\n const lc = header.toLowerCase()\n\n switch (lc) {\n case 'referer':\n case 'referrer':\n return req.headers.referrer || req.headers.referer\n default:\n return req.headers[lc]\n }\n }\n\nexport const getRangeFromHeader =\n (req: Pick) =>\n (size: number, options?: Options): Result | Ranges => {\n const range = getRequestHeader(req)('Range') as string\n\n if (!range) return\n\n return parseRange(size, range, options)\n }\n\nexport const getFreshOrStale = (\n req: Pick,\n res: Pick\n): boolean => {\n const method = req.method\n const status = res.statusCode\n\n // GET or HEAD for weak freshness validation only\n if (method !== 'GET' && method !== 'HEAD') return false\n\n // 2xx or 304 as per rfc2616 14.26\n if ((status >= 200 && status < 300) || status === 304) {\n return fresh(req.headers, {\n etag: res.getHeader('ETag'),\n 'last-modified': res.getHeader('Last-Modified')\n })\n }\n\n return false\n}\n\nexport const checkIfXMLHttpRequest = (req: Pick): boolean =>\n req.headers['x-requested-with'] === 'XMLHttpRequest'\n\nexport const reqIs =\n (req: Pick) =>\n (...types: string[]) =>\n typeIs(req.headers['content-type'], ...types)\n"],"names":[],"mappings":";;;;AAEA,MAAM,gCAAgC;AAEtC,MAAM,eAAe,CAAC,MAAc,QAAgB,QAAQ,QAAQ,QAAQ,KAAK,IAAI,MAAM,KAAK,GAAG,OAAO;AAE1G,SAAS,QAAQ,MAAc,WAAmB;AAChD,MAAI,QAAQ;AACZ,MAAI,MAAM;AAEV,WAAS,IAAI,GAAG,MAAM,UAAU,QAAQ,IAAI,KAAK,KAAK;AAC5C,YAAA,UAAU,WAAW,CAAC,GAAG;AAAA,MAC/B,KAAK;AACH,YAAI,UAAU;AAAK,kBAAQ,MAAM,IAAI;AACrC;AAAA,MACF,KAAK;AACH,YAAI,aAAa,MAAM,UAAU,UAAU,OAAO,GAAG,CAAC;AAAU,iBAAA;AAChE,gBAAQ,MAAM,IAAI;AAClB;AAAA,MACF;AACE,cAAM,IAAI;AACV;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,aAAa,MAAM,UAAU,UAAU,OAAO,GAAG,CAAC;AAAU,WAAA;AAEzD,SAAA;AACT;AAKgB,SAAA,MAAM,YAAiC,YAAiC;AAChF,QAAA,gBAAgB,WAAW,mBAAmB;AAC9C,QAAA,YAAY,WAAW,eAAe;AAExC,MAAA,CAAC,iBAAiB,CAAC;AAAkB,WAAA;AAEnC,QAAA,eAAe,WAAW,eAAe;AAC3C,MAAA,gBAAgB,8BAA8B,KAAK,YAAY;AAAU,WAAA;AAG7E,MAAI,cAAc,KAAK;AACrB,UAAM,OAAO,WAAW;AAExB,QAAI,CAAC,QAAQ,QAAQ,MAAM,SAAS;AAAU,aAAA;AAAA,EAChD;AAGA,MAAI,eAAe;AACX,UAAA,eAAe,WAAW,eAAe;AAE3C,QAAA,CAAC,gBAAgB,EAAE,KAAK,MAAM,YAAY,KAAK,KAAK,MAAM,aAAa;AAAW,aAAA;AAAA,EACxF;AAEO,SAAA;AACT;AClDa,MAAA,aACX,CAAC,QACD,IAAI,UACF,IAAI,QAAQ,GAAG,EAAE,MAAM,KAAK;AAEnB,MAAA,sBACX,CAAC,QACD,IAAI,cACF,IAAI,QAAQ,GAAG,EAAE,UAAU,SAAS;AAE3B,MAAA,qBACX,CAAC,QACD,IAAI,aACF,IAAI,QAAQ,GAAG,EAAE,SAAS,QAAQ;AAEzB,MAAA,sBACX,CAAC,QACD,IAAI,cACF,IAAI,QAAQ,GAAG,EAAE,UAAU,SAAS;ACfjC,MAAM,mBACX,CAAC,QACD,CAAC,WAAsC;AAC/B,QAAA,KAAK,OAAO;AAElB,UAAQ,IAAI;AAAA,IACV,KAAK;AAAA,IACL,KAAK;AACH,aAAO,IAAI,QAAQ,YAAY,IAAI,QAAQ;AAAA,IAC7C;AACS,aAAA,IAAI,QAAQ,EAAE;AAAA,EACzB;AACF;AAEK,MAAM,qBACX,CAAC,QACD,CAAC,MAAc,YAAuC;AACpD,QAAM,QAAQ,iBAAiB,GAAG,EAAE,OAAO;AAE3C,MAAI,CAAC;AAAO;AAEL,SAAA,WAAW,MAAM,OAAO,OAAO;AACxC;AAEW,MAAA,kBAAkB,CAC7B,KACA,QACY;AACZ,QAAM,SAAS,IAAI;AACnB,QAAM,SAAS,IAAI;AAGf,MAAA,WAAW,SAAS,WAAW;AAAe,WAAA;AAGlD,MAAK,UAAU,OAAO,SAAS,OAAQ,WAAW,KAAK;AAC9C,WAAA,MAAM,IAAI,SAAS;AAAA,MACxB,MAAM,IAAI,UAAU,MAAM;AAAA,MAC1B,iBAAiB,IAAI,UAAU,eAAe;AAAA,IAAA,CAC/C;AAAA,EACH;AAEO,SAAA;AACT;AAEO,MAAM,wBAAwB,CAAC,QACpC,IAAI,QAAQ,kBAAkB,MAAM;AAEzB,MAAA,QACX,CAAC,QACD,IAAI,UACF,OAAO,IAAI,QAAQ,cAAc,GAAG,GAAG,KAAK;"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/req/package.json b/node_modules/@tinyhttp/req/package.json new file mode 100644 index 0000000..3792dbb --- /dev/null +++ b/node_modules/@tinyhttp/req/package.json @@ -0,0 +1,41 @@ +{ + "name": "@tinyhttp/req", + "version": "2.2.2", + "type": "module", + "description": "request extensions for tinyhttp", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/req" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "req", + "request" + ], + "engines": { + "node": ">=12.20.0" + }, + "author": "v1rtl", + "license": "MIT", + "dependencies": { + "header-range-parser": "^1.1.3", + "@tinyhttp/accepts": "2.2.1", + "@tinyhttp/url": "2.1.1", + "@tinyhttp/type-is": "2.2.2" + }, + "files": [ + "dist" + ], + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/LICENSE b/node_modules/@tinyhttp/res/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/res/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/res/README.md b/node_modules/@tinyhttp/res/README.md new file mode 100644 index 0000000..f4446ac --- /dev/null +++ b/node_modules/@tinyhttp/res/README.md @@ -0,0 +1,19 @@ +# @tinyhttp/res + +[![npm (scoped)][npm-badge]](https://npmjs.com/package/@tinyhttp/res) [![npm][dl-badge]](https://npmjs.com/package/@tinyhttp/res) [![][web-badge]](https://tinyhttp.v1rtl.site/mw/res) + +Response extensions for tinyhttp collected in one package. This module itself depends on other modules, such as [`@tinyhttp/send`](/packages/send). + +## Install + +```sh +pnpm i @tinyhttp/res +``` + +## API + +[tinyhttp Response docs](https://tinyhttp.v1rtl.site/docs#response). + +[npm-badge]: https://img.shields.io/npm/v/@tinyhttp/res?style=flat-square +[dl-badge]: https://img.shields.io/npm/dt/@tinyhttp/res?style=flat-square +[web-badge]: https://img.shields.io/badge/website-visit-hotpink?style=flat-square diff --git a/node_modules/@tinyhttp/res/dist/append.d.ts b/node_modules/@tinyhttp/res/dist/append.d.ts new file mode 100644 index 0000000..1323584 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/append.d.ts @@ -0,0 +1,4 @@ +/// +import { ServerResponse as Res } from 'node:http'; +export declare const append: = Res>(res: Response_1) => (field: string, value: string | number | string[]) => Response_1; +//# sourceMappingURL=append.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/append.d.ts.map b/node_modules/@tinyhttp/res/dist/append.d.ts.map new file mode 100644 index 0000000..96fb007 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/append.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"append.d.ts","sourceRoot":"","sources":["../src/append.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,IAAI,GAAG,EAAE,MAAM,WAAW,CAAA;AAGjD,eAAO,MAAM,MAAM,6HAET,MAAM,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,eAahD,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/cookie.d.ts b/node_modules/@tinyhttp/res/dist/cookie.d.ts new file mode 100644 index 0000000..5c7edf2 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/cookie.d.ts @@ -0,0 +1,10 @@ +/// +import { IncomingMessage as Req, ServerResponse as Res } from 'node:http'; +import * as cookie from '@tinyhttp/cookie'; +export declare const setCookie: = Res>(req: Request_1 & { + secret?: string | string[]; +}, res: Response_1) => (name: string, value: string | Record, options?: cookie.SerializeOptions & Partial<{ + signed: boolean; +}>) => Response_1; +export declare const clearCookie: = Res>(req: Request_1, res: Response_1) => (name: string, options?: cookie.SerializeOptions) => Response_1; +//# sourceMappingURL=cookie.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/cookie.d.ts.map b/node_modules/@tinyhttp/res/dist/cookie.d.ts.map new file mode 100644 index 0000000..40badec --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/cookie.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"cookie.d.ts","sourceRoot":"","sources":["../src/cookie.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,IAAI,GAAG,EAAE,cAAc,IAAI,GAAG,EAAE,MAAM,WAAW,CAAA;AACzE,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAA;AAI1C,eAAO,MAAM,SAAS;aAGP,MAAM,GAAG,MAAM,EAAE;8BAKtB,MAAM,SACL,MAAM,GAAG,OAAO,MAAM,EAAE,OAAO,CAAC,YAC9B,OAAO,gBAAgB,GAC9B,QAAQ;IACN,MAAM,EAAE,OAAO,CAAA;CAChB,CAAC,eAsBL,CAAA;AAEH,eAAO,MAAM,WAAW,mHAEf,MAAM,YAAY,OAAO,gBAAgB,eAE/C,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/download.d.ts b/node_modules/@tinyhttp/res/dist/download.d.ts new file mode 100644 index 0000000..10b788d --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/download.d.ts @@ -0,0 +1,11 @@ +/// +import { IncomingMessage as Req, ServerResponse as Res } from 'node:http'; +import type { SendFileOptions } from '@tinyhttp/send'; +export type DownloadOptions = SendFileOptions & Partial<{ + headers: Record; +}>; +type Callback = (err?: any) => void; +export declare const download: = Res>(req: Request_1, res: Response_1) => (path: string, filename?: string | Callback, options?: DownloadOptions | Callback, cb?: Callback) => Response_1; +export declare const attachment: >(res: Response_1) => (filename?: string) => Response_1; +export {}; +//# sourceMappingURL=download.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/download.d.ts.map b/node_modules/@tinyhttp/res/dist/download.d.ts.map new file mode 100644 index 0000000..9825e5f --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/download.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,eAAe,IAAI,GAAG,EAAE,cAAc,IAAI,GAAG,EAAE,MAAM,WAAW,CAAA;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAErD,MAAM,MAAM,eAAe,GAAG,eAAe,GAC3C,OAAO,CAAC;IACN,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC,CAAC,CAAA;AAEJ,KAAK,QAAQ,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;AAEnC,eAAO,MAAM,QAAQ,mHAEZ,MAAM,aAAa,MAAM,GAAG,QAAQ,YAAY,eAAe,GAAG,QAAQ,OAAO,QAAQ,eAgC/F,CAAA;AAEH,eAAO,MAAM,UAAU,gEAET,MAAM,eASjB,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/format.d.ts b/node_modules/@tinyhttp/res/dist/format.d.ts new file mode 100644 index 0000000..a2a8b7a --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/format.d.ts @@ -0,0 +1,14 @@ +/// +import { IncomingMessage as Req, ServerResponse as Res } from 'node:http'; +export type FormatProps = { + default?: () => void; +} & Record; +export type FormatError = Error & { + status: number; + statusCode: number; + types: string[]; +}; +type next = (err?: FormatError) => void; +export declare const formatResponse: = Res, Next extends next = next>(req: Request_1, res: Response_1, next: Next) => (obj: FormatProps) => Response_1; +export {}; +//# sourceMappingURL=format.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/format.d.ts.map b/node_modules/@tinyhttp/res/dist/format.d.ts.map new file mode 100644 index 0000000..50049b2 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/format.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,IAAI,GAAG,EAAE,cAAc,IAAI,GAAG,EAAE,MAAM,WAAW,CAAA;AAKzE,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAEvB,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB,CAAA;AAED,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;AAEvC,eAAO,MAAM,cAAc,wJAMnB,WAAW,eAyBhB,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/headers.d.ts b/node_modules/@tinyhttp/res/dist/headers.d.ts new file mode 100644 index 0000000..81e3e4e --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/headers.d.ts @@ -0,0 +1,11 @@ +/// +import { IncomingMessage as Req, ServerResponse as Res } from 'node:http'; +export declare const setHeader: = Res>(res: Response_1) => (field: string | Record, val?: string | number | readonly string[]) => Response_1; +export declare const setLocationHeader: = Res>(req: Request_1, res: Response_1) => (url: string) => Response_1; +export declare const getResponseHeader: = Res>(res: Response_1) => (field: string) => string | number | string[]; +export declare const setLinksHeader: = Res>(res: Response_1) => (links: { + [key: string]: string; +}) => Response_1; +export declare const setVaryHeader: = Res>(res: Response_1) => (field: string) => Response_1; +export declare const setContentType: = Res>(res: Response_1) => (type: string) => Response_1; +//# sourceMappingURL=headers.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/headers.d.ts.map b/node_modules/@tinyhttp/res/dist/headers.d.ts.map new file mode 100644 index 0000000..4eb74f5 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/headers.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../src/headers.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,IAAI,GAAG,EAAE,cAAc,IAAI,GAAG,EAAE,MAAM,WAAW,CAAA;AAQzE,eAAO,MAAM,SAAS,uEAEZ,MAAM,GAAG,OAAO,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,MAAM,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,eAwBrG,CAAA;AAEH,eAAO,MAAM,iBAAiB,kHAEtB,MAAM,eASX,CAAA;AAEH,eAAO,MAAM,iBAAiB,uEAEpB,MAAM,KAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAExC,CAAA;AAEH,eAAO,MAAM,cAAc;;gBAcxB,CAAA;AAEH,eAAO,MAAM,aAAa,uEAEhB,MAAM,eAIb,CAAA;AAEH,eAAO,MAAM,cAAc,sEAElB,MAAM,eAMZ,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/index.d.ts b/node_modules/@tinyhttp/res/dist/index.d.ts new file mode 100644 index 0000000..c508d42 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/index.d.ts @@ -0,0 +1,9 @@ +export * from '@tinyhttp/send'; +export * from './cookie.js'; +export { setContentType, setHeader, setLinksHeader, setLocationHeader, setVaryHeader, getResponseHeader } from './headers.js'; +export type { FormatProps, FormatError } from './format.js'; +export { formatResponse } from './format.js'; +export { redirect } from './redirect.js'; +export * from './download.js'; +export { append } from './append.js'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/index.d.ts.map b/node_modules/@tinyhttp/res/dist/index.d.ts.map new file mode 100644 index 0000000..93c2505 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,OAAO,EACL,cAAc,EACd,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EAClB,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,cAAc,eAAe,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/index.js b/node_modules/@tinyhttp/res/dist/index.js new file mode 100644 index 0000000..9b2a9b7 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/index.js @@ -0,0 +1,207 @@ +import { sendFile } from "@tinyhttp/send"; +export * from "@tinyhttp/send"; +import * as cookie from "@tinyhttp/cookie"; +import { sign } from "@tinyhttp/cookie-signature"; +import mime from "mime"; +import { getRequestHeader, getAccepts } from "@tinyhttp/req"; +import { vary } from "@tinyhttp/vary"; +import { encodeUrl } from "@tinyhttp/encode-url"; +import { STATUS_CODES } from "node:http"; +import { escapeHTML } from "es-escape-html"; +import { contentDisposition } from "@tinyhttp/content-disposition"; +import { basename, resolve, extname } from "node:path"; +const charsetRegExp = /;\s*charset\s*=/; +const setHeader = (res) => (field, val) => { + if (typeof field === "string") { + let value = Array.isArray(val) ? val.map(String) : String(val); + if (field.toLowerCase() === "content-type") { + if (Array.isArray(value)) { + throw new TypeError("Content-Type cannot be set to an Array"); + } + if (!charsetRegExp.test(value)) { + const charset = "UTF-8"; + value += "; charset=" + charset.toLowerCase(); + } + } + res.setHeader(field, value); + } else { + for (const key in field) { + setHeader(res)(key, field[key]); + } + } + return res; +}; +const setLocationHeader = (req, res) => (url) => { + let loc = url; + if (url === "back") + loc = getRequestHeader(req)("Referrer") || "/"; + res.setHeader("Location", encodeUrl(loc)); + return res; +}; +const getResponseHeader = (res) => (field) => { + return res.getHeader(field); +}; +const setLinksHeader = (res) => (links) => { + let link = res.getHeader("Link") || ""; + if (link) + link += ", "; + res.setHeader( + "Link", + link + Object.keys(links).map((rel) => "<" + links[rel] + '>; rel="' + rel + '"').join(", ") + ); + return res; +}; +const setVaryHeader = (res) => (field) => { + vary(res, field); + return res; +}; +const setContentType = (res) => (type) => { + const ct = type.indexOf("/") === -1 ? mime.getType(type) : type; + setHeader(res)("Content-Type", ct); + return res; +}; +const append = (res) => (field, value) => { + const prevVal = getResponseHeader(res)(field); + let newVal = value; + if (prevVal && typeof newVal !== "number" && typeof prevVal !== "number") { + newVal = Array.isArray(prevVal) ? prevVal.concat(newVal) : Array.isArray(newVal) ? [prevVal].concat(newVal) : [prevVal, newVal]; + } + setHeader(res)(field, newVal); + return res; +}; +const setCookie = (req, res) => (name, value, options = {}) => { + const secret = req.secret; + const signed = options.signed || false; + if (signed && !secret) + throw new Error('cookieParser("secret") required for signed cookies'); + let val = typeof value === "object" ? "j:" + JSON.stringify(value) : String(value); + if (signed) + val = "s:" + sign(val, secret); + if (options.maxAge) { + options.expires = new Date(Date.now() + options.maxAge); + options.maxAge /= 1e3; + } + if (options.path == null) + options.path = "/"; + append(res)("Set-Cookie", `${cookie.serialize(name, String(val), options)}`); + return res; +}; +const clearCookie = (req, res) => (name, options) => { + return setCookie(req, res)(name, "", Object.assign({}, { expires: /* @__PURE__ */ new Date(1), path: "/" }, options)); +}; +const normalizeType = (type) => ~type.indexOf("/") ? acceptParams(type) : { value: mime.getType(type), params: {} }; +function acceptParams(str, index) { + const parts = str.split(/ *; */); + const ret = { value: parts[0], quality: 1, params: {}, originalIndex: index }; + for (const part of parts) { + const pms = part.split(/ *= */); + if ("q" === pms[0]) + ret.quality = parseFloat(pms[1]); + else + ret.params[pms[0]] = pms[1]; + } + return ret; +} +function normalizeTypes(types) { + const ret = []; + for (const type of types) { + ret.push(normalizeType(type)); + } + return ret; +} +const formatResponse = (req, res, next) => (obj) => { + const fn = obj.default; + if (fn) + delete obj.default; + const keys = Object.keys(obj); + const key = keys.length > 0 ? getAccepts(req)(...keys) : false; + setVaryHeader(res)("Accept"); + if (key) { + res.setHeader("Content-Type", normalizeType(key).value); + obj[key](req, res, next); + } else if (fn) { + fn(); + } else { + const err = new Error("Not Acceptable"); + err.status = err.statusCode = 406; + err.types = normalizeTypes(keys).map((o) => o.value); + next(err); + } + return res; +}; +const redirect = (req, res, next) => (url, status) => { + let address = url; + status = status || 302; + let body = ""; + address = setLocationHeader(req, res)(address).getHeader("Location"); + formatResponse( + req, + res, + next + )({ + text: () => { + body = STATUS_CODES[status] + ". Redirecting to " + address; + }, + html: () => { + const u = escapeHTML(address); + body = `

${STATUS_CODES[status]}. Redirecting to ${u}

`; + }, + default: () => { + body = ""; + } + }); + res.setHeader("Content-Length", Buffer.byteLength(body)); + res.statusCode = status; + if (req.method === "HEAD") + res.end(); + else + res.end(body); + return res; +}; +const download = (req, res) => (path, filename, options, cb) => { + let done = cb; + let name = filename; + let opts = options || null; + if (typeof filename === "function") { + done = filename; + name = null; + } else if (typeof options === "function") { + done = options; + opts = null; + } + const headers = { + "Content-Disposition": contentDisposition(name || basename(path)) + }; + if (opts && opts.headers) { + for (const key of Object.keys(opts.headers)) { + if (key.toLowerCase() !== "content-disposition") + headers[key] = opts.headers[key]; + } + } + opts = { ...opts, headers }; + return sendFile(req, res)(opts.root ? path : resolve(path), opts, done || (() => void 0)); +}; +const attachment = (res) => (filename) => { + if (filename) { + setContentType(res)(extname(filename)); + filename = basename(filename); + } + setHeader(res)("Content-Disposition", contentDisposition(filename)); + return res; +}; +export { + append, + attachment, + clearCookie, + download, + formatResponse, + getResponseHeader, + redirect, + setContentType, + setCookie, + setHeader, + setLinksHeader, + setLocationHeader, + setVaryHeader +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/res/dist/index.js.map b/node_modules/@tinyhttp/res/dist/index.js.map new file mode 100644 index 0000000..9b4ca76 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/headers.ts","../src/append.ts","../src/cookie.ts","../src/util.ts","../src/format.ts","../src/redirect.ts","../src/download.ts"],"sourcesContent":["import { IncomingMessage as Req, ServerResponse as Res } from 'node:http'\nimport mime from 'mime'\nimport { getRequestHeader } from '@tinyhttp/req'\nimport { vary } from '@tinyhttp/vary'\nimport { encodeUrl } from '@tinyhttp/encode-url'\n\nconst charsetRegExp = /;\\s*charset\\s*=/\n\nexport const setHeader =\n (res: Response) =>\n (field: string | Record, val?: string | number | readonly string[]): Response => {\n if (typeof field === 'string') {\n let value = Array.isArray(val) ? val.map(String) : String(val)\n\n // add charset to content-type\n if (field.toLowerCase() === 'content-type') {\n if (Array.isArray(value)) {\n throw new TypeError('Content-Type cannot be set to an Array')\n }\n\n if (!charsetRegExp.test(value)) {\n const charset = 'UTF-8' // UTF-8 is the default charset for all types\n\n if (typeof charset === 'string') value += '; charset=' + charset.toLowerCase()\n }\n }\n\n res.setHeader(field, value)\n } else {\n for (const key in field) {\n setHeader(res)(key, field[key] as string)\n }\n }\n return res\n }\n\nexport const setLocationHeader =\n (req: Request, res: Response) =>\n (url: string): Response => {\n let loc = url\n\n // \"back\" is an alias for the referrer\n if (url === 'back') loc = (getRequestHeader(req)('Referrer') as string) || '/'\n\n // set location\n res.setHeader('Location', encodeUrl(loc))\n return res\n }\n\nexport const getResponseHeader =\n (res: Response) =>\n (field: string): string | number | string[] => {\n return res.getHeader(field)\n }\n\nexport const setLinksHeader =\n (res: Response) =>\n (links: { [key: string]: string }): Response => {\n let link = res.getHeader('Link') || ''\n if (link) link += ', '\n res.setHeader(\n 'Link',\n link +\n Object.keys(links)\n .map((rel) => '<' + links[rel] + '>; rel=\"' + rel + '\"')\n .join(', ')\n )\n\n return res\n }\n\nexport const setVaryHeader =\n (res: Response) =>\n (field: string): Response => {\n vary(res, field)\n\n return res\n }\n\nexport const setContentType =\n (res: Response) =>\n (type: string): Response => {\n const ct = type.indexOf('/') === -1 ? mime.getType(type) : type\n\n setHeader(res)('Content-Type', ct)\n\n return res\n }\n","import { ServerResponse as Res } from 'node:http'\nimport { getResponseHeader, setHeader } from './headers.js'\n\nexport const append =\n (res: Response) =>\n (field: string, value: string | number | string[]): Response => {\n const prevVal = getResponseHeader(res)(field)\n let newVal = value\n\n if (prevVal && typeof newVal !== 'number' && typeof prevVal !== 'number') {\n newVal = Array.isArray(prevVal)\n ? prevVal.concat(newVal)\n : Array.isArray(newVal)\n ? [prevVal].concat(newVal)\n : [prevVal, newVal]\n }\n setHeader(res)(field, newVal)\n return res\n }\n","import { IncomingMessage as Req, ServerResponse as Res } from 'node:http'\nimport * as cookie from '@tinyhttp/cookie'\nimport { sign } from '@tinyhttp/cookie-signature'\nimport { append } from './append.js'\n\nexport const setCookie =\n (\n req: Request & {\n secret?: string | string[]\n },\n res: Response\n ) =>\n (\n name: string,\n value: string | Record,\n options: cookie.SerializeOptions &\n Partial<{\n signed: boolean\n }> = {}\n ): Response => {\n const secret = req.secret as string\n\n const signed = options.signed || false\n\n if (signed && !secret) throw new Error('cookieParser(\"secret\") required for signed cookies')\n\n let val = typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value)\n\n if (signed) val = 's:' + sign(val, secret)\n\n if (options.maxAge) {\n options.expires = new Date(Date.now() + options.maxAge)\n options.maxAge /= 1000\n }\n\n if (options.path == null) options.path = '/'\n\n append(res)('Set-Cookie', `${cookie.serialize(name, String(val), options)}`)\n\n return res\n }\n\nexport const clearCookie =\n (req: Request, res: Response) =>\n (name: string, options?: cookie.SerializeOptions): Response => {\n return setCookie(req, res)(name, '', Object.assign({}, { expires: new Date(1), path: '/' }, options))\n }\n","import mime from 'mime'\n\nexport type NormalizedType = {\n value: string\n quality?: number\n params: Record\n originalIndex?: number\n}\n\nexport const normalizeType = (type: string): NormalizedType =>\n ~type.indexOf('/') ? acceptParams(type) : { value: mime.getType(type), params: {} }\n\nexport function acceptParams(str: string, index?: number): NormalizedType {\n const parts = str.split(/ *; */)\n const ret: NormalizedType = { value: parts[0], quality: 1, params: {}, originalIndex: index }\n\n for (const part of parts) {\n const pms = part.split(/ *= */)\n if ('q' === pms[0]) ret.quality = parseFloat(pms[1])\n else ret.params[pms[0]] = pms[1]\n }\n\n return ret\n}\n\nexport function normalizeTypes(types: string[]): NormalizedType[] {\n const ret: NormalizedType[] = []\n\n for (const type of types) {\n ret.push(normalizeType(type))\n }\n\n return ret\n}\n","import { IncomingMessage as Req, ServerResponse as Res } from 'node:http'\nimport { getAccepts } from '@tinyhttp/req'\nimport { setVaryHeader } from './headers.js'\nimport { normalizeType, normalizeTypes } from './util.js'\n\nexport type FormatProps = {\n default?: () => void\n} & Record\n\nexport type FormatError = Error & {\n status: number\n statusCode: number\n types: string[]\n}\n\ntype next = (err?: FormatError) => void\n\nexport const formatResponse =\n (\n req: Request,\n res: Response,\n next: Next\n ) =>\n (obj: FormatProps): Response => {\n const fn = obj.default\n\n if (fn) delete obj.default\n\n const keys = Object.keys(obj)\n\n const key = keys.length > 0 ? (getAccepts(req)(...keys) as string) : false\n\n setVaryHeader(res)('Accept')\n\n if (key) {\n res.setHeader('Content-Type', normalizeType(key).value)\n obj[key](req, res, next)\n } else if (fn) {\n fn()\n } else {\n const err = new Error('Not Acceptable') as FormatError\n err.status = err.statusCode = 406\n err.types = normalizeTypes(keys).map((o) => o.value)\n\n next(err)\n }\n\n return res\n }\n","import { IncomingMessage as Req, ServerResponse as Res, STATUS_CODES } from 'node:http'\nimport { escapeHTML } from 'es-escape-html'\nimport { formatResponse } from './format.js'\nimport { setLocationHeader } from './headers.js'\n\ntype next = (err?: any) => void\n\nexport const redirect =\n (\n req: Request,\n res: Response,\n next: Next\n ) =>\n (url: string, status?: number): Response => {\n let address = url\n status = status || 302\n\n let body = ''\n\n address = setLocationHeader(req, res)(address).getHeader('Location') as string\n\n formatResponse(\n req,\n res,\n next\n )({\n text: () => {\n body = STATUS_CODES[status] + '. Redirecting to ' + address\n },\n html: () => {\n const u = escapeHTML(address)\n\n body = `

${STATUS_CODES[status]}. Redirecting to ${u}

`\n },\n default: () => {\n body = ''\n }\n })\n\n res.setHeader('Content-Length', Buffer.byteLength(body))\n\n res.statusCode = status\n\n if (req.method === 'HEAD') res.end()\n else res.end(body)\n\n return res\n }\n","import { contentDisposition } from '@tinyhttp/content-disposition'\nimport { sendFile } from '@tinyhttp/send'\nimport { extname, resolve, basename } from 'node:path'\nimport { IncomingMessage as Req, ServerResponse as Res } from 'node:http'\nimport { setContentType, setHeader } from './headers.js'\nimport type { SendFileOptions } from '@tinyhttp/send'\n\nexport type DownloadOptions = SendFileOptions &\n Partial<{\n headers: Record\n }>\n\ntype Callback = (err?: any) => void\n\nexport const download =\n (req: Request, res: Response) =>\n (path: string, filename?: string | Callback, options?: DownloadOptions | Callback, cb?: Callback): Response => {\n let done = cb\n let name = filename as string\n let opts = (options || null) as DownloadOptions\n\n // support function as second or third arg\n if (typeof filename === 'function') {\n done = filename\n name = null\n } else if (typeof options === 'function') {\n done = options\n opts = null\n }\n\n // set Content-Disposition when file is sent\n const headers = {\n 'Content-Disposition': contentDisposition(name || basename(path))\n }\n\n // merge user-provided headers\n if (opts && opts.headers) {\n for (const key of Object.keys(opts.headers)) {\n if (key.toLowerCase() !== 'content-disposition') headers[key] = opts.headers[key]\n }\n }\n\n // merge user-provided options\n opts = { ...opts, headers }\n\n // send file\n\n return sendFile(req, res)(opts.root ? path : resolve(path), opts, done || (() => undefined))\n }\n\nexport const attachment =\n (res: Response) =>\n (filename?: string): Response => {\n if (filename) {\n setContentType(res)(extname(filename))\n filename = basename(filename)\n }\n\n setHeader(res)('Content-Disposition', contentDisposition(filename))\n\n return res\n }\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/redirect.d.ts b/node_modules/@tinyhttp/res/dist/redirect.d.ts new file mode 100644 index 0000000..3aa47b1 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/redirect.d.ts @@ -0,0 +1,6 @@ +/// +import { IncomingMessage as Req, ServerResponse as Res } from 'node:http'; +type next = (err?: any) => void; +export declare const redirect: = Res, Next extends next = next>(req: Request_1, res: Response_1, next: Next) => (url: string, status?: number) => Response_1; +export {}; +//# sourceMappingURL=redirect.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/redirect.d.ts.map b/node_modules/@tinyhttp/res/dist/redirect.d.ts.map new file mode 100644 index 0000000..ce58803 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/redirect.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"redirect.d.ts","sourceRoot":"","sources":["../src/redirect.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,IAAI,GAAG,EAAE,cAAc,IAAI,GAAG,EAAgB,MAAM,WAAW,CAAA;AAKvF,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;AAE/B,eAAO,MAAM,QAAQ,wJAMb,MAAM,WAAW,MAAM,eAkC5B,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/util.d.ts b/node_modules/@tinyhttp/res/dist/util.d.ts new file mode 100644 index 0000000..a5de9e8 --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/util.d.ts @@ -0,0 +1,10 @@ +export type NormalizedType = { + value: string; + quality?: number; + params: Record; + originalIndex?: number; +}; +export declare const normalizeType: (type: string) => NormalizedType; +export declare function acceptParams(str: string, index?: number): NormalizedType; +export declare function normalizeTypes(types: string[]): NormalizedType[]; +//# sourceMappingURL=util.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/dist/util.d.ts.map b/node_modules/@tinyhttp/res/dist/util.d.ts.map new file mode 100644 index 0000000..d71860e --- /dev/null +++ b/node_modules/@tinyhttp/res/dist/util.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,aAAa,SAAU,MAAM,KAAG,cACwC,CAAA;AAErF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,cAAc,CAWxE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAQhE"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/res/package.json b/node_modules/@tinyhttp/res/package.json new file mode 100644 index 0000000..9352fac --- /dev/null +++ b/node_modules/@tinyhttp/res/package.json @@ -0,0 +1,45 @@ +{ + "name": "@tinyhttp/res", + "version": "2.2.2", + "type": "module", + "description": "response extensions for tinyhttp", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/res" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "res" + ], + "engines": { + "node": ">=12.20.0" + }, + "author": "v1rtl", + "license": "MIT", + "dependencies": { + "@tinyhttp/vary": "^0.1.3", + "es-escape-html": "^0.1.1", + "mime": "4.0.1", + "@tinyhttp/cookie": "2.1.0", + "@tinyhttp/send": "2.2.1", + "@tinyhttp/cookie-signature": "2.1.0", + "@tinyhttp/req": "2.2.2", + "@tinyhttp/content-disposition": "2.2.0", + "@tinyhttp/encode-url": "2.1.1" + }, + "files": [ + "dist" + ], + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/router/LICENSE b/node_modules/@tinyhttp/router/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/router/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/router/README.md b/node_modules/@tinyhttp/router/README.md new file mode 100644 index 0000000..4107414 --- /dev/null +++ b/node_modules/@tinyhttp/router/README.md @@ -0,0 +1,26 @@ +# @tinyhttp/router + +[![npm (scoped)][npm-badge]](https://npmjs.com/package/@tinyhttp/router) [![npm][dl-badge]](https://npmjs.com/package/@tinyhttp/router) + +Framework-agnostic HTTP router. + +## Install + +```sh +pnpm i @tinyhttp/router +``` + +## Example + +```js +import { Router } from '@tinyhttp/router' + +const router = new Router() + +router.get('/', (req, res) => res.send('Hello World')) + +console.log(router.middleware) +``` + +[npm-badge]: https://img.shields.io/npm/v/@tinyhttp/router?style=flat-square +[dl-badge]: https://img.shields.io/npm/dt/@tinyhttp/router?style=flat-square diff --git a/node_modules/@tinyhttp/router/dist/index.d.ts b/node_modules/@tinyhttp/router/dist/index.d.ts new file mode 100644 index 0000000..f8bfb95 --- /dev/null +++ b/node_modules/@tinyhttp/router/dist/index.d.ts @@ -0,0 +1,95 @@ +export type NextFunction = (err?: any) => void; +export type SyncHandler = (req: Request, res: Response, next: NextFunction) => void; +export type AsyncHandler = (req: Request, res: Response, next: NextFunction) => Promise; +export type Handler = AsyncHandler | SyncHandler; +declare const METHODS: readonly ["ACL", "BIND", "CHECKOUT", "CONNECT", "COPY", "DELETE", "GET", "HEAD", "LINK", "LOCK", "M-SEARCH", "MERGE", "MKACTIVITY", "MKCALENDAR", "MKCOL", "MOVE", "NOTIFY", "OPTIONS", "PATCH", "POST", "PRI", "PROPFIND", "PROPPATCH", "PURGE", "PUT", "REBIND", "REPORT", "SEARCH", "SOURCE", "SUBSCRIBE", "TRACE", "UNBIND", "UNLINK", "UNLOCK", "UNSUBSCRIBE"]; +export type Method = (typeof METHODS)[number]; +export type MiddlewareType = 'mw' | 'route'; +type RegexParams = { + keys: string[] | false; + pattern: RegExp; +}; +type RIM = (...args: RouterMethodParams) => App; +export interface Middleware { + method?: Method; + handler: Handler; + path?: string; + type: MiddlewareType; + regex?: RegexParams; + fullPath?: string; +} +export type MethodHandler = { + path?: string | string[] | Handler; + handler?: Handler; + type: MiddlewareType; + regex?: RegexParams; + fullPath?: string; +}; +export type RouterHandler = Handler | Handler[] | string[]; +export type RouterPathOrHandler = string | RouterHandler; +export type RouterMethod = (path: string | string[] | Handler, handler?: RouterHandler, ...handlers: RouterHandler[]) => any; +type RouterMethodParams = Parameters>; +export type UseMethod = (path: RouterPathOrHandler | App, handler?: RouterHandler | App, ...handlers: (RouterHandler | App)[]) => any; +export type UseMethodParams = Parameters>; +/** + * Push wares to a middleware array + * @param mw Middleware arrays + */ +export declare const pushMiddleware: (mw: Middleware[]) => ({ path, handler, method, handlers, type, fullPaths }: MethodHandler & { + method?: Method; + handlers?: RouterHandler[]; + fullPaths?: string[]; +}) => void; +/** + * tinyhttp Router. Manages middleware and has HTTP methods aliases, e.g. `app.get`, `app.put` + */ +export declare class Router { + middleware: Middleware[]; + mountpath: string; + parent: App; + apps: Record; + acl: RIM; + bind: RIM; + checkout: RIM; + connect: RIM; + copy: RIM; + delete: RIM; + get: RIM; + head: RIM; + link: RIM; + lock: RIM; + merge: RIM; + mkactivity: RIM; + mkcalendar: RIM; + mkcol: RIM; + move: RIM; + notify: RIM; + options: RIM; + patch: RIM; + post: RIM; + pri: RIM; + propfind: RIM; + proppatch: RIM; + purge: RIM; + put: RIM; + rebind: RIM; + report: RIM; + search: RIM; + source: RIM; + subscribe: RIM; + trace: RIM; + unbind: RIM; + unlink: RIM; + unlock: RIM; + unsubscribe: RIM; + constructor(); + add(method: Method): (path: string | string[] | Handler, handler?: RouterHandler, ...handlers: RouterHandler[]) => this; + msearch(...args: RouterMethodParams): this; + all(...args: RouterMethodParams): this; + /** + * Push middleware to the stack + */ + use(...args: UseMethodParams): this; +} +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/router/dist/index.d.ts.map b/node_modules/@tinyhttp/router/dist/index.d.ts.map new file mode 100644 index 0000000..2053556 --- /dev/null +++ b/node_modules/@tinyhttp/router/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;AAE9C,MAAM,MAAM,WAAW,CAAC,OAAO,GAAG,GAAG,EAAE,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;AAElH,MAAM,MAAM,YAAY,CAAC,OAAO,GAAG,GAAG,EAAE,QAAQ,GAAG,GAAG,IAAI,CACxD,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,KACf,OAAO,CAAC,IAAI,CAAC,CAAA;AAElB,MAAM,MAAM,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,QAAQ,GAAG,GAAG,IAAI,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;AAErH,QAAA,MAAM,OAAO,qWAoCH,CAAA;AAEV,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA;AAE7C,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,OAAO,CAAA;AAE3C,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,KAAK,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,GAAG,CAAA;AAExE,MAAM,WAAW,UAAU,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,aAAa,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI;IAChD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC3B,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,aAAa,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,MAAM,EAAE,CAAA;AAEpG,MAAM,MAAM,mBAAmB,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;AAExF,MAAM,MAAM,YAAY,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,CAC/C,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAC3C,OAAO,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EACjC,GAAG,QAAQ,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,KACnC,GAAG,CAAA;AAER,KAAK,kBAAkB,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;AAElF,MAAM,MAAM,SAAS,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,SAAS,MAAM,GAAG,GAAG,IAAI,CACtE,IAAI,EAAE,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,EACzC,OAAO,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,EACvC,GAAG,QAAQ,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,EAAE,KAC3C,GAAG,CAAA;AAER,MAAM,MAAM,eAAe,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,SAAS,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;AAkBlH;;;GAGG;AACH,eAAO,MAAM,cAAc,6BACE,UAAU,EAAE;aAS5B,MAAM;;gBAEH,MAAM,EAAE;MAClB,IAmBH,CAAA;AAEH;;GAEG;AACH,qBAAa,MAAM,CAAC,GAAG,SAAS,MAAM,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG;IAChE,UAAU,EAAE,UAAU,EAAE,CAAK;IAC7B,SAAS,SAAM;IACf,MAAM,EAAE,GAAG,CAAA;IACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAK;IAE9B,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACxB,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACzB,QAAQ,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC7B,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC5B,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACzB,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC3B,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACxB,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACzB,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACzB,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACzB,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC1B,UAAU,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC/B,UAAU,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC/B,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC1B,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACzB,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC3B,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC5B,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC1B,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACzB,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACxB,QAAQ,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC7B,SAAS,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9B,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC1B,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACxB,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC3B,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC3B,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC3B,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC3B,SAAS,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9B,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC1B,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC3B,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC3B,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC3B,WAAW,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;;IAQhC,GAAG,CAAC,MAAM,EAAE,MAAM,+HACgC,IAAI;IA4BtD,OAAO,CAAC,GAAG,IAAI,EAAE,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI;IAcpD,GAAG,CAAC,GAAG,IAAI,EAAE,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI;IAahD;;OAEG;IACH,GAAG,CAAC,GAAG,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI;CAyBnD"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/router/dist/index.js b/node_modules/@tinyhttp/router/dist/index.js new file mode 100644 index 0000000..4dbbbd2 --- /dev/null +++ b/node_modules/@tinyhttp/router/dist/index.js @@ -0,0 +1,159 @@ +const METHODS = [ + "ACL", + "BIND", + "CHECKOUT", + "CONNECT", + "COPY", + "DELETE", + "GET", + "HEAD", + "LINK", + "LOCK", + "M-SEARCH", + "MERGE", + "MKACTIVITY", + "MKCALENDAR", + "MKCOL", + "MOVE", + "NOTIFY", + "OPTIONS", + "PATCH", + "POST", + "PRI", + "PROPFIND", + "PROPPATCH", + "PURGE", + "PUT", + "REBIND", + "REPORT", + "SEARCH", + "SOURCE", + "SUBSCRIBE", + "TRACE", + "UNBIND", + "UNLINK", + "UNLOCK", + "UNSUBSCRIBE" +]; +const createMiddlewareFromRoute = ({ + path, + handler, + fullPath, + method +}) => ({ + method, + handler: handler || path, + path: typeof path === "string" ? path : "/", + fullPath: typeof path === "string" ? fullPath : path +}); +const pushMiddleware = (mw) => ({ + path, + handler, + method, + handlers, + type, + fullPaths +}) => { + const m = createMiddlewareFromRoute({ path, handler, method, type, fullPath: fullPaths == null ? void 0 : fullPaths[0] }); + let waresFromHandlers = []; + let idx = 1; + if (handlers) { + waresFromHandlers = handlers.flat().map( + (handler2) => createMiddlewareFromRoute({ + path, + handler: handler2, + method, + type, + fullPath: fullPaths == null ? null : fullPaths[idx++] + }) + ); + } + for (const mdw of [m, ...waresFromHandlers]) + mw.push({ ...mdw, type }); +}; +class Router { + constructor() { + this.middleware = []; + this.mountpath = "/"; + this.apps = {}; + for (const m of METHODS) { + this[m.toLowerCase()] = this.add(m); + } + } + add(method) { + return (...args) => { + const handlers = args.slice(1).flat(); + if (Array.isArray(args[0])) { + Object.values(args[0]).forEach((arg) => { + if (typeof arg == "string") { + pushMiddleware(this.middleware)({ + path: arg, + handler: handlers[0], + handlers: handlers.slice(1), + method, + type: "route" + }); + } + }); + } else { + pushMiddleware(this.middleware)({ + path: args[0], + handler: handlers[0], + handlers: handlers.slice(1), + method, + type: "route" + }); + } + return this; + }; + } + msearch(...args) { + const handlers = args.slice(1).flat(); + pushMiddleware(this.middleware)({ + path: args[0], + handler: handlers[0], + handlers: handlers.slice(1), + method: "M-SEARCH", + type: "route" + }); + return this; + } + all(...args) { + const handlers = args.slice(1).flat(); + pushMiddleware(this.middleware)({ + path: args[0], + handler: handlers[0], + handlers: handlers.slice(1), + type: "route" + }); + return this; + } + /** + * Push middleware to the stack + */ + use(...args) { + const base = args[0]; + const handlers = args.slice(1).flat(); + if (typeof base === "string") { + pushMiddleware(this.middleware)({ + path: base, + handler: handlers[0], + handlers: handlers.slice(1), + type: "mw" + }); + } else { + pushMiddleware(this.middleware)({ + path: "/", + handler: Array.isArray(base) ? base[0] : base, + handlers: Array.isArray(base) ? [...base.slice(1), ...handlers] : handlers, + type: "mw" + }); + } + return this; + } +} +export { + Router, + pushMiddleware +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/router/dist/index.js.map b/node_modules/@tinyhttp/router/dist/index.js.map new file mode 100644 index 0000000..7f5a7a0 --- /dev/null +++ b/node_modules/@tinyhttp/router/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* HELPER TYPES */\n\nexport type NextFunction = (err?: any) => void\n\nexport type SyncHandler = (req: Request, res: Response, next: NextFunction) => void\n\nexport type AsyncHandler = (\n req: Request,\n res: Response,\n next: NextFunction\n) => Promise\n\nexport type Handler = AsyncHandler | SyncHandler\n\nconst METHODS = [\n 'ACL',\n 'BIND',\n 'CHECKOUT',\n 'CONNECT',\n 'COPY',\n 'DELETE',\n 'GET',\n 'HEAD',\n 'LINK',\n 'LOCK',\n 'M-SEARCH',\n 'MERGE',\n 'MKACTIVITY',\n 'MKCALENDAR',\n 'MKCOL',\n 'MOVE',\n 'NOTIFY',\n 'OPTIONS',\n 'PATCH',\n 'POST',\n 'PRI',\n 'PROPFIND',\n 'PROPPATCH',\n 'PURGE',\n 'PUT',\n 'REBIND',\n 'REPORT',\n 'SEARCH',\n 'SOURCE',\n 'SUBSCRIBE',\n 'TRACE',\n 'UNBIND',\n 'UNLINK',\n 'UNLOCK',\n 'UNSUBSCRIBE'\n] as const\n\nexport type Method = (typeof METHODS)[number]\n\nexport type MiddlewareType = 'mw' | 'route'\n\ntype RegexParams = {\n keys: string[] | false\n pattern: RegExp\n}\n\ntype RIM = (...args: RouterMethodParams) => App\n\nexport interface Middleware {\n method?: Method\n handler: Handler\n path?: string\n type: MiddlewareType\n regex?: RegexParams\n fullPath?: string\n}\n\nexport type MethodHandler = {\n path?: string | string[] | Handler\n handler?: Handler\n type: MiddlewareType\n regex?: RegexParams\n fullPath?: string\n}\n\nexport type RouterHandler = Handler | Handler[] | string[]\n\nexport type RouterPathOrHandler = string | RouterHandler\n\nexport type RouterMethod = (\n path: string | string[] | Handler,\n handler?: RouterHandler,\n ...handlers: RouterHandler[]\n) => any\n\ntype RouterMethodParams = Parameters>\n\nexport type UseMethod = (\n path: RouterPathOrHandler | App,\n handler?: RouterHandler | App,\n ...handlers: (RouterHandler | App)[]\n) => any\n\nexport type UseMethodParams = Parameters>\n\n/** HELPER METHODS */\n\nconst createMiddlewareFromRoute = ({\n path,\n handler,\n fullPath,\n method\n}: MethodHandler & {\n method?: Method\n}) => ({\n method,\n handler: handler || (path as Handler),\n path: typeof path === 'string' ? path : '/',\n fullPath: typeof path === 'string' ? fullPath : path\n})\n\n/**\n * Push wares to a middleware array\n * @param mw Middleware arrays\n */\nexport const pushMiddleware =\n (mw: Middleware[]) =>\n ({\n path,\n handler,\n method,\n handlers,\n type,\n fullPaths\n }: MethodHandler & {\n method?: Method\n handlers?: RouterHandler[]\n fullPaths?: string[]\n }): void => {\n const m = createMiddlewareFromRoute({ path, handler, method, type, fullPath: fullPaths?.[0] })\n\n let waresFromHandlers: { handler: Handler }[] = []\n let idx = 1\n\n if (handlers) {\n waresFromHandlers = handlers.flat().map((handler) =>\n createMiddlewareFromRoute({\n path,\n handler: handler as Handler,\n method,\n type,\n fullPath: fullPaths == null ? null : fullPaths[idx++]\n })\n )\n }\n\n for (const mdw of [m, ...waresFromHandlers]) mw.push({ ...mdw, type })\n }\n\n/**\n * tinyhttp Router. Manages middleware and has HTTP methods aliases, e.g. `app.get`, `app.put`\n */\nexport class Router {\n middleware: Middleware[] = []\n mountpath = '/'\n parent: App\n apps: Record = {}\n\n acl: RIM\n bind: RIM\n checkout: RIM\n connect: RIM\n copy: RIM\n delete: RIM\n get: RIM\n head: RIM\n link: RIM\n lock: RIM\n merge: RIM\n mkactivity: RIM\n mkcalendar: RIM\n mkcol: RIM\n move: RIM\n notify: RIM\n options: RIM\n patch: RIM\n post: RIM\n pri: RIM\n propfind: RIM\n proppatch: RIM\n purge: RIM\n put: RIM\n rebind: RIM\n report: RIM\n search: RIM\n source: RIM\n subscribe: RIM\n trace: RIM\n unbind: RIM\n unlink: RIM\n unlock: RIM\n unsubscribe: RIM\n\n constructor() {\n for (const m of METHODS) {\n this[m.toLowerCase()] = this.add(m as Method)\n }\n }\n\n add(method: Method) {\n return (...args: RouterMethodParams): this => {\n const handlers = args.slice(1).flat() as Handler[]\n if (Array.isArray(args[0])) {\n Object.values(args[0]).forEach((arg) => {\n if (typeof arg == 'string') {\n pushMiddleware(this.middleware)({\n path: arg,\n handler: handlers[0],\n handlers: handlers.slice(1),\n method,\n type: 'route'\n })\n }\n })\n } else {\n pushMiddleware(this.middleware)({\n path: args[0],\n handler: handlers[0],\n handlers: handlers.slice(1),\n method,\n type: 'route'\n })\n }\n\n return this\n }\n }\n\n msearch(...args: RouterMethodParams): this {\n const handlers = args.slice(1).flat() as Handler[]\n\n pushMiddleware(this.middleware)({\n path: args[0],\n handler: handlers[0],\n handlers: handlers.slice(1),\n method: 'M-SEARCH',\n type: 'route'\n })\n\n return this\n }\n\n all(...args: RouterMethodParams): this {\n const handlers = args.slice(1).flat() as Handler[]\n\n pushMiddleware(this.middleware)({\n path: args[0],\n handler: handlers[0],\n handlers: handlers.slice(1),\n type: 'route'\n })\n\n return this\n }\n\n /**\n * Push middleware to the stack\n */\n use(...args: UseMethodParams): this {\n const base = args[0]\n\n const handlers = args.slice(1).flat()\n\n if (typeof base === 'string') {\n pushMiddleware(this.middleware)({\n path: base,\n handler: handlers[0] as Handler,\n handlers: handlers.slice(1) as Handler[],\n type: 'mw'\n })\n } else {\n pushMiddleware(this.middleware)({\n path: '/',\n handler: Array.isArray(base) ? (base[0] as Handler) : (base as Handler),\n handlers: Array.isArray(base)\n ? [...(base.slice(1) as Handler[]), ...(handlers as Handler[])]\n : (handlers as Handler[]),\n type: 'mw'\n })\n }\n\n return this\n }\n}\n"],"names":["handler"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/router/package.json b/node_modules/@tinyhttp/router/package.json new file mode 100644 index 0000000..c79d51f --- /dev/null +++ b/node_modules/@tinyhttp/router/package.json @@ -0,0 +1,34 @@ +{ + "name": "@tinyhttp/router", + "version": "2.2.2", + "type": "module", + "description": "Router for tinyhttp", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/router" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "router" + ], + "engines": { + "node": ">=12.20.0" + }, + "author": "v1rtl", + "license": "MIT", + "files": [ + "dist" + ], + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/LICENSE b/node_modules/@tinyhttp/send/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/send/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/send/README.md b/node_modules/@tinyhttp/send/README.md new file mode 100644 index 0000000..596d044 --- /dev/null +++ b/node_modules/@tinyhttp/send/README.md @@ -0,0 +1,110 @@ +# @tinyhttp/send + +[![npm (scoped)][npm-badge]](https://npmjs.com/package/@tinyhttp/send) +[![npm][dl-badge]](https://npmjs.com/package/@tinyhttp/send) +[![][web-badge]](https://tinyhttp.v1rtl.site/mw/send) + +Extensions for sending a response, including `send`, `sendStatus`, `status`, +`sendFile` and `json`. Works with any backend framework. + +## Install + +```sh +pnpm i @tinyhttp/send +``` + +## API + +```js +import { json, send, sendStatus, status } from '@tinyhttp/send' +``` + +### `send(body)` [![][doc-badge]](https://tinyhttp.v1rtl.site/docs#ressend) + +Sends the HTTP response. + +The body parameter can be a Buffer object, a string, an object, or an array. + +##### Example + +```ts +res.send(Buffer.from('whoop')) +res.send({ some: 'json' }) +res.send('

some html

') +res.status(404).send('Sorry, we cannot find that!') +res.status(500).send({ error: 'something blew up' }) +``` + +### `json(body)` [![][doc-badge]](https://tinyhttp.v1rtl.site/docs#resjson) + +Sends a JSON response. This method sends a response (with the correct +content-type) that is the parameter converted to a JSON string using +[`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). + +The parameter can be any JSON type, including object, array, string, boolean, +number, or null, and you can also use it to convert other values to JSON. + +##### Example + +```ts +res.json(null) +res.json({ user: 'tobi' }) +res.status(500).json({ error: 'message' }) +``` + +### `status(number)` [![][doc-badge]](https://tinyhttp.v1rtl.site/docs#resstatus) + +Sets the HTTP status for the response. It is a chainable alias of Node’s +`response.statusCode`. + +##### Example + +```ts +res.status(403).end() +res.status(400).send('Bad Request') +``` + +### `sendStatus` [![][doc-badge]](https://tinyhttp.v1rtl.site/docs#ressendstatus) + +Sets the response HTTP status code to statusCode and send its string +representation as the response body. + +##### Example + +```ts +res.sendStatus(200) // equivalent to res.status(200).send('OK') +res.sendStatus(403) // equivalent to res.status(403).send('Forbidden') +res.sendStatus(404) // equivalent to res.status(404).send('Not Found') +res.sendStatus(500) // equivalent to res.status(500).send('Internal Server Error') +``` + +If an unsupported status code is specified, the HTTP status is still set to +statusCode and the string version of the code is sent as the response body. + +### `sendFile` [![][doc-badge]](https://tinyhttp.v1rtl.site/docs#ressendfile) + +Sends a file by piping a stream to response. It also checks for extension to set +a proper `Content-Type` header. + +> Path argument must be absolute. To use a relative path, specify the `root` +> option first. + +##### Example + +```js +res.sendFile('song.mp3', { root: process.cwd() }, (err) => console.log(err)) +``` + +## Example + +```js +import { createServer } from 'node:http' +import { send } from '@tinyhttp/send' + +createServer((req, res) => send(req, res)('Hello World')).listen(3000) +``` + +[npm-badge]: https://img.shields.io/npm/v/@tinyhttp/send?style=flat-square +[dl-badge]: https://img.shields.io/npm/dt/@tinyhttp/send?style=flat-square +[web-badge]: https://img.shields.io/badge/website-visit-hotpink?style=flat-square +[doc-badge]: https://img.shields.io/badge/-docs-hotpink?style=flat-square diff --git a/node_modules/@tinyhttp/send/dist/index.d.ts b/node_modules/@tinyhttp/send/dist/index.d.ts new file mode 100644 index 0000000..9149ca3 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/index.d.ts @@ -0,0 +1,6 @@ +export * from './json.js'; +export * from './send.js'; +export * from './sendStatus.js'; +export * from './status.js'; +export * from './sendFile.js'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/index.d.ts.map b/node_modules/@tinyhttp/send/dist/index.d.ts.map new file mode 100644 index 0000000..f71d685 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/index.js b/node_modules/@tinyhttp/send/dist/index.js new file mode 100644 index 0000000..d0ee03f --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/index.js @@ -0,0 +1,146 @@ +import { parse, format } from "@tinyhttp/content-type"; +import { eTag } from "@tinyhttp/etag"; +import { Stats, statSync, createReadStream } from "node:fs"; +import { STATUS_CODES } from "node:http"; +import { isAbsolute, join, extname } from "node:path"; +import mime from "mime"; +const json = (res) => (body, ...args) => { + res.setHeader("Content-Type", "application/json"); + if (typeof body === "object" && body != null) + res.end(JSON.stringify(body, null, 2), ...args); + else if (typeof body === "string") + res.end(body, ...args); + else if (body == null) { + res.removeHeader("Content-Length"); + res.removeHeader("Transfer-Encoding"); + res.end(null, ...args); + } + return res; +}; +const createETag = (body, encoding) => { + if (body instanceof Stats) { + return eTag(body, { weak: true }); + } else { + return eTag(!Buffer.isBuffer(body) ? Buffer.from(body, encoding) : body, { weak: true }); + } +}; +function setCharset(type, charset) { + const parsed = parse(type); + parsed.parameters.charset = charset; + return format(parsed); +} +const send = (req, res) => (body) => { + let bodyToSend = body; + if (Buffer.isBuffer(body)) { + bodyToSend = body; + } else if (typeof body === "object" && body !== null) { + bodyToSend = JSON.stringify(body, null, 2); + } else if (typeof body === "string") { + const type = res.getHeader("Content-Type"); + if (type && typeof type === "string") { + res.setHeader("Content-Type", setCharset(type, "utf-8")); + } else + res.setHeader("Content-Type", setCharset("text/html", "utf-8")); + } + const encoding = "utf8"; + let etag; + if (body && !res.getHeader("etag") && (etag = createETag(bodyToSend, encoding))) { + res.setHeader("etag", etag); + } + if (req.fresh) + res.statusCode = 304; + if (res.statusCode === 204 || res.statusCode === 304) { + res.removeHeader("Content-Type"); + res.removeHeader("Content-Length"); + res.removeHeader("Transfer-Encoding"); + bodyToSend = ""; + } + if (req.method === "HEAD") { + res.end(""); + return res; + } + if (typeof body === "object") { + if (body == null) { + res.end(""); + return res; + } else if (Buffer.isBuffer(body)) { + if (!res.getHeader("Content-Type")) + res.setHeader("content-type", "application/octet-stream"); + res.end(bodyToSend); + } else + json(res)(bodyToSend, encoding); + } else { + if (typeof bodyToSend !== "string") + bodyToSend = bodyToSend.toString(); + res.end(bodyToSend, encoding); + } + return res; +}; +const sendStatus = (req, res) => (statusCode) => { + const body = STATUS_CODES[statusCode] || String(statusCode); + res.statusCode = statusCode; + res.setHeader("Content-Type", "text/plain"); + return send(req, res)(body); +}; +const status = (res) => (status2) => { + res.statusCode = status2; + return res; +}; +const enableCaching = (res, caching) => { + let cc = caching.maxAge != null && `public,max-age=${caching.maxAge}`; + if (cc && caching.immutable) + cc += ",immutable"; + else if (cc && caching.maxAge === 0) + cc += ",must-revalidate"; + if (cc) + res.setHeader("Cache-Control", cc); +}; +const sendFile = (req, res) => (path, opts = {}, cb) => { + const { root, headers = {}, encoding = "utf-8", caching, ...options } = opts; + if (!isAbsolute(path) && !root) + throw new TypeError("path must be absolute"); + if (caching) + enableCaching(res, caching); + const filePath = root ? join(root, path) : path; + const stats = statSync(filePath); + headers["Content-Encoding"] = encoding; + headers["Last-Modified"] = stats.mtime.toUTCString(); + headers["ETag"] = createETag(stats, encoding); + if (!res.getHeader("Content-Type")) + headers["Content-Type"] = mime.getType(extname(path)) + "; charset=utf-8"; + let status2 = res.statusCode || 200; + if (req.headers["range"]) { + status2 = 206; + const [x, y] = req.headers.range.replace("bytes=", "").split("-"); + const end = options.end = parseInt(y, 10) || stats.size - 1; + const start = options.start = parseInt(x, 10) || 0; + if (start >= stats.size || end >= stats.size) { + res.writeHead(416, { + "Content-Range": `bytes */${stats.size}` + }).end(); + return res; + } + headers["Content-Range"] = `bytes ${start}-${end}/${stats.size}`; + headers["Content-Length"] = end - start + 1; + headers["Accept-Ranges"] = "bytes"; + } else { + headers["Content-Length"] = stats.size; + } + for (const [k, v] of Object.entries(headers)) + res.setHeader(k, v); + res.writeHead(status2, headers); + const stream = createReadStream(filePath, options); + if (cb) + stream.on("error", (err) => cb(err)).on("end", () => cb()); + stream.pipe(res); + return res; +}; +export { + enableCaching, + json, + send, + sendFile, + sendStatus, + status +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/send/dist/index.js.map b/node_modules/@tinyhttp/send/dist/index.js.map new file mode 100644 index 0000000..f29f223 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/json.ts","../src/utils.ts","../src/send.ts","../src/sendStatus.ts","../src/status.ts","../src/sendFile.ts"],"sourcesContent":["import { ServerResponse as S } from 'node:http'\n\ntype Res = Pick\n\n/**\n * Respond with stringified JSON object\n * @param res Response\n */\nexport const json =\n (res: Response) =>\n (body: any, ...args: any[]): Response => {\n res.setHeader('Content-Type', 'application/json')\n if (typeof body === 'object' && body != null) res.end(JSON.stringify(body, null, 2), ...args)\n else if (typeof body === 'string') res.end(body, ...args)\n else if (body == null) {\n res.removeHeader('Content-Length')\n res.removeHeader('Transfer-Encoding')\n res.end(null, ...args)\n }\n\n return res\n }\n","import { parse, format } from '@tinyhttp/content-type'\nimport { eTag } from '@tinyhttp/etag'\nimport { Stats } from 'node:fs'\n\nexport const createETag = (body: Buffer | string | Stats, encoding: BufferEncoding): string => {\n if (body instanceof Stats) {\n return eTag(body, { weak: true })\n } else {\n return eTag(!Buffer.isBuffer(body) ? Buffer.from(body, encoding) : body, { weak: true })\n }\n}\n\nexport function setCharset(type: string, charset: string): string {\n const parsed = parse(type)\n parsed.parameters.charset = charset\n return format(parsed)\n}\n","import type { IncomingMessage as I, ServerResponse as S } from 'node:http'\nimport { json } from './json.js'\nimport { setCharset, createETag } from './utils.js'\n\ntype Req = Pick & { fresh?: boolean }\n\ntype Res = Pick\n\n/**\n * Sends the HTTP response.\n *\n * The body parameter can be a Buffer object, a string, an object, or an array.\n *\n * This method performs many useful tasks for simple non-streaming responses.\n * For example, it automatically assigns the Content-Length HTTP response header field (unless previously defined) and provides automatic HEAD and HTTP cache freshness support.\n *\n * @param req Request\n * @param res Response\n */\nexport const send =\n (req: Request, res: Response) =>\n (body: any): Response => {\n let bodyToSend = body\n\n if (Buffer.isBuffer(body)) {\n bodyToSend = body\n } else if (typeof body === 'object' && body !== null) {\n // in case of object - turn it to json\n bodyToSend = JSON.stringify(body, null, 2)\n } else if (typeof body === 'string') {\n // reflect this in content-type\n const type = res.getHeader('Content-Type')\n\n if (type && typeof type === 'string') {\n res.setHeader('Content-Type', setCharset(type, 'utf-8'))\n } else res.setHeader('Content-Type', setCharset('text/html', 'utf-8'))\n }\n\n // Set encoding\n const encoding: 'utf8' | undefined = 'utf8'\n\n // populate ETag\n let etag: string | undefined\n if (body && !res.getHeader('etag') && (etag = createETag(bodyToSend, encoding))) {\n res.setHeader('etag', etag)\n }\n\n // freshness\n if (req.fresh) res.statusCode = 304\n\n // strip irrelevant headers\n if (res.statusCode === 204 || res.statusCode === 304) {\n res.removeHeader('Content-Type')\n res.removeHeader('Content-Length')\n res.removeHeader('Transfer-Encoding')\n bodyToSend = ''\n }\n\n if (req.method === 'HEAD') {\n res.end('')\n return res\n }\n\n if (typeof body === 'object') {\n if (body == null) {\n res.end('')\n return res\n } else if (Buffer.isBuffer(body)) {\n if (!res.getHeader('Content-Type')) res.setHeader('content-type', 'application/octet-stream')\n res.end(bodyToSend)\n } else json(res)(bodyToSend, encoding)\n } else {\n if (typeof bodyToSend !== 'string') bodyToSend = bodyToSend.toString()\n\n res.end(bodyToSend, encoding)\n }\n\n return res\n }\n","import { IncomingMessage as I, ServerResponse as S } from 'node:http'\nimport { STATUS_CODES } from 'node:http'\nimport { send } from './send.js'\n\ntype Req = Pick\n\ntype Res = Pick\n\n/**\n * Sets the response HTTP status code to statusCode and send its string representation as the response body.\n *\n * If an unsupported status code is specified, the HTTP status is still set to statusCode and the string version of the code is sent as the response body.\n *\n * @param req Request\n * @param res Response\n */\nexport const sendStatus =\n (req: Request, res: Response) =>\n (statusCode: number): Response => {\n const body = STATUS_CODES[statusCode] || String(statusCode)\n\n res.statusCode = statusCode\n\n res.setHeader('Content-Type', 'text/plain')\n\n return send(req, res)(body)\n }\n","import type { ServerResponse } from 'node:http'\n\ntype Res = Pick\n\n/**\n * Sets the HTTP status for the response. It is a chainable alias of Node’s `response.statusCode`.\n *\n * @param res Response\n */\nexport const status =\n (res: Response) =>\n (status: number): Response => {\n res.statusCode = status\n\n return res\n }\n","import type { IncomingMessage as I, ServerResponse as S } from 'node:http'\nimport { createReadStream, statSync } from 'node:fs'\nimport { isAbsolute, extname } from 'node:path'\nimport { createETag } from './utils.js'\nimport { join } from 'node:path'\nimport mime from 'mime'\n\nexport type ReadStreamOptions = Partial<{\n flags: string\n encoding: BufferEncoding\n fd: number\n mode: number\n autoClose: boolean\n emitClose: boolean\n start: number\n end: number\n highWaterMark: number\n}>\n\nexport type SendFileOptions = ReadStreamOptions &\n Partial<{\n root: string\n headers: Record\n caching: Partial<{\n maxAge: number\n immutable: boolean\n }>\n }>\n\nexport type Caching = Partial<{\n maxAge: number\n immutable: boolean\n}>\n\ntype Req = Pick\n\ntype Res = Pick & NodeJS.WritableStream\n\nexport const enableCaching = (res: Res, caching: Caching): void => {\n let cc = caching.maxAge != null && `public,max-age=${caching.maxAge}`\n if (cc && caching.immutable) cc += ',immutable'\n else if (cc && caching.maxAge === 0) cc += ',must-revalidate'\n\n if (cc) res.setHeader('Cache-Control', cc)\n}\n\n/**\n * Sends a file by piping a stream to response.\n *\n * It also checks for extension to set a proper `Content-Type` header.\n *\n * Path argument must be absolute. To use a relative path, specify the `root` option first.\n *\n * @param res Response\n */\nexport const sendFile =\n (req: Request, res: Response) =>\n (path: string, opts: SendFileOptions = {}, cb?: (err?: any) => void): Response => {\n const { root, headers = {}, encoding = 'utf-8', caching, ...options } = opts\n\n if (!isAbsolute(path) && !root) throw new TypeError('path must be absolute')\n\n if (caching) enableCaching(res, caching)\n\n const filePath = root ? join(root, path) : path\n\n const stats = statSync(filePath)\n\n headers['Content-Encoding'] = encoding\n\n headers['Last-Modified'] = stats.mtime.toUTCString()\n\n headers['ETag'] = createETag(stats, encoding)\n\n if (!res.getHeader('Content-Type')) headers['Content-Type'] = mime.getType(extname(path)) + '; charset=utf-8'\n\n let status = res.statusCode || 200\n\n if (req.headers['range']) {\n status = 206\n const [x, y] = req.headers.range.replace('bytes=', '').split('-')\n const end = (options.end = parseInt(y, 10) || stats.size - 1)\n const start = (options.start = parseInt(x, 10) || 0)\n\n if (start >= stats.size || end >= stats.size) {\n res\n .writeHead(416, {\n 'Content-Range': `bytes */${stats.size}`\n })\n .end()\n return res\n }\n headers['Content-Range'] = `bytes ${start}-${end}/${stats.size}`\n headers['Content-Length'] = end - start + 1\n headers['Accept-Ranges'] = 'bytes'\n } else {\n headers['Content-Length'] = stats.size\n }\n\n for (const [k, v] of Object.entries(headers)) res.setHeader(k, v)\n\n res.writeHead(status, headers)\n\n const stream = createReadStream(filePath, options)\n\n if (cb) stream.on('error', (err) => cb(err)).on('end', () => cb())\n\n stream.pipe(res)\n\n return res\n }\n"],"names":["status"],"mappings":";;;;;;AAQO,MAAM,OACX,CAA6B,QAC7B,CAAC,SAAc,SAA0B;AACnC,MAAA,UAAU,gBAAgB,kBAAkB;AAC5C,MAAA,OAAO,SAAS,YAAY,QAAQ;AAAU,QAAA,IAAI,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,GAAG,IAAI;AAAA,WACnF,OAAO,SAAS;AAAc,QAAA,IAAI,MAAM,GAAG,IAAI;AAAA,WAC/C,QAAQ,MAAM;AACrB,QAAI,aAAa,gBAAgB;AACjC,QAAI,aAAa,mBAAmB;AAChC,QAAA,IAAI,MAAM,GAAG,IAAI;AAAA,EACvB;AAEO,SAAA;AACT;ACjBW,MAAA,aAAa,CAAC,MAA+B,aAAqC;AAC7F,MAAI,gBAAgB,OAAO;AACzB,WAAO,KAAK,MAAM,EAAE,MAAM,KAAM,CAAA;AAAA,EAAA,OAC3B;AACL,WAAO,KAAK,CAAC,OAAO,SAAS,IAAI,IAAI,OAAO,KAAK,MAAM,QAAQ,IAAI,MAAM,EAAE,MAAM,KAAM,CAAA;AAAA,EACzF;AACF;AAEgB,SAAA,WAAW,MAAc,SAAyB;AAC1D,QAAA,SAAS,MAAM,IAAI;AACzB,SAAO,WAAW,UAAU;AAC5B,SAAO,OAAO,MAAM;AACtB;ACGO,MAAM,OACX,CAAwD,KAAc,QACtE,CAAC,SAAwB;AACvB,MAAI,aAAa;AAEb,MAAA,OAAO,SAAS,IAAI,GAAG;AACZ,iBAAA;AAAA,EACJ,WAAA,OAAO,SAAS,YAAY,SAAS,MAAM;AAEpD,iBAAa,KAAK,UAAU,MAAM,MAAM,CAAC;AAAA,EAAA,WAChC,OAAO,SAAS,UAAU;AAE7B,UAAA,OAAO,IAAI,UAAU,cAAc;AAErC,QAAA,QAAQ,OAAO,SAAS,UAAU;AACpC,UAAI,UAAU,gBAAgB,WAAW,MAAM,OAAO,CAAC;AAAA,IACzD;AAAO,UAAI,UAAU,gBAAgB,WAAW,aAAa,OAAO,CAAC;AAAA,EACvE;AAGA,QAAM,WAA+B;AAGjC,MAAA;AACA,MAAA,QAAQ,CAAC,IAAI,UAAU,MAAM,MAAM,OAAO,WAAW,YAAY,QAAQ,IAAI;AAC3E,QAAA,UAAU,QAAQ,IAAI;AAAA,EAC5B;AAGA,MAAI,IAAI;AAAO,QAAI,aAAa;AAGhC,MAAI,IAAI,eAAe,OAAO,IAAI,eAAe,KAAK;AACpD,QAAI,aAAa,cAAc;AAC/B,QAAI,aAAa,gBAAgB;AACjC,QAAI,aAAa,mBAAmB;AACvB,iBAAA;AAAA,EACf;AAEI,MAAA,IAAI,WAAW,QAAQ;AACzB,QAAI,IAAI,EAAE;AACH,WAAA;AAAA,EACT;AAEI,MAAA,OAAO,SAAS,UAAU;AAC5B,QAAI,QAAQ,MAAM;AAChB,UAAI,IAAI,EAAE;AACH,aAAA;AAAA,IACE,WAAA,OAAO,SAAS,IAAI,GAAG;AAC5B,UAAA,CAAC,IAAI,UAAU,cAAc;AAAO,YAAA,UAAU,gBAAgB,0BAA0B;AAC5F,UAAI,IAAI,UAAU;AAAA,IACpB;AAAY,WAAA,GAAG,EAAE,YAAY,QAAQ;AAAA,EAAA,OAChC;AACL,QAAI,OAAO,eAAe;AAAU,mBAAa,WAAW;AAExD,QAAA,IAAI,YAAY,QAAQ;AAAA,EAC9B;AAEO,SAAA;AACT;AC9DK,MAAM,aACX,CAAwD,KAAc,QACtE,CAAC,eAAiC;AAChC,QAAM,OAAO,aAAa,UAAU,KAAK,OAAO,UAAU;AAE1D,MAAI,aAAa;AAEb,MAAA,UAAU,gBAAgB,YAAY;AAE1C,SAAO,KAAK,KAAK,GAAG,EAAE,IAAI;AAC5B;ACjBK,MAAM,SACX,CAA6B,QAC7B,CAACA,YAA6B;AAC5B,MAAI,aAAaA;AAEV,SAAA;AACT;ACuBW,MAAA,gBAAgB,CAAC,KAAU,YAA2B;AACjE,MAAI,KAAK,QAAQ,UAAU,QAAQ,kBAAkB,QAAQ,MAAM;AACnE,MAAI,MAAM,QAAQ;AAAiB,UAAA;AAAA,WAC1B,MAAM,QAAQ,WAAW;AAAS,UAAA;AAEvC,MAAA;AAAQ,QAAA,UAAU,iBAAiB,EAAE;AAC3C;AAWa,MAAA,WACX,CAAwD,KAAc,QACtE,CAAC,MAAc,OAAwB,CAAC,GAAG,OAAuC;AAC1E,QAAA,EAAE,MAAM,UAAU,IAAI,WAAW,SAAS,SAAS,GAAG,QAAY,IAAA;AAExE,MAAI,CAAC,WAAW,IAAI,KAAK,CAAC;AAAY,UAAA,IAAI,UAAU,uBAAuB;AAEvE,MAAA;AAAS,kBAAc,KAAK,OAAO;AAEvC,QAAM,WAAW,OAAO,KAAK,MAAM,IAAI,IAAI;AAErC,QAAA,QAAQ,SAAS,QAAQ;AAE/B,UAAQ,kBAAkB,IAAI;AAE9B,UAAQ,eAAe,IAAI,MAAM,MAAM,YAAY;AAEnD,UAAQ,MAAM,IAAI,WAAW,OAAO,QAAQ;AAExC,MAAA,CAAC,IAAI,UAAU,cAAc;AAAG,YAAQ,cAAc,IAAI,KAAK,QAAQ,QAAQ,IAAI,CAAC,IAAI;AAExF,MAAAA,UAAS,IAAI,cAAc;AAE3B,MAAA,IAAI,QAAQ,OAAO,GAAG;AACf,IAAAA,UAAA;AACT,UAAM,CAAC,GAAG,CAAC,IAAI,IAAI,QAAQ,MAAM,QAAQ,UAAU,EAAE,EAAE,MAAM,GAAG;AAC1D,UAAA,MAAO,QAAQ,MAAM,SAAS,GAAG,EAAE,KAAK,MAAM,OAAO;AAC3D,UAAM,QAAS,QAAQ,QAAQ,SAAS,GAAG,EAAE,KAAK;AAElD,QAAI,SAAS,MAAM,QAAQ,OAAO,MAAM,MAAM;AAC5C,UACG,UAAU,KAAK;AAAA,QACd,iBAAiB,WAAW,MAAM,IAAI;AAAA,MAAA,CACvC,EACA,IAAI;AACA,aAAA;AAAA,IACT;AACQ,YAAA,eAAe,IAAI,SAAS,KAAK,IAAI,GAAG,IAAI,MAAM,IAAI;AACtD,YAAA,gBAAgB,IAAI,MAAM,QAAQ;AAC1C,YAAQ,eAAe,IAAI;AAAA,EAAA,OACtB;AACG,YAAA,gBAAgB,IAAI,MAAM;AAAA,EACpC;AAEA,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,OAAO;AAAO,QAAA,UAAU,GAAG,CAAC;AAE5D,MAAA,UAAUA,SAAQ,OAAO;AAEvB,QAAA,SAAS,iBAAiB,UAAU,OAAO;AAE7C,MAAA;AAAI,WAAO,GAAG,SAAS,CAAC,QAAQ,GAAG,GAAG,CAAC,EAAE,GAAG,OAAO,MAAM,GAAI,CAAA;AAEjE,SAAO,KAAK,GAAG;AAER,SAAA;AACT;"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/json.d.ts b/node_modules/@tinyhttp/send/dist/json.d.ts new file mode 100644 index 0000000..768b833 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/json.d.ts @@ -0,0 +1,10 @@ +/// +import { ServerResponse as S } from 'node:http'; +type Res = Pick; +/** + * Respond with stringified JSON object + * @param res Response + */ +export declare const json: (res: Response_1) => (body: any, ...args: any[]) => Response_1; +export {}; +//# sourceMappingURL=json.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/json.d.ts.map b/node_modules/@tinyhttp/send/dist/json.d.ts.map new file mode 100644 index 0000000..c7ae1aa --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/json.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,IAAI,CAAC,EAAE,MAAM,WAAW,CAAA;AAE/C,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,cAAc,CAAC,CAAA;AAExD;;;GAGG;AACH,eAAO,MAAM,IAAI,4DAER,GAAG,WAAW,GAAG,EAAE,eAWzB,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/send.d.ts b/node_modules/@tinyhttp/send/dist/send.d.ts new file mode 100644 index 0000000..2311946 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/send.d.ts @@ -0,0 +1,20 @@ +/// +import type { IncomingMessage as I, ServerResponse as S } from 'node:http'; +type Req = Pick & { + fresh?: boolean; +}; +type Res = Pick; +/** + * Sends the HTTP response. + * + * The body parameter can be a Buffer object, a string, an object, or an array. + * + * This method performs many useful tasks for simple non-streaming responses. + * For example, it automatically assigns the Content-Length HTTP response header field (unless previously defined) and provides automatic HEAD and HTTP cache freshness support. + * + * @param req Request + * @param res Response + */ +export declare const send: (req: Request_1, res: Response_1) => (body: any) => Response_1; +export {}; +//# sourceMappingURL=send.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/send.d.ts.map b/node_modules/@tinyhttp/send/dist/send.d.ts.map new file mode 100644 index 0000000..e429dc2 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/send.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,eAAe,IAAI,CAAC,EAAE,cAAc,IAAI,CAAC,EAAE,MAAM,WAAW,CAAA;AAI1E,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAElD,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,WAAW,GAAG,cAAc,GAAG,KAAK,GAAG,WAAW,GAAG,YAAY,CAAC,CAAA;AAErF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,IAAI,yGAER,GAAG,eAyDT,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/sendFile.d.ts b/node_modules/@tinyhttp/send/dist/sendFile.d.ts new file mode 100644 index 0000000..bde3b97 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/sendFile.d.ts @@ -0,0 +1,42 @@ +/// +/// +/// +import type { IncomingMessage as I, ServerResponse as S } from 'node:http'; +export type ReadStreamOptions = Partial<{ + flags: string; + encoding: BufferEncoding; + fd: number; + mode: number; + autoClose: boolean; + emitClose: boolean; + start: number; + end: number; + highWaterMark: number; +}>; +export type SendFileOptions = ReadStreamOptions & Partial<{ + root: string; + headers: Record; + caching: Partial<{ + maxAge: number; + immutable: boolean; + }>; +}>; +export type Caching = Partial<{ + maxAge: number; + immutable: boolean; +}>; +type Req = Pick; +type Res = Pick & NodeJS.WritableStream; +export declare const enableCaching: (res: Res, caching: Caching) => void; +/** + * Sends a file by piping a stream to response. + * + * It also checks for extension to set a proper `Content-Type` header. + * + * Path argument must be absolute. To use a relative path, specify the `root` option first. + * + * @param res Response + */ +export declare const sendFile: (req: Request_1, res: Response_1) => (path: string, opts?: SendFileOptions, cb?: (err?: any) => void) => Response_1; +export {}; +//# sourceMappingURL=sendFile.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/sendFile.d.ts.map b/node_modules/@tinyhttp/send/dist/sendFile.d.ts.map new file mode 100644 index 0000000..f7bcd48 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/sendFile.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"sendFile.d.ts","sourceRoot":"","sources":["../src/sendFile.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,EAAE,eAAe,IAAI,CAAC,EAAE,cAAc,IAAI,CAAC,EAAE,MAAM,WAAW,CAAA;AAO1E,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,cAAc,CAAA;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,EAAE,MAAM,CAAA;CACtB,CAAC,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAC7C,OAAO,CAAC;IACN,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,OAAO,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,MAAM,CAAA;QACd,SAAS,EAAE,OAAO,CAAA;KACnB,CAAC,CAAA;CACH,CAAC,CAAA;AAEJ,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;CACnB,CAAC,CAAA;AAEF,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;AAE7B,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,CAAC,GAAG,MAAM,CAAC,cAAc,CAAA;AAElG,eAAO,MAAM,aAAa,QAAS,GAAG,WAAW,OAAO,KAAG,IAM1D,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,yGAEZ,MAAM,SAAQ,eAAe,cAAmB,GAAG,KAAK,IAAI,eAqDlE,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/sendStatus.d.ts b/node_modules/@tinyhttp/send/dist/sendStatus.d.ts new file mode 100644 index 0000000..8be61e0 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/sendStatus.d.ts @@ -0,0 +1,15 @@ +/// +import { IncomingMessage as I, ServerResponse as S } from 'node:http'; +type Req = Pick; +type Res = Pick; +/** + * Sets the response HTTP status code to statusCode and send its string representation as the response body. + * + * If an unsupported status code is specified, the HTTP status is still set to statusCode and the string version of the code is sent as the response body. + * + * @param req Request + * @param res Response + */ +export declare const sendStatus: (req: Request_1, res: Response_1) => (statusCode: number) => Response_1; +export {}; +//# sourceMappingURL=sendStatus.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/sendStatus.d.ts.map b/node_modules/@tinyhttp/send/dist/sendStatus.d.ts.map new file mode 100644 index 0000000..22567b3 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/sendStatus.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"sendStatus.d.ts","sourceRoot":"","sources":["../src/sendStatus.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,IAAI,CAAC,EAAE,cAAc,IAAI,CAAC,EAAE,MAAM,WAAW,CAAA;AAIrE,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;AAE5B,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,WAAW,GAAG,cAAc,GAAG,KAAK,GAAG,WAAW,GAAG,YAAY,CAAC,CAAA;AAErF;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,+GAER,MAAM,eAQlB,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/status.d.ts b/node_modules/@tinyhttp/send/dist/status.d.ts new file mode 100644 index 0000000..6a37166 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/status.d.ts @@ -0,0 +1,11 @@ +/// +import type { ServerResponse } from 'node:http'; +type Res = Pick; +/** + * Sets the HTTP status for the response. It is a chainable alias of Node’s `response.statusCode`. + * + * @param res Response + */ +export declare const status: (res: Response_1) => (status: number) => Response_1; +export {}; +//# sourceMappingURL=status.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/status.d.ts.map b/node_modules/@tinyhttp/send/dist/status.d.ts.map new file mode 100644 index 0000000..dd79d4a --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/status.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE/C,KAAK,GAAG,GAAG,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAA;AAE7C;;;;GAIG;AACH,eAAO,MAAM,MAAM,8DAER,MAAM,eAId,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/utils.d.ts b/node_modules/@tinyhttp/send/dist/utils.d.ts new file mode 100644 index 0000000..ac05fe7 --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/utils.d.ts @@ -0,0 +1,6 @@ +/// +/// +import { Stats } from 'node:fs'; +export declare const createETag: (body: Buffer | string | Stats, encoding: BufferEncoding) => string; +export declare function setCharset(type: string, charset: string): string; +//# sourceMappingURL=utils.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/dist/utils.d.ts.map b/node_modules/@tinyhttp/send/dist/utils.d.ts.map new file mode 100644 index 0000000..b66a66a --- /dev/null +++ b/node_modules/@tinyhttp/send/dist/utils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/B,eAAO,MAAM,UAAU,SAAU,MAAM,GAAG,MAAM,GAAG,KAAK,YAAY,cAAc,KAAG,MAMpF,CAAA;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIhE"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/send/package.json b/node_modules/@tinyhttp/send/package.json new file mode 100644 index 0000000..e764f92 --- /dev/null +++ b/node_modules/@tinyhttp/send/package.json @@ -0,0 +1,41 @@ +{ + "name": "@tinyhttp/send", + "version": "2.2.1", + "type": "module", + "description": "json, send, sendFile, status and sendStatus methods for tinyhttp", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/res" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "res", + "send", + "send-file" + ], + "engines": { + "node": ">=12.20.0" + }, + "author": "v1rtl", + "license": "MIT", + "dependencies": { + "@tinyhttp/content-type": "^0.1.4", + "mime": "4.0.1", + "@tinyhttp/etag": "2.1.1" + }, + "files": [ + "dist" + ], + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/type-is/LICENSE b/node_modules/@tinyhttp/type-is/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/type-is/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/type-is/README.md b/node_modules/@tinyhttp/type-is/README.md new file mode 100644 index 0000000..066efb4 --- /dev/null +++ b/node_modules/@tinyhttp/type-is/README.md @@ -0,0 +1,11 @@ +# @tinyhttp/type-is + +> [`type-is`](https://github.com/jshttp/type-is) rewrite in TypeScript. + +Infer the content-type of a request. + +## Install + +```sh +pnpm i @tinyhttp/type-is +``` diff --git a/node_modules/@tinyhttp/type-is/dist/index.d.ts b/node_modules/@tinyhttp/type-is/dist/index.d.ts new file mode 100644 index 0000000..00f0c24 --- /dev/null +++ b/node_modules/@tinyhttp/type-is/dist/index.d.ts @@ -0,0 +1,8 @@ +/** + * Compare a `value` content-type with `types`. + * Each `type` can be an extension like `html`, + * a special shortcut like `multipart` or `urlencoded`, + * or a mime type. + */ +export declare const typeIs: (value: string, ...types: string[]) => string | false; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/type-is/dist/index.d.ts.map b/node_modules/@tinyhttp/type-is/dist/index.d.ts.map new file mode 100644 index 0000000..79dd002 --- /dev/null +++ b/node_modules/@tinyhttp/type-is/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgEA;;;;;GAKG;AACH,eAAO,MAAM,MAAM,UAAW,MAAM,YAAY,MAAM,EAAE,mBAoBvD,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/type-is/dist/index.js b/node_modules/@tinyhttp/type-is/dist/index.js new file mode 100644 index 0000000..eb35a2d --- /dev/null +++ b/node_modules/@tinyhttp/type-is/dist/index.js @@ -0,0 +1,63 @@ +import * as typer from "@tinyhttp/content-type"; +import mime from "mime"; +function normalizeType(value) { + const type = typer.parse(value); + type.parameters = {}; + return typer.format(type); +} +function tryNormalizeType(value) { + if (!value) + return null; + try { + return normalizeType(value); + } catch (err) { + return null; + } +} +function mimeMatch(expected, actual) { + if (expected === false) + return false; + const actualParts = actual.split("/"); + const expectedParts = expected.split("/"); + if (actualParts.length !== 2 || expectedParts.length !== 2) + return false; + if (expectedParts[0] !== "*" && expectedParts[0] !== actualParts[0]) + return false; + if (expectedParts[1].slice(0, 2) === "*+") + return expectedParts[1].length <= actualParts[1].length + 1 && expectedParts[1].slice(1) === actualParts[1].slice(1 - expectedParts[1].length); + if (expectedParts[1] !== "*" && expectedParts[1] !== actualParts[1]) + return false; + return true; +} +function normalize(type) { + if (typeof type !== "string") + return false; + switch (type) { + case "urlencoded": + return "application/x-www-form-urlencoded"; + case "multipart": + return "multipart/*"; + } + if (type[0] === "+") + return "*/*" + type; + return type.indexOf("/") === -1 ? mime.getType(type) : type; +} +const typeIs = (value, ...types) => { + let i; + const val = tryNormalizeType(value); + if (!val) + return false; + if (!types || !types.length) + return val; + let type; + for (i = 0; i < types.length; i++) { + if (mimeMatch(normalize(type = types[i]), val)) { + return type[0] === "+" || type.indexOf("*") !== -1 ? val : type; + } + } + return false; +}; +export { + typeIs +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/type-is/dist/index.js.map b/node_modules/@tinyhttp/type-is/dist/index.js.map new file mode 100644 index 0000000..4df2b78 --- /dev/null +++ b/node_modules/@tinyhttp/type-is/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import * as typer from '@tinyhttp/content-type'\nimport mime from 'mime'\n\nfunction normalizeType(value: string) {\n // parse the type\n const type = typer.parse(value)\n type.parameters = {}\n // reformat it\n return typer.format(type)\n}\n\nfunction tryNormalizeType(value: string) {\n if (!value) return null\n\n try {\n return normalizeType(value)\n } catch (err) {\n return null\n }\n}\n\nfunction mimeMatch(expected: string | boolean, actual: string | boolean): boolean {\n // invalid type\n if (expected === false) return false\n\n // split types\n const actualParts = (actual as string).split('/')\n const expectedParts = (expected as string).split('/')\n\n // invalid format\n if (actualParts.length !== 2 || expectedParts.length !== 2) return false\n\n // validate type\n if (expectedParts[0] !== '*' && expectedParts[0] !== actualParts[0]) return false\n\n // validate suffix wildcard\n if (expectedParts[1].slice(0, 2) === '*+')\n return (\n expectedParts[1].length <= actualParts[1].length + 1 &&\n expectedParts[1].slice(1) === actualParts[1].slice(1 - expectedParts[1].length)\n )\n\n // validate subtype\n if (expectedParts[1] !== '*' && expectedParts[1] !== actualParts[1]) return false\n\n return true\n}\n\nfunction normalize(type: string | unknown) {\n // invalid type\n if (typeof type !== 'string') return false\n\n switch (type) {\n case 'urlencoded':\n return 'application/x-www-form-urlencoded'\n case 'multipart':\n return 'multipart/*'\n }\n // \"+json\" -> \"*/*+json\" expando\n if (type[0] === '+') return '*/*' + type\n\n return type.indexOf('/') === -1 ? mime.getType(type) : type\n}\n\n/**\n * Compare a `value` content-type with `types`.\n * Each `type` can be an extension like `html`,\n * a special shortcut like `multipart` or `urlencoded`,\n * or a mime type.\n */\nexport const typeIs = (value: string, ...types: string[]) => {\n let i: number\n // remove parameters and normalize\n const val = tryNormalizeType(value)\n\n // no type or invalid\n if (!val) return false\n\n // no types, return the content type\n if (!types || !types.length) return val\n\n let type: string\n for (i = 0; i < types.length; i++) {\n if (mimeMatch(normalize((type = types[i])), val)) {\n return type[0] === '+' || type.indexOf('*') !== -1 ? val : type\n }\n }\n\n // no matches\n return false\n}\n"],"names":[],"mappings":";;AAGA,SAAS,cAAc,OAAe;AAE9B,QAAA,OAAO,MAAM,MAAM,KAAK;AAC9B,OAAK,aAAa;AAEX,SAAA,MAAM,OAAO,IAAI;AAC1B;AAEA,SAAS,iBAAiB,OAAe;AACvC,MAAI,CAAC;AAAc,WAAA;AAEf,MAAA;AACF,WAAO,cAAc,KAAK;AAAA,WACnB,KAAK;AACL,WAAA;AAAA,EACT;AACF;AAEA,SAAS,UAAU,UAA4B,QAAmC;AAEhF,MAAI,aAAa;AAAc,WAAA;AAGzB,QAAA,cAAe,OAAkB,MAAM,GAAG;AAC1C,QAAA,gBAAiB,SAAoB,MAAM,GAAG;AAGpD,MAAI,YAAY,WAAW,KAAK,cAAc,WAAW;AAAU,WAAA;AAG/D,MAAA,cAAc,CAAC,MAAM,OAAO,cAAc,CAAC,MAAM,YAAY,CAAC;AAAU,WAAA;AAG5E,MAAI,cAAc,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM;AAEjC,WAAA,cAAc,CAAC,EAAE,UAAU,YAAY,CAAC,EAAE,SAAS,KACnD,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,YAAY,CAAC,EAAE,MAAM,IAAI,cAAc,CAAC,EAAE,MAAM;AAI9E,MAAA,cAAc,CAAC,MAAM,OAAO,cAAc,CAAC,MAAM,YAAY,CAAC;AAAU,WAAA;AAErE,SAAA;AACT;AAEA,SAAS,UAAU,MAAwB;AAEzC,MAAI,OAAO,SAAS;AAAiB,WAAA;AAErC,UAAQ,MAAM;AAAA,IACZ,KAAK;AACI,aAAA;AAAA,IACT,KAAK;AACI,aAAA;AAAA,EACX;AAEI,MAAA,KAAK,CAAC,MAAM;AAAK,WAAO,QAAQ;AAE7B,SAAA,KAAK,QAAQ,GAAG,MAAM,KAAK,KAAK,QAAQ,IAAI,IAAI;AACzD;AAQa,MAAA,SAAS,CAAC,UAAkB,UAAoB;AACvD,MAAA;AAEE,QAAA,MAAM,iBAAiB,KAAK;AAGlC,MAAI,CAAC;AAAY,WAAA;AAGb,MAAA,CAAC,SAAS,CAAC,MAAM;AAAe,WAAA;AAEhC,MAAA;AACJ,OAAK,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AAC7B,QAAA,UAAU,UAAW,OAAO,MAAM,CAAC,CAAE,GAAG,GAAG,GAAG;AACzC,aAAA,KAAK,CAAC,MAAM,OAAO,KAAK,QAAQ,GAAG,MAAM,KAAK,MAAM;AAAA,IAC7D;AAAA,EACF;AAGO,SAAA;AACT;"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/type-is/package.json b/node_modules/@tinyhttp/type-is/package.json new file mode 100644 index 0000000..3f21796 --- /dev/null +++ b/node_modules/@tinyhttp/type-is/package.json @@ -0,0 +1,41 @@ +{ + "name": "@tinyhttp/type-is", + "version": "2.2.2", + "type": "module", + "description": "TypeScript rewrite of type-is with CJS and ESM targets", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/type-is" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "req", + "request", + "type-is", + "javascript" + ], + "engines": { + "node": ">=12.20.0" + }, + "author": "v1rtl", + "license": "MIT", + "dependencies": { + "@tinyhttp/content-type": "^0.1.4", + "mime": "4.0.1" + }, + "files": [ + "dist" + ], + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/url/LICENSE b/node_modules/@tinyhttp/url/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/url/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/url/README.md b/node_modules/@tinyhttp/url/README.md new file mode 100644 index 0000000..603038e --- /dev/null +++ b/node_modules/@tinyhttp/url/README.md @@ -0,0 +1,15 @@ +# @tinyhttp/req + +[![npm (scoped)][npm-badge]](https://npmjs.com/package/@tinyhttp/req) [![npm][dl-badge]](https://npmjs.com/package/@tinyhttp/req) [![][web-badge]](https://tinyhttp.v1rtl.site/mw/req) + +URL extensions for to parse query parameters, URL parameters, and more. + +## Install + +```sh +pnpm i @tinyhttp/url +``` + +[npm-badge]: https://img.shields.io/npm/v/@tinyhttp/req?style=flat-square +[dl-badge]: https://img.shields.io/npm/dt/@tinyhttp/req?style=flat-square +[web-badge]: https://img.shields.io/badge/website-visit-hotpink?style=flat-square diff --git a/node_modules/@tinyhttp/url/dist/index.d.ts b/node_modules/@tinyhttp/url/dist/index.d.ts new file mode 100644 index 0000000..4870cda --- /dev/null +++ b/node_modules/@tinyhttp/url/dist/index.d.ts @@ -0,0 +1,14 @@ +/// +import { ParsedUrlQuery } from 'node:querystring'; +type Regex = { + keys: string[] | false; + pattern: RegExp; +}; +export declare const getURLParams: ({ pattern, keys }: Regex, reqUrl?: string) => URLParams; +export type URLParams = { + [key: string]: string; +}; +export declare const getPathname: (url: string) => string; +export declare const getQueryParams: (url?: string) => ParsedUrlQuery; +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@tinyhttp/url/dist/index.d.ts.map b/node_modules/@tinyhttp/url/dist/index.d.ts.map new file mode 100644 index 0000000..47940c8 --- /dev/null +++ b/node_modules/@tinyhttp/url/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,EAAS,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAExD,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,eAAO,MAAM,YAAY,sBAAuB,KAAK,sBAAiB,SAarE,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CACtB,CAAA;AAOD,eAAO,MAAM,WAAW,QAAS,MAAM,KAAG,MAA0C,CAAA;AAEpF,eAAO,MAAM,cAAc,oBAAgB,cAA0D,CAAA"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/url/dist/index.js b/node_modules/@tinyhttp/url/dist/index.js new file mode 100644 index 0000000..e67409a --- /dev/null +++ b/node_modules/@tinyhttp/url/dist/index.js @@ -0,0 +1,24 @@ +import { parse } from "node:querystring"; +const getURLParams = ({ pattern, keys }, reqUrl = "/") => { + const matches = pattern.exec(reqUrl); + const params = {}; + if (matches && typeof keys !== "boolean") + for (let i = 0; i < keys.length; i++) { + if (matches[i + 1]) { + params[keys[i]] = decodeURIComponent(matches[i + 1]); + } + } + return params; +}; +const getQueryIndex = (url) => { + const index = url.indexOf("?"); + return index === -1 ? url.length : index; +}; +const getPathname = (url) => url.slice(0, getQueryIndex(url)); +const getQueryParams = (url = "/") => parse(url.slice(getQueryIndex(url) + 1)); +export { + getPathname, + getQueryParams, + getURLParams +}; +//# sourceMappingURL=index.js.map diff --git a/node_modules/@tinyhttp/url/dist/index.js.map b/node_modules/@tinyhttp/url/dist/index.js.map new file mode 100644 index 0000000..24d8c8b --- /dev/null +++ b/node_modules/@tinyhttp/url/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { parse, ParsedUrlQuery } from 'node:querystring'\n\ntype Regex = {\n keys: string[] | false\n pattern: RegExp\n}\n\nexport const getURLParams = ({ pattern, keys }: Regex, reqUrl = '/'): URLParams => {\n const matches = pattern.exec(reqUrl)\n\n const params = {}\n\n if (matches && typeof keys !== 'boolean')\n for (let i = 0; i < keys.length; i++) {\n if (matches[i + 1]) {\n params[keys[i]] = decodeURIComponent(matches[i + 1])\n }\n }\n\n return params\n}\n\nexport type URLParams = {\n [key: string]: string\n}\n\nconst getQueryIndex = (url: string): number => {\n const index = url.indexOf('?')\n return index === -1 ? url.length : index\n}\n\nexport const getPathname = (url: string): string => url.slice(0, getQueryIndex(url))\n\nexport const getQueryParams = (url = '/'): ParsedUrlQuery => parse(url.slice(getQueryIndex(url) + 1))\n"],"names":[],"mappings":";AAOO,MAAM,eAAe,CAAC,EAAE,SAAS,KAAK,GAAU,SAAS,QAAmB;AAC3E,QAAA,UAAU,QAAQ,KAAK,MAAM;AAEnC,QAAM,SAAS,CAAA;AAEX,MAAA,WAAW,OAAO,SAAS;AAC7B,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAChC,UAAA,QAAQ,IAAI,CAAC,GAAG;AACX,eAAA,KAAK,CAAC,CAAC,IAAI,mBAAmB,QAAQ,IAAI,CAAC,CAAC;AAAA,MACrD;AAAA,IACF;AAEK,SAAA;AACT;AAMA,MAAM,gBAAgB,CAAC,QAAwB;AACvC,QAAA,QAAQ,IAAI,QAAQ,GAAG;AACtB,SAAA,UAAU,KAAK,IAAI,SAAS;AACrC;AAEa,MAAA,cAAc,CAAC,QAAwB,IAAI,MAAM,GAAG,cAAc,GAAG,CAAC;AAEtE,MAAA,iBAAiB,CAAC,MAAM,QAAwB,MAAM,IAAI,MAAM,cAAc,GAAG,IAAI,CAAC,CAAC;"} \ No newline at end of file diff --git a/node_modules/@tinyhttp/url/package.json b/node_modules/@tinyhttp/url/package.json new file mode 100644 index 0000000..4874c40 --- /dev/null +++ b/node_modules/@tinyhttp/url/package.json @@ -0,0 +1,38 @@ +{ + "name": "@tinyhttp/url", + "version": "2.1.1", + "type": "module", + "description": "URL extensions for tinyhttp", + "homepage": "https://tinyhttp.v1rtl.site", + "repository": { + "type": "git", + "url": "https://github.com/tinyhttp/tinyhttp.git", + "directory": "packages/url" + }, + "types": "./dist/index.d.ts", + "exports": "./dist/index.js", + "keywords": [ + "tinyhttp", + "node.js", + "web framework", + "web", + "backend", + "req", + "request", + "url", + "params", + "query" + ], + "engines": { + "node": ">=12.20.0" + }, + "author": "v1rtl", + "license": "MIT", + "files": [ + "dist" + ], + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/node_modules/@tinyhttp/vary/LICENSE b/node_modules/@tinyhttp/vary/LICENSE new file mode 100644 index 0000000..9b450a0 --- /dev/null +++ b/node_modules/@tinyhttp/vary/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tinyhttp/vary/README.md b/node_modules/@tinyhttp/vary/README.md new file mode 100644 index 0000000..9d3f4bf --- /dev/null +++ b/node_modules/@tinyhttp/vary/README.md @@ -0,0 +1,77 @@ +# @tinyhttp/vary + +[![Version][v-badge-url]][npm-url] [![Downloads][dl-badge-url]][npm-url] [![GitHub Workflow Status][gh-actions-img]][github-actions] [![Codecov][cov-badge-url]][cov-url] + +> [`vary`](https://github.com/jshttp/vary) rewrite in TypeScript with ESM and CommonJS targets + +Manipulate the HTTP Vary header + +## Install + +```sh +pnpm i @tinyhttp/vary +``` + +## API + +```ts +import { vary, append } from '@tinyhttp/vary' +``` + +### `vary(res, field)` + +Adds the given header `field` to the `Vary` response header of `res`. +This can be a string of a single field, a string of a valid `Vary` +header, or an array of multiple fields. + +This will append the header if not already listed, otherwise leaves +it listed in the current location. + +```ts +vary(res, 'Origin') +``` + +### `append(header, field)` + +Adds the given header `field` to the `Vary` response header string `header`. +This can be a string of a single field, a string of a valid `Vary` header, +or an array of multiple fields. + +This will append the header if not already listed, otherwise leaves +it listed in the current location. The new header string is returned. + +```ts +// Get header string appending "Origin" to "Accept, User-Agent" +append('Accept, User-Agent', 'Origin') +``` + +## Examples + +```ts +import { createServer } from 'node:http' +import { vary } from '@tinyhttp/vary' + +createServer((req, res) => { + // about to user-agent sniff + vary(res, 'User-Agent') + + const ua = req.headers['user-agent'] || '' + const isMobile = /mobi|android|touch|mini/i.test(ua) + + // serve site, depending on isMobile + res.setHeader('Content-Type', 'text/html') + res.end('You are (probably) ' + (isMobile ? '' : 'not ') + 'a mobile user') +}) +``` + +## License + +MIT © [v1rtl](https://v1rtl.site) + +[v-badge-url]: https://img.shields.io/npm/v/@tinyhttp/vary.svg?style=for-the-badge&color=FF69B4&label=&logo=npm +[npm-url]: https://www.npmjs.com/package/@tinyhttp/vary +[cov-badge-url]: https://img.shields.io/coveralls/github/tinyhttp/vary?style=for-the-badge&color=FF69B4 +[cov-url]: https://coveralls.io/github/tinyhttp/vary +[dl-badge-url]: https://img.shields.io/npm/dt/@tinyhttp/vary?style=for-the-badge&color=FF69B4 +[github-actions]: https://github.com/tinyhttp/vary/actions +[gh-actions-img]: https://img.shields.io/github/actions/workflow/status/tinyhttp/vary/main.yml?branch=master&style=for-the-badge&color=FF69B4&label=&logo=github diff --git a/node_modules/@tinyhttp/vary/dist/index.d.ts b/node_modules/@tinyhttp/vary/dist/index.d.ts new file mode 100644 index 0000000..390801b --- /dev/null +++ b/node_modules/@tinyhttp/vary/dist/index.d.ts @@ -0,0 +1,9 @@ +import { ServerResponse } from 'node:http'; + +declare function append(header: string, field: string | string[]): string; +/** + * Mark that a request is varied on a header field. + */ +declare function vary(res: ServerResponse, field: string | string[]): void; + +export { append, vary }; diff --git a/node_modules/@tinyhttp/vary/dist/index.js b/node_modules/@tinyhttp/vary/dist/index.js new file mode 100644 index 0000000..bfcba61 --- /dev/null +++ b/node_modules/@tinyhttp/vary/dist/index.js @@ -0,0 +1 @@ +var FIELD_NAME_REGEXP=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;function parse(header){let end=0;const list=[];let start=0;for(let i=0,len=header.length;i=12.20" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/tinyhttp/vary.git" + }, + "keywords": [ + "http", + "esm", + "es", + "vary", + "nodejs", + "javascript" + ], + "files": [ + "dist" + ], + "author": "v1rtl ", + "license": "MIT", + "bugs": { + "url": "https://github.com/tinyhttp/vary/issues" + }, + "homepage": "https://github.com/tinyhttp/vary#readme", + "devDependencies": { + "@types/node": "^20.7.1", + "@typescript-eslint/eslint-plugin": "^6.7.3", + "@typescript-eslint/parser": "^6.7.3", + "c8": "^8.0.1", + "tsm": "^2.3.0", + "tsup": "^7.2.0", + "typescript": "^5.2.2", + "uvu": "^0.5.6" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "tsup src/index.ts --minify-whitespace --format esm --dts", + "test": "tsm node_modules/uvu/bin.js test", + "test:coverage": "c8 --include=src pnpm test", + "test:report": "c8 report --reporter=text-lcov > coverage.lcov" + } +} \ No newline at end of file diff --git a/node_modules/anymatch/LICENSE b/node_modules/anymatch/LICENSE new file mode 100644 index 0000000..491766c --- /dev/null +++ b/node_modules/anymatch/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2019 Elan Shanker, Paul Miller (https://paulmillr.com) + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/anymatch/README.md b/node_modules/anymatch/README.md new file mode 100644 index 0000000..1dd67f5 --- /dev/null +++ b/node_modules/anymatch/README.md @@ -0,0 +1,87 @@ +anymatch [![Build Status](https://travis-ci.org/micromatch/anymatch.svg?branch=master)](https://travis-ci.org/micromatch/anymatch) [![Coverage Status](https://img.shields.io/coveralls/micromatch/anymatch.svg?branch=master)](https://coveralls.io/r/micromatch/anymatch?branch=master) +====== +Javascript module to match a string against a regular expression, glob, string, +or function that takes the string as an argument and returns a truthy or falsy +value. The matcher can also be an array of any or all of these. Useful for +allowing a very flexible user-defined config to define things like file paths. + +__Note: This module has Bash-parity, please be aware that Windows-style backslashes are not supported as separators. See https://github.com/micromatch/micromatch#backslashes for more information.__ + + +Usage +----- +```sh +npm install anymatch +``` + +#### anymatch(matchers, testString, [returnIndex], [options]) +* __matchers__: (_Array|String|RegExp|Function_) +String to be directly matched, string with glob patterns, regular expression +test, function that takes the testString as an argument and returns a truthy +value if it should be matched, or an array of any number and mix of these types. +* __testString__: (_String|Array_) The string to test against the matchers. If +passed as an array, the first element of the array will be used as the +`testString` for non-function matchers, while the entire array will be applied +as the arguments for function matchers. +* __options__: (_Object_ [optional]_) Any of the [picomatch](https://github.com/micromatch/picomatch#options) options. + * __returnIndex__: (_Boolean [optional]_) If true, return the array index of +the first matcher that that testString matched, or -1 if no match, instead of a +boolean result. + +```js +const anymatch = require('anymatch'); + +const matchers = [ 'path/to/file.js', 'path/anyjs/**/*.js', /foo.js$/, string => string.includes('bar') && string.length > 10 ] ; + +anymatch(matchers, 'path/to/file.js'); // true +anymatch(matchers, 'path/anyjs/baz.js'); // true +anymatch(matchers, 'path/to/foo.js'); // true +anymatch(matchers, 'path/to/bar.js'); // true +anymatch(matchers, 'bar.js'); // false + +// returnIndex = true +anymatch(matchers, 'foo.js', {returnIndex: true}); // 2 +anymatch(matchers, 'path/anyjs/foo.js', {returnIndex: true}); // 1 + +// any picomatc + +// using globs to match directories and their children +anymatch('node_modules', 'node_modules'); // true +anymatch('node_modules', 'node_modules/somelib/index.js'); // false +anymatch('node_modules/**', 'node_modules/somelib/index.js'); // true +anymatch('node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // false +anymatch('**/node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // true + +const matcher = anymatch(matchers); +['foo.js', 'bar.js'].filter(matcher); // [ 'foo.js' ] +anymatch master* ❯ + +``` + +#### anymatch(matchers) +You can also pass in only your matcher(s) to get a curried function that has +already been bound to the provided matching criteria. This can be used as an +`Array#filter` callback. + +```js +var matcher = anymatch(matchers); + +matcher('path/to/file.js'); // true +matcher('path/anyjs/baz.js', true); // 1 + +['foo.js', 'bar.js'].filter(matcher); // ['foo.js'] +``` + +Changelog +---------- +[See release notes page on GitHub](https://github.com/micromatch/anymatch/releases) + +- **v3.0:** Removed `startIndex` and `endIndex` arguments. Node 8.x-only. +- **v2.0:** [micromatch](https://github.com/jonschlinkert/micromatch) moves away from minimatch-parity and inline with Bash. This includes handling backslashes differently (see https://github.com/micromatch/micromatch#backslashes for more information). +- **v1.2:** anymatch uses [micromatch](https://github.com/jonschlinkert/micromatch) +for glob pattern matching. Issues with glob pattern matching should be +reported directly to the [micromatch issue tracker](https://github.com/jonschlinkert/micromatch/issues). + +License +------- +[ISC](https://raw.github.com/micromatch/anymatch/master/LICENSE) diff --git a/node_modules/anymatch/index.d.ts b/node_modules/anymatch/index.d.ts new file mode 100644 index 0000000..3ef7eaa --- /dev/null +++ b/node_modules/anymatch/index.d.ts @@ -0,0 +1,20 @@ +type AnymatchFn = (testString: string) => boolean; +type AnymatchPattern = string|RegExp|AnymatchFn; +type AnymatchMatcher = AnymatchPattern|AnymatchPattern[] +type AnymatchTester = { + (testString: string|any[], returnIndex: true): number; + (testString: string|any[]): boolean; +} + +type PicomatchOptions = {dot: boolean}; + +declare const anymatch: { + (matchers: AnymatchMatcher): AnymatchTester; + (matchers: AnymatchMatcher, testString: null, returnIndex: true | PicomatchOptions): AnymatchTester; + (matchers: AnymatchMatcher, testString: string|any[], returnIndex: true | PicomatchOptions): number; + (matchers: AnymatchMatcher, testString: string|any[]): boolean; +} + +export {AnymatchMatcher as Matcher} +export {AnymatchTester as Tester} +export default anymatch diff --git a/node_modules/anymatch/index.js b/node_modules/anymatch/index.js new file mode 100644 index 0000000..8eb73e9 --- /dev/null +++ b/node_modules/anymatch/index.js @@ -0,0 +1,104 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { value: true }); + +const picomatch = require('picomatch'); +const normalizePath = require('normalize-path'); + +/** + * @typedef {(testString: string) => boolean} AnymatchFn + * @typedef {string|RegExp|AnymatchFn} AnymatchPattern + * @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher + */ +const BANG = '!'; +const DEFAULT_OPTIONS = {returnIndex: false}; +const arrify = (item) => Array.isArray(item) ? item : [item]; + +/** + * @param {AnymatchPattern} matcher + * @param {object} options + * @returns {AnymatchFn} + */ +const createPattern = (matcher, options) => { + if (typeof matcher === 'function') { + return matcher; + } + if (typeof matcher === 'string') { + const glob = picomatch(matcher, options); + return (string) => matcher === string || glob(string); + } + if (matcher instanceof RegExp) { + return (string) => matcher.test(string); + } + return (string) => false; +}; + +/** + * @param {Array} patterns + * @param {Array} negPatterns + * @param {String|Array} args + * @param {Boolean} returnIndex + * @returns {boolean|number} + */ +const matchPatterns = (patterns, negPatterns, args, returnIndex) => { + const isList = Array.isArray(args); + const _path = isList ? args[0] : args; + if (!isList && typeof _path !== 'string') { + throw new TypeError('anymatch: second argument must be a string: got ' + + Object.prototype.toString.call(_path)) + } + const path = normalizePath(_path, false); + + for (let index = 0; index < negPatterns.length; index++) { + const nglob = negPatterns[index]; + if (nglob(path)) { + return returnIndex ? -1 : false; + } + } + + const applied = isList && [path].concat(args.slice(1)); + for (let index = 0; index < patterns.length; index++) { + const pattern = patterns[index]; + if (isList ? pattern(...applied) : pattern(path)) { + return returnIndex ? index : true; + } + } + + return returnIndex ? -1 : false; +}; + +/** + * @param {AnymatchMatcher} matchers + * @param {Array|string} testString + * @param {object} options + * @returns {boolean|number|Function} + */ +const anymatch = (matchers, testString, options = DEFAULT_OPTIONS) => { + if (matchers == null) { + throw new TypeError('anymatch: specify first argument'); + } + const opts = typeof options === 'boolean' ? {returnIndex: options} : options; + const returnIndex = opts.returnIndex || false; + + // Early cache for matchers. + const mtchers = arrify(matchers); + const negatedGlobs = mtchers + .filter(item => typeof item === 'string' && item.charAt(0) === BANG) + .map(item => item.slice(1)) + .map(item => picomatch(item, opts)); + const patterns = mtchers + .filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG)) + .map(matcher => createPattern(matcher, opts)); + + if (testString == null) { + return (testString, ri = false) => { + const returnIndex = typeof ri === 'boolean' ? ri : false; + return matchPatterns(patterns, negatedGlobs, testString, returnIndex); + } + } + + return matchPatterns(patterns, negatedGlobs, testString, returnIndex); +}; + +anymatch.default = anymatch; +module.exports = anymatch; diff --git a/node_modules/anymatch/package.json b/node_modules/anymatch/package.json new file mode 100644 index 0000000..2cb2307 --- /dev/null +++ b/node_modules/anymatch/package.json @@ -0,0 +1,48 @@ +{ + "name": "anymatch", + "version": "3.1.3", + "description": "Matches strings against configurable strings, globs, regular expressions, and/or functions", + "files": [ + "index.js", + "index.d.ts" + ], + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "author": { + "name": "Elan Shanker", + "url": "https://github.com/es128" + }, + "license": "ISC", + "homepage": "https://github.com/micromatch/anymatch", + "repository": { + "type": "git", + "url": "https://github.com/micromatch/anymatch" + }, + "keywords": [ + "match", + "any", + "string", + "file", + "fs", + "list", + "glob", + "regex", + "regexp", + "regular", + "expression", + "function" + ], + "scripts": { + "test": "nyc mocha", + "mocha": "mocha" + }, + "devDependencies": { + "mocha": "^6.1.3", + "nyc": "^14.0.0" + }, + "engines": { + "node": ">= 8" + } +} diff --git a/node_modules/binary-extensions/binary-extensions.json b/node_modules/binary-extensions/binary-extensions.json new file mode 100644 index 0000000..ac08048 --- /dev/null +++ b/node_modules/binary-extensions/binary-extensions.json @@ -0,0 +1,263 @@ +[ + "3dm", + "3ds", + "3g2", + "3gp", + "7z", + "a", + "aac", + "adp", + "afdesign", + "afphoto", + "afpub", + "ai", + "aif", + "aiff", + "alz", + "ape", + "apk", + "appimage", + "ar", + "arj", + "asf", + "au", + "avi", + "bak", + "baml", + "bh", + "bin", + "bk", + "bmp", + "btif", + "bz2", + "bzip2", + "cab", + "caf", + "cgm", + "class", + "cmx", + "cpio", + "cr2", + "cur", + "dat", + "dcm", + "deb", + "dex", + "djvu", + "dll", + "dmg", + "dng", + "doc", + "docm", + "docx", + "dot", + "dotm", + "dra", + "DS_Store", + "dsk", + "dts", + "dtshd", + "dvb", + "dwg", + "dxf", + "ecelp4800", + "ecelp7470", + "ecelp9600", + "egg", + "eol", + "eot", + "epub", + "exe", + "f4v", + "fbs", + "fh", + "fla", + "flac", + "flatpak", + "fli", + "flv", + "fpx", + "fst", + "fvt", + "g3", + "gh", + "gif", + "graffle", + "gz", + "gzip", + "h261", + "h263", + "h264", + "icns", + "ico", + "ief", + "img", + "ipa", + "iso", + "jar", + "jpeg", + "jpg", + "jpgv", + "jpm", + "jxr", + "key", + "ktx", + "lha", + "lib", + "lvp", + "lz", + "lzh", + "lzma", + "lzo", + "m3u", + "m4a", + "m4v", + "mar", + "mdi", + "mht", + "mid", + "midi", + "mj2", + "mka", + "mkv", + "mmr", + "mng", + "mobi", + "mov", + "movie", + "mp3", + "mp4", + "mp4a", + "mpeg", + "mpg", + "mpga", + "mxu", + "nef", + "npx", + "numbers", + "nupkg", + "o", + "odp", + "ods", + "odt", + "oga", + "ogg", + "ogv", + "otf", + "ott", + "pages", + "pbm", + "pcx", + "pdb", + "pdf", + "pea", + "pgm", + "pic", + "png", + "pnm", + "pot", + "potm", + "potx", + "ppa", + "ppam", + "ppm", + "pps", + "ppsm", + "ppsx", + "ppt", + "pptm", + "pptx", + "psd", + "pya", + "pyc", + "pyo", + "pyv", + "qt", + "rar", + "ras", + "raw", + "resources", + "rgb", + "rip", + "rlc", + "rmf", + "rmvb", + "rpm", + "rtf", + "rz", + "s3m", + "s7z", + "scpt", + "sgi", + "shar", + "snap", + "sil", + "sketch", + "slk", + "smv", + "snk", + "so", + "stl", + "suo", + "sub", + "swf", + "tar", + "tbz", + "tbz2", + "tga", + "tgz", + "thmx", + "tif", + "tiff", + "tlz", + "ttc", + "ttf", + "txz", + "udf", + "uvh", + "uvi", + "uvm", + "uvp", + "uvs", + "uvu", + "viv", + "vob", + "war", + "wav", + "wax", + "wbmp", + "wdp", + "weba", + "webm", + "webp", + "whl", + "wim", + "wm", + "wma", + "wmv", + "wmx", + "woff", + "woff2", + "wrm", + "wvx", + "xbm", + "xif", + "xla", + "xlam", + "xls", + "xlsb", + "xlsm", + "xlsx", + "xlt", + "xltm", + "xltx", + "xm", + "xmind", + "xpi", + "xpm", + "xwd", + "xz", + "z", + "zip", + "zipx" +] diff --git a/node_modules/binary-extensions/binary-extensions.json.d.ts b/node_modules/binary-extensions/binary-extensions.json.d.ts new file mode 100644 index 0000000..94a248c --- /dev/null +++ b/node_modules/binary-extensions/binary-extensions.json.d.ts @@ -0,0 +1,3 @@ +declare const binaryExtensionsJson: readonly string[]; + +export = binaryExtensionsJson; diff --git a/node_modules/binary-extensions/index.d.ts b/node_modules/binary-extensions/index.d.ts new file mode 100644 index 0000000..f469ac5 --- /dev/null +++ b/node_modules/binary-extensions/index.d.ts @@ -0,0 +1,14 @@ +/** +List of binary file extensions. + +@example +``` +import binaryExtensions = require('binary-extensions'); + +console.log(binaryExtensions); +//=> ['3ds', '3g2', …] +``` +*/ +declare const binaryExtensions: readonly string[]; + +export = binaryExtensions; diff --git a/node_modules/binary-extensions/index.js b/node_modules/binary-extensions/index.js new file mode 100644 index 0000000..d46e468 --- /dev/null +++ b/node_modules/binary-extensions/index.js @@ -0,0 +1 @@ +module.exports = require('./binary-extensions.json'); diff --git a/node_modules/binary-extensions/license b/node_modules/binary-extensions/license new file mode 100644 index 0000000..5493a1a --- /dev/null +++ b/node_modules/binary-extensions/license @@ -0,0 +1,10 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) +Copyright (c) Paul Miller (https://paulmillr.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/binary-extensions/package.json b/node_modules/binary-extensions/package.json new file mode 100644 index 0000000..4710c33 --- /dev/null +++ b/node_modules/binary-extensions/package.json @@ -0,0 +1,40 @@ +{ + "name": "binary-extensions", + "version": "2.3.0", + "description": "List of binary file extensions", + "license": "MIT", + "repository": "sindresorhus/binary-extensions", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "sideEffects": false, + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts", + "binary-extensions.json", + "binary-extensions.json.d.ts" + ], + "keywords": [ + "binary", + "extensions", + "extension", + "file", + "json", + "list", + "array" + ], + "devDependencies": { + "ava": "^1.4.1", + "tsd": "^0.7.2", + "xo": "^0.24.0" + } +} diff --git a/node_modules/binary-extensions/readme.md b/node_modules/binary-extensions/readme.md new file mode 100644 index 0000000..88519b3 --- /dev/null +++ b/node_modules/binary-extensions/readme.md @@ -0,0 +1,25 @@ +# binary-extensions + +> List of binary file extensions + +The list is just a [JSON file](binary-extensions.json) and can be used anywhere. + +## Install + +```sh +npm install binary-extensions +``` + +## Usage + +```js +const binaryExtensions = require('binary-extensions'); + +console.log(binaryExtensions); +//=> ['3ds', '3g2', …] +``` + +## Related + +- [is-binary-path](https://github.com/sindresorhus/is-binary-path) - Check if a filepath is a binary file +- [text-extensions](https://github.com/sindresorhus/text-extensions) - List of text file extensions diff --git a/node_modules/braces/CHANGELOG.md b/node_modules/braces/CHANGELOG.md new file mode 100644 index 0000000..36f798b --- /dev/null +++ b/node_modules/braces/CHANGELOG.md @@ -0,0 +1,184 @@ +# Release history + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +
+ Guiding Principles + +- Changelogs are for humans, not machines. +- There should be an entry for every single version. +- The same types of changes should be grouped. +- Versions and sections should be linkable. +- The latest version comes first. +- The release date of each versions is displayed. +- Mention whether you follow Semantic Versioning. + +
+ +
+ Types of changes + +Changelog entries are classified using the following labels _(from [keep-a-changelog](http://keepachangelog.com/)_): + +- `Added` for new features. +- `Changed` for changes in existing functionality. +- `Deprecated` for soon-to-be removed features. +- `Removed` for now removed features. +- `Fixed` for any bug fixes. +- `Security` in case of vulnerabilities. + +
+ +## [3.0.0] - 2018-04-08 + +v3.0 is a complete refactor, resulting in a faster, smaller codebase, with fewer deps, and a more accurate parser and compiler. + +**Breaking Changes** + +- The undocumented `.makeRe` method was removed + +**Non-breaking changes** + +- Caching was removed + +## [2.3.2] - 2018-04-08 + +- start refactoring +- cover sets +- better range handling + +## [2.3.1] - 2018-02-17 + +- Remove unnecessary escape in Regex. (#14) + +## [2.3.0] - 2017-10-19 + +- minor code reorganization +- optimize regex +- expose `maxLength` option + +## [2.2.1] - 2017-05-30 + +- don't condense when braces contain extglobs + +## [2.2.0] - 2017-05-28 + +- ensure word boundaries are preserved +- fixes edge case where extglob characters precede a brace pattern + +## [2.1.1] - 2017-04-27 + +- use snapdragon-node +- handle edge case +- optimizations, lint + +## [2.0.4] - 2017-04-11 + +- pass opts to compiler +- minor optimization in create method +- re-write parser handlers to remove negation regex + +## [2.0.3] - 2016-12-10 + +- use split-string +- clear queue at the end +- adds sequences example +- add unit tests + +## [2.0.2] - 2016-10-21 + +- fix comma handling in nested extglobs + +## [2.0.1] - 2016-10-20 + +- add comments +- more tests, ensure quotes are stripped + +## [2.0.0] - 2016-10-19 + +- don't expand braces inside character classes +- add quantifier pattern + +## [1.8.5] - 2016-05-21 + +- Refactor (#10) + +## [1.8.4] - 2016-04-20 + +- fixes https://github.com/jonschlinkert/micromatch/issues/66 + +## [1.8.0] - 2015-03-18 + +- adds exponent examples, tests +- fixes the first example in https://github.com/jonschlinkert/micromatch/issues/38 + +## [1.6.0] - 2015-01-30 + +- optimizations, `bash` mode: +- improve path escaping + +## [1.5.0] - 2015-01-28 + +- Merge pull request #5 from eush77/lib-files + +## [1.4.0] - 2015-01-24 + +- add extglob tests +- externalize exponent function +- better whitespace handling + +## [1.3.0] - 2015-01-24 + +- make regex patterns explicity + +## [1.1.0] - 2015-01-11 + +- don't create a match group with `makeRe` + +## [1.0.0] - 2014-12-23 + +- Merge commit '97b05f5544f8348736a8efaecf5c32bbe3e2ad6e' +- support empty brace syntax +- better bash coverage +- better support for regex strings + +## [0.1.4] - 2014-11-14 + +- improve recognition of bad args, recognize mismatched argument types +- support escaping +- remove pathname-expansion +- support whitespace in patterns + +## [0.1.0] + +- first commit + +[2.3.2]: https://github.com/micromatch/braces/compare/2.3.1...2.3.2 +[2.3.1]: https://github.com/micromatch/braces/compare/2.3.0...2.3.1 +[2.3.0]: https://github.com/micromatch/braces/compare/2.2.1...2.3.0 +[2.2.1]: https://github.com/micromatch/braces/compare/2.2.0...2.2.1 +[2.2.0]: https://github.com/micromatch/braces/compare/2.1.1...2.2.0 +[2.1.1]: https://github.com/micromatch/braces/compare/2.1.0...2.1.1 +[2.1.0]: https://github.com/micromatch/braces/compare/2.0.4...2.1.0 +[2.0.4]: https://github.com/micromatch/braces/compare/2.0.3...2.0.4 +[2.0.3]: https://github.com/micromatch/braces/compare/2.0.2...2.0.3 +[2.0.2]: https://github.com/micromatch/braces/compare/2.0.1...2.0.2 +[2.0.1]: https://github.com/micromatch/braces/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/micromatch/braces/compare/1.8.5...2.0.0 +[1.8.5]: https://github.com/micromatch/braces/compare/1.8.4...1.8.5 +[1.8.4]: https://github.com/micromatch/braces/compare/1.8.0...1.8.4 +[1.8.0]: https://github.com/micromatch/braces/compare/1.6.0...1.8.0 +[1.6.0]: https://github.com/micromatch/braces/compare/1.5.0...1.6.0 +[1.5.0]: https://github.com/micromatch/braces/compare/1.4.0...1.5.0 +[1.4.0]: https://github.com/micromatch/braces/compare/1.3.0...1.4.0 +[1.3.0]: https://github.com/micromatch/braces/compare/1.2.0...1.3.0 +[1.2.0]: https://github.com/micromatch/braces/compare/1.1.0...1.2.0 +[1.1.0]: https://github.com/micromatch/braces/compare/1.0.0...1.1.0 +[1.0.0]: https://github.com/micromatch/braces/compare/0.1.4...1.0.0 +[0.1.4]: https://github.com/micromatch/braces/compare/0.1.0...0.1.4 + +[Unreleased]: https://github.com/micromatch/braces/compare/0.1.0...HEAD +[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog \ No newline at end of file diff --git a/node_modules/braces/LICENSE b/node_modules/braces/LICENSE new file mode 100644 index 0000000..d32ab44 --- /dev/null +++ b/node_modules/braces/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2018, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/braces/README.md b/node_modules/braces/README.md new file mode 100644 index 0000000..cba2f60 --- /dev/null +++ b/node_modules/braces/README.md @@ -0,0 +1,593 @@ +# braces [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [![NPM version](https://img.shields.io/npm/v/braces.svg?style=flat)](https://www.npmjs.com/package/braces) [![NPM monthly downloads](https://img.shields.io/npm/dm/braces.svg?style=flat)](https://npmjs.org/package/braces) [![NPM total downloads](https://img.shields.io/npm/dt/braces.svg?style=flat)](https://npmjs.org/package/braces) [![Linux Build Status](https://img.shields.io/travis/micromatch/braces.svg?style=flat&label=Travis)](https://travis-ci.org/micromatch/braces) + +> Bash-like brace expansion, implemented in JavaScript. Safer than other brace expansion libs, with complete support for the Bash 4.3 braces specification, without sacrificing speed. + +Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save braces +``` + +## v3.0.0 Released!! + +See the [changelog](CHANGELOG.md) for details. + +## Why use braces? + +Brace patterns make globs more powerful by adding the ability to match specific ranges and sequences of characters. + +* **Accurate** - complete support for the [Bash 4.3 Brace Expansion](www.gnu.org/software/bash/) specification (passes all of the Bash braces tests) +* **[fast and performant](#benchmarks)** - Starts fast, runs fast and [scales well](#performance) as patterns increase in complexity. +* **Organized code base** - The parser and compiler are easy to maintain and update when edge cases crop up. +* **Well-tested** - Thousands of test assertions, and passes all of the Bash, minimatch, and [brace-expansion](https://github.com/juliangruber/brace-expansion) unit tests (as of the date this was written). +* **Safer** - You shouldn't have to worry about users defining aggressive or malicious brace patterns that can break your application. Braces takes measures to prevent malicious regex that can be used for DDoS attacks (see [catastrophic backtracking](https://www.regular-expressions.info/catastrophic.html)). +* [Supports lists](#lists) - (aka "sets") `a/{b,c}/d` => `['a/b/d', 'a/c/d']` +* [Supports sequences](#sequences) - (aka "ranges") `{01..03}` => `['01', '02', '03']` +* [Supports steps](#steps) - (aka "increments") `{2..10..2}` => `['2', '4', '6', '8', '10']` +* [Supports escaping](#escaping) - To prevent evaluation of special characters. + +## Usage + +The main export is a function that takes one or more brace `patterns` and `options`. + +```js +const braces = require('braces'); +// braces(patterns[, options]); + +console.log(braces(['{01..05}', '{a..e}'])); +//=> ['(0[1-5])', '([a-e])'] + +console.log(braces(['{01..05}', '{a..e}'], { expand: true })); +//=> ['01', '02', '03', '04', '05', 'a', 'b', 'c', 'd', 'e'] +``` + +### Brace Expansion vs. Compilation + +By default, brace patterns are compiled into strings that are optimized for creating regular expressions and matching. + +**Compiled** + +```js +console.log(braces('a/{x,y,z}/b')); +//=> ['a/(x|y|z)/b'] +console.log(braces(['a/{01..20}/b', 'a/{1..5}/b'])); +//=> [ 'a/(0[1-9]|1[0-9]|20)/b', 'a/([1-5])/b' ] +``` + +**Expanded** + +Enable brace expansion by setting the `expand` option to true, or by using [braces.expand()](#expand) (returns an array similar to what you'd expect from Bash, or `echo {1..5}`, or [minimatch](https://github.com/isaacs/minimatch)): + +```js +console.log(braces('a/{x,y,z}/b', { expand: true })); +//=> ['a/x/b', 'a/y/b', 'a/z/b'] + +console.log(braces.expand('{01..10}')); +//=> ['01','02','03','04','05','06','07','08','09','10'] +``` + +### Lists + +Expand lists (like Bash "sets"): + +```js +console.log(braces('a/{foo,bar,baz}/*.js')); +//=> ['a/(foo|bar|baz)/*.js'] + +console.log(braces.expand('a/{foo,bar,baz}/*.js')); +//=> ['a/foo/*.js', 'a/bar/*.js', 'a/baz/*.js'] +``` + +### Sequences + +Expand ranges of characters (like Bash "sequences"): + +```js +console.log(braces.expand('{1..3}')); // ['1', '2', '3'] +console.log(braces.expand('a/{1..3}/b')); // ['a/1/b', 'a/2/b', 'a/3/b'] +console.log(braces('{a..c}', { expand: true })); // ['a', 'b', 'c'] +console.log(braces('foo/{a..c}', { expand: true })); // ['foo/a', 'foo/b', 'foo/c'] + +// supports zero-padded ranges +console.log(braces('a/{01..03}/b')); //=> ['a/(0[1-3])/b'] +console.log(braces('a/{001..300}/b')); //=> ['a/(0{2}[1-9]|0[1-9][0-9]|[12][0-9]{2}|300)/b'] +``` + +See [fill-range](https://github.com/jonschlinkert/fill-range) for all available range-expansion options. + +### Steppped ranges + +Steps, or increments, may be used with ranges: + +```js +console.log(braces.expand('{2..10..2}')); +//=> ['2', '4', '6', '8', '10'] + +console.log(braces('{2..10..2}')); +//=> ['(2|4|6|8|10)'] +``` + +When the [.optimize](#optimize) method is used, or [options.optimize](#optionsoptimize) is set to true, sequences are passed to [to-regex-range](https://github.com/jonschlinkert/to-regex-range) for expansion. + +### Nesting + +Brace patterns may be nested. The results of each expanded string are not sorted, and left to right order is preserved. + +**"Expanded" braces** + +```js +console.log(braces.expand('a{b,c,/{x,y}}/e')); +//=> ['ab/e', 'ac/e', 'a/x/e', 'a/y/e'] + +console.log(braces.expand('a/{x,{1..5},y}/c')); +//=> ['a/x/c', 'a/1/c', 'a/2/c', 'a/3/c', 'a/4/c', 'a/5/c', 'a/y/c'] +``` + +**"Optimized" braces** + +```js +console.log(braces('a{b,c,/{x,y}}/e')); +//=> ['a(b|c|/(x|y))/e'] + +console.log(braces('a/{x,{1..5},y}/c')); +//=> ['a/(x|([1-5])|y)/c'] +``` + +### Escaping + +**Escaping braces** + +A brace pattern will not be expanded or evaluted if _either the opening or closing brace is escaped_: + +```js +console.log(braces.expand('a\\{d,c,b}e')); +//=> ['a{d,c,b}e'] + +console.log(braces.expand('a{d,c,b\\}e')); +//=> ['a{d,c,b}e'] +``` + +**Escaping commas** + +Commas inside braces may also be escaped: + +```js +console.log(braces.expand('a{b\\,c}d')); +//=> ['a{b,c}d'] + +console.log(braces.expand('a{d\\,c,b}e')); +//=> ['ad,ce', 'abe'] +``` + +**Single items** + +Following bash conventions, a brace pattern is also not expanded when it contains a single character: + +```js +console.log(braces.expand('a{b}c')); +//=> ['a{b}c'] +``` + +## Options + +### options.maxLength + +**Type**: `Number` + +**Default**: `65,536` + +**Description**: Limit the length of the input string. Useful when the input string is generated or your application allows users to pass a string, et cetera. + +```js +console.log(braces('a/{b,c}/d', { maxLength: 3 })); //=> throws an error +``` + +### options.expand + +**Type**: `Boolean` + +**Default**: `undefined` + +**Description**: Generate an "expanded" brace pattern (alternatively you can use the `braces.expand()` method, which does the same thing). + +```js +console.log(braces('a/{b,c}/d', { expand: true })); +//=> [ 'a/b/d', 'a/c/d' ] +``` + +### options.nodupes + +**Type**: `Boolean` + +**Default**: `undefined` + +**Description**: Remove duplicates from the returned array. + +### options.rangeLimit + +**Type**: `Number` + +**Default**: `1000` + +**Description**: To prevent malicious patterns from being passed by users, an error is thrown when `braces.expand()` is used or `options.expand` is true and the generated range will exceed the `rangeLimit`. + +You can customize `options.rangeLimit` or set it to `Inifinity` to disable this altogether. + +**Examples** + +```js +// pattern exceeds the "rangeLimit", so it's optimized automatically +console.log(braces.expand('{1..1000}')); +//=> ['([1-9]|[1-9][0-9]{1,2}|1000)'] + +// pattern does not exceed "rangeLimit", so it's NOT optimized +console.log(braces.expand('{1..100}')); +//=> ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100'] +``` + +### options.transform + +**Type**: `Function` + +**Default**: `undefined` + +**Description**: Customize range expansion. + +**Example: Transforming non-numeric values** + +```js +const alpha = braces.expand('x/{a..e}/y', { + transform(value, index) { + // When non-numeric values are passed, "value" is a character code. + return 'foo/' + String.fromCharCode(value) + '-' + index; + } +}); +console.log(alpha); +//=> [ 'x/foo/a-0/y', 'x/foo/b-1/y', 'x/foo/c-2/y', 'x/foo/d-3/y', 'x/foo/e-4/y' ] +``` + +**Example: Transforming numeric values** + +```js +const numeric = braces.expand('{1..5}', { + transform(value) { + // when numeric values are passed, "value" is a number + return 'foo/' + value * 2; + } +}); +console.log(numeric); +//=> [ 'foo/2', 'foo/4', 'foo/6', 'foo/8', 'foo/10' ] +``` + +### options.quantifiers + +**Type**: `Boolean` + +**Default**: `undefined` + +**Description**: In regular expressions, quanitifiers can be used to specify how many times a token can be repeated. For example, `a{1,3}` will match the letter `a` one to three times. + +Unfortunately, regex quantifiers happen to share the same syntax as [Bash lists](#lists) + +The `quantifiers` option tells braces to detect when [regex quantifiers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#quantifiers) are defined in the given pattern, and not to try to expand them as lists. + +**Examples** + +```js +const braces = require('braces'); +console.log(braces('a/b{1,3}/{x,y,z}')); +//=> [ 'a/b(1|3)/(x|y|z)' ] +console.log(braces('a/b{1,3}/{x,y,z}', {quantifiers: true})); +//=> [ 'a/b{1,3}/(x|y|z)' ] +console.log(braces('a/b{1,3}/{x,y,z}', {quantifiers: true, expand: true})); +//=> [ 'a/b{1,3}/x', 'a/b{1,3}/y', 'a/b{1,3}/z' ] +``` + +### options.unescape + +**Type**: `Boolean` + +**Default**: `undefined` + +**Description**: Strip backslashes that were used for escaping from the result. + +## What is "brace expansion"? + +Brace expansion is a type of parameter expansion that was made popular by unix shells for generating lists of strings, as well as regex-like matching when used alongside wildcards (globs). + +In addition to "expansion", braces are also used for matching. In other words: + +* [brace expansion](#brace-expansion) is for generating new lists +* [brace matching](#brace-matching) is for filtering existing lists + +
+More about brace expansion (click to expand) + +There are two main types of brace expansion: + +1. **lists**: which are defined using comma-separated values inside curly braces: `{a,b,c}` +2. **sequences**: which are defined using a starting value and an ending value, separated by two dots: `a{1..3}b`. Optionally, a third argument may be passed to define a "step" or increment to use: `a{1..100..10}b`. These are also sometimes referred to as "ranges". + +Here are some example brace patterns to illustrate how they work: + +**Sets** + +``` +{a,b,c} => a b c +{a,b,c}{1,2} => a1 a2 b1 b2 c1 c2 +``` + +**Sequences** + +``` +{1..9} => 1 2 3 4 5 6 7 8 9 +{4..-4} => 4 3 2 1 0 -1 -2 -3 -4 +{1..20..3} => 1 4 7 10 13 16 19 +{a..j} => a b c d e f g h i j +{j..a} => j i h g f e d c b a +{a..z..3} => a d g j m p s v y +``` + +**Combination** + +Sets and sequences can be mixed together or used along with any other strings. + +``` +{a,b,c}{1..3} => a1 a2 a3 b1 b2 b3 c1 c2 c3 +foo/{a,b,c}/bar => foo/a/bar foo/b/bar foo/c/bar +``` + +The fact that braces can be "expanded" from relatively simple patterns makes them ideal for quickly generating test fixtures, file paths, and similar use cases. + +## Brace matching + +In addition to _expansion_, brace patterns are also useful for performing regular-expression-like matching. + +For example, the pattern `foo/{1..3}/bar` would match any of following strings: + +``` +foo/1/bar +foo/2/bar +foo/3/bar +``` + +But not: + +``` +baz/1/qux +baz/2/qux +baz/3/qux +``` + +Braces can also be combined with [glob patterns](https://github.com/jonschlinkert/micromatch) to perform more advanced wildcard matching. For example, the pattern `*/{1..3}/*` would match any of following strings: + +``` +foo/1/bar +foo/2/bar +foo/3/bar +baz/1/qux +baz/2/qux +baz/3/qux +``` + +## Brace matching pitfalls + +Although brace patterns offer a user-friendly way of matching ranges or sets of strings, there are also some major disadvantages and potential risks you should be aware of. + +### tldr + +**"brace bombs"** + +* brace expansion can eat up a huge amount of processing resources +* as brace patterns increase _linearly in size_, the system resources required to expand the pattern increase exponentially +* users can accidentally (or intentially) exhaust your system's resources resulting in the equivalent of a DoS attack (bonus: no programming knowledge is required!) + +For a more detailed explanation with examples, see the [geometric complexity](#geometric-complexity) section. + +### The solution + +Jump to the [performance section](#performance) to see how Braces solves this problem in comparison to other libraries. + +### Geometric complexity + +At minimum, brace patterns with sets limited to two elements have quadradic or `O(n^2)` complexity. But the complexity of the algorithm increases exponentially as the number of sets, _and elements per set_, increases, which is `O(n^c)`. + +For example, the following sets demonstrate quadratic (`O(n^2)`) complexity: + +``` +{1,2}{3,4} => (2X2) => 13 14 23 24 +{1,2}{3,4}{5,6} => (2X2X2) => 135 136 145 146 235 236 245 246 +``` + +But add an element to a set, and we get a n-fold Cartesian product with `O(n^c)` complexity: + +``` +{1,2,3}{4,5,6}{7,8,9} => (3X3X3) => 147 148 149 157 158 159 167 168 169 247 248 + 249 257 258 259 267 268 269 347 348 349 357 + 358 359 367 368 369 +``` + +Now, imagine how this complexity grows given that each element is a n-tuple: + +``` +{1..100}{1..100} => (100X100) => 10,000 elements (38.4 kB) +{1..100}{1..100}{1..100} => (100X100X100) => 1,000,000 elements (5.76 MB) +``` + +Although these examples are clearly contrived, they demonstrate how brace patterns can quickly grow out of control. + +**More information** + +Interested in learning more about brace expansion? + +* [linuxjournal/bash-brace-expansion](http://www.linuxjournal.com/content/bash-brace-expansion) +* [rosettacode/Brace_expansion](https://rosettacode.org/wiki/Brace_expansion) +* [cartesian product](https://en.wikipedia.org/wiki/Cartesian_product) + +
+ +## Performance + +Braces is not only screaming fast, it's also more accurate the other brace expansion libraries. + +### Better algorithms + +Fortunately there is a solution to the ["brace bomb" problem](#brace-matching-pitfalls): _don't expand brace patterns into an array when they're used for matching_. + +Instead, convert the pattern into an optimized regular expression. This is easier said than done, and braces is the only library that does this currently. + +**The proof is in the numbers** + +Minimatch gets exponentially slower as patterns increase in complexity, braces does not. The following results were generated using `braces()` and `minimatch.braceExpand()`, respectively. + +| **Pattern** | **braces** | **[minimatch][]** | +| --- | --- | --- | +| `{1..9007199254740991}`[^1] | `298 B` (5ms 459μs)| N/A (freezes) | +| `{1..1000000000000000}` | `41 B` (1ms 15μs) | N/A (freezes) | +| `{1..100000000000000}` | `40 B` (890μs) | N/A (freezes) | +| `{1..10000000000000}` | `39 B` (2ms 49μs) | N/A (freezes) | +| `{1..1000000000000}` | `38 B` (608μs) | N/A (freezes) | +| `{1..100000000000}` | `37 B` (397μs) | N/A (freezes) | +| `{1..10000000000}` | `35 B` (983μs) | N/A (freezes) | +| `{1..1000000000}` | `34 B` (798μs) | N/A (freezes) | +| `{1..100000000}` | `33 B` (733μs) | N/A (freezes) | +| `{1..10000000}` | `32 B` (5ms 632μs) | `78.89 MB` (16s 388ms 569μs) | +| `{1..1000000}` | `31 B` (1ms 381μs) | `6.89 MB` (1s 496ms 887μs) | +| `{1..100000}` | `30 B` (950μs) | `588.89 kB` (146ms 921μs) | +| `{1..10000}` | `29 B` (1ms 114μs) | `48.89 kB` (14ms 187μs) | +| `{1..1000}` | `28 B` (760μs) | `3.89 kB` (1ms 453μs) | +| `{1..100}` | `22 B` (345μs) | `291 B` (196μs) | +| `{1..10}` | `10 B` (533μs) | `20 B` (37μs) | +| `{1..3}` | `7 B` (190μs) | `5 B` (27μs) | + +### Faster algorithms + +When you need expansion, braces is still much faster. + +_(the following results were generated using `braces.expand()` and `minimatch.braceExpand()`, respectively)_ + +| **Pattern** | **braces** | **[minimatch][]** | +| --- | --- | --- | +| `{1..10000000}` | `78.89 MB` (2s 698ms 642μs) | `78.89 MB` (18s 601ms 974μs) | +| `{1..1000000}` | `6.89 MB` (458ms 576μs) | `6.89 MB` (1s 491ms 621μs) | +| `{1..100000}` | `588.89 kB` (20ms 728μs) | `588.89 kB` (156ms 919μs) | +| `{1..10000}` | `48.89 kB` (2ms 202μs) | `48.89 kB` (13ms 641μs) | +| `{1..1000}` | `3.89 kB` (1ms 796μs) | `3.89 kB` (1ms 958μs) | +| `{1..100}` | `291 B` (424μs) | `291 B` (211μs) | +| `{1..10}` | `20 B` (487μs) | `20 B` (72μs) | +| `{1..3}` | `5 B` (166μs) | `5 B` (27μs) | + +If you'd like to run these comparisons yourself, see [test/support/generate.js](test/support/generate.js). + +## Benchmarks + +### Running benchmarks + +Install dev dependencies: + +```bash +npm i -d && npm benchmark +``` + +### Latest results + +Braces is more accurate, without sacrificing performance. + +```bash +# range (expanded) + braces x 29,040 ops/sec ±3.69% (91 runs sampled)) + minimatch x 4,735 ops/sec ±1.28% (90 runs sampled) + +# range (optimized for regex) + braces x 382,878 ops/sec ±0.56% (94 runs sampled) + minimatch x 1,040 ops/sec ±0.44% (93 runs sampled) + +# nested ranges (expanded) + braces x 19,744 ops/sec ±2.27% (92 runs sampled)) + minimatch x 4,579 ops/sec ±0.50% (93 runs sampled) + +# nested ranges (optimized for regex) + braces x 246,019 ops/sec ±2.02% (93 runs sampled) + minimatch x 1,028 ops/sec ±0.39% (94 runs sampled) + +# set (expanded) + braces x 138,641 ops/sec ±0.53% (95 runs sampled) + minimatch x 219,582 ops/sec ±0.98% (94 runs sampled) + +# set (optimized for regex) + braces x 388,408 ops/sec ±0.41% (95 runs sampled) + minimatch x 44,724 ops/sec ±0.91% (89 runs sampled) + +# nested sets (expanded) + braces x 84,966 ops/sec ±0.48% (94 runs sampled) + minimatch x 140,720 ops/sec ±0.37% (95 runs sampled) + +# nested sets (optimized for regex) + braces x 263,340 ops/sec ±2.06% (92 runs sampled) + minimatch x 28,714 ops/sec ±0.40% (90 runs sampled) +``` + +## About + +
+Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +
+ +
+Running Tests + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +$ npm install && npm test +``` + +
+ +
+Building docs + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +$ npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +
+ +### Contributors + +| **Commits** | **Contributor** | +| --- | --- | +| 197 | [jonschlinkert](https://github.com/jonschlinkert) | +| 4 | [doowb](https://github.com/doowb) | +| 1 | [es128](https://github.com/es128) | +| 1 | [eush77](https://github.com/eush77) | +| 1 | [hemanth](https://github.com/hemanth) | +| 1 | [wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg) | + +### Author + +**Jon Schlinkert** + +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) + +### License + +Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 08, 2019._ \ No newline at end of file diff --git a/node_modules/braces/index.js b/node_modules/braces/index.js new file mode 100644 index 0000000..0eee0f5 --- /dev/null +++ b/node_modules/braces/index.js @@ -0,0 +1,170 @@ +'use strict'; + +const stringify = require('./lib/stringify'); +const compile = require('./lib/compile'); +const expand = require('./lib/expand'); +const parse = require('./lib/parse'); + +/** + * Expand the given pattern or create a regex-compatible string. + * + * ```js + * const braces = require('braces'); + * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] + * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {String} + * @api public + */ + +const braces = (input, options = {}) => { + let output = []; + + if (Array.isArray(input)) { + for (let pattern of input) { + let result = braces.create(pattern, options); + if (Array.isArray(result)) { + output.push(...result); + } else { + output.push(result); + } + } + } else { + output = [].concat(braces.create(input, options)); + } + + if (options && options.expand === true && options.nodupes === true) { + output = [...new Set(output)]; + } + return output; +}; + +/** + * Parse the given `str` with the given `options`. + * + * ```js + * // braces.parse(pattern, [, options]); + * const ast = braces.parse('a/{b,c}/d'); + * console.log(ast); + * ``` + * @param {String} pattern Brace pattern to parse + * @param {Object} options + * @return {Object} Returns an AST + * @api public + */ + +braces.parse = (input, options = {}) => parse(input, options); + +/** + * Creates a braces string from an AST, or an AST node. + * + * ```js + * const braces = require('braces'); + * let ast = braces.parse('foo/{a,b}/bar'); + * console.log(stringify(ast.nodes[2])); //=> '{a,b}' + * ``` + * @param {String} `input` Brace pattern or AST. + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.stringify = (input, options = {}) => { + if (typeof input === 'string') { + return stringify(braces.parse(input, options), options); + } + return stringify(input, options); +}; + +/** + * Compiles a brace pattern into a regex-compatible, optimized string. + * This method is called by the main [braces](#braces) function by default. + * + * ```js + * const braces = require('braces'); + * console.log(braces.compile('a/{b,c}/d')); + * //=> ['a/(b|c)/d'] + * ``` + * @param {String} `input` Brace pattern or AST. + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.compile = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); + } + return compile(input, options); +}; + +/** + * Expands a brace pattern into an array. This method is called by the + * main [braces](#braces) function when `options.expand` is true. Before + * using this method it's recommended that you read the [performance notes](#performance)) + * and advantages of using [.compile](#compile) instead. + * + * ```js + * const braces = require('braces'); + * console.log(braces.expand('a/{b,c}/d')); + * //=> ['a/b/d', 'a/c/d']; + * ``` + * @param {String} `pattern` Brace pattern + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.expand = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); + } + + let result = expand(input, options); + + // filter out empty strings if specified + if (options.noempty === true) { + result = result.filter(Boolean); + } + + // filter out duplicates if specified + if (options.nodupes === true) { + result = [...new Set(result)]; + } + + return result; +}; + +/** + * Processes a brace pattern and returns either an expanded array + * (if `options.expand` is true), a highly optimized regex-compatible string. + * This method is called by the main [braces](#braces) function. + * + * ```js + * const braces = require('braces'); + * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) + * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' + * ``` + * @param {String} `pattern` Brace pattern + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.create = (input, options = {}) => { + if (input === '' || input.length < 3) { + return [input]; + } + + return options.expand !== true + ? braces.compile(input, options) + : braces.expand(input, options); +}; + +/** + * Expose "braces" + */ + +module.exports = braces; diff --git a/node_modules/braces/lib/compile.js b/node_modules/braces/lib/compile.js new file mode 100644 index 0000000..3e984a4 --- /dev/null +++ b/node_modules/braces/lib/compile.js @@ -0,0 +1,57 @@ +'use strict'; + +const fill = require('fill-range'); +const utils = require('./utils'); + +const compile = (ast, options = {}) => { + let walk = (node, parent = {}) => { + let invalidBlock = utils.isInvalidBrace(parent); + let invalidNode = node.invalid === true && options.escapeInvalid === true; + let invalid = invalidBlock === true || invalidNode === true; + let prefix = options.escapeInvalid === true ? '\\' : ''; + let output = ''; + + if (node.isOpen === true) { + return prefix + node.value; + } + if (node.isClose === true) { + return prefix + node.value; + } + + if (node.type === 'open') { + return invalid ? (prefix + node.value) : '('; + } + + if (node.type === 'close') { + return invalid ? (prefix + node.value) : ')'; + } + + if (node.type === 'comma') { + return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|'); + } + + if (node.value) { + return node.value; + } + + if (node.nodes && node.ranges > 0) { + let args = utils.reduce(node.nodes); + let range = fill(...args, { ...options, wrap: false, toRegex: true }); + + if (range.length !== 0) { + return args.length > 1 && range.length > 1 ? `(${range})` : range; + } + } + + if (node.nodes) { + for (let child of node.nodes) { + output += walk(child, node); + } + } + return output; + }; + + return walk(ast); +}; + +module.exports = compile; diff --git a/node_modules/braces/lib/constants.js b/node_modules/braces/lib/constants.js new file mode 100644 index 0000000..a937943 --- /dev/null +++ b/node_modules/braces/lib/constants.js @@ -0,0 +1,57 @@ +'use strict'; + +module.exports = { + MAX_LENGTH: 1024 * 64, + + // Digits + CHAR_0: '0', /* 0 */ + CHAR_9: '9', /* 9 */ + + // Alphabet chars. + CHAR_UPPERCASE_A: 'A', /* A */ + CHAR_LOWERCASE_A: 'a', /* a */ + CHAR_UPPERCASE_Z: 'Z', /* Z */ + CHAR_LOWERCASE_Z: 'z', /* z */ + + CHAR_LEFT_PARENTHESES: '(', /* ( */ + CHAR_RIGHT_PARENTHESES: ')', /* ) */ + + CHAR_ASTERISK: '*', /* * */ + + // Non-alphabetic chars. + CHAR_AMPERSAND: '&', /* & */ + CHAR_AT: '@', /* @ */ + CHAR_BACKSLASH: '\\', /* \ */ + CHAR_BACKTICK: '`', /* ` */ + CHAR_CARRIAGE_RETURN: '\r', /* \r */ + CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ + CHAR_COLON: ':', /* : */ + CHAR_COMMA: ',', /* , */ + CHAR_DOLLAR: '$', /* . */ + CHAR_DOT: '.', /* . */ + CHAR_DOUBLE_QUOTE: '"', /* " */ + CHAR_EQUAL: '=', /* = */ + CHAR_EXCLAMATION_MARK: '!', /* ! */ + CHAR_FORM_FEED: '\f', /* \f */ + CHAR_FORWARD_SLASH: '/', /* / */ + CHAR_HASH: '#', /* # */ + CHAR_HYPHEN_MINUS: '-', /* - */ + CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ + CHAR_LEFT_CURLY_BRACE: '{', /* { */ + CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ + CHAR_LINE_FEED: '\n', /* \n */ + CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ + CHAR_PERCENT: '%', /* % */ + CHAR_PLUS: '+', /* + */ + CHAR_QUESTION_MARK: '?', /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ + CHAR_RIGHT_CURLY_BRACE: '}', /* } */ + CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ + CHAR_SEMICOLON: ';', /* ; */ + CHAR_SINGLE_QUOTE: '\'', /* ' */ + CHAR_SPACE: ' ', /* */ + CHAR_TAB: '\t', /* \t */ + CHAR_UNDERSCORE: '_', /* _ */ + CHAR_VERTICAL_LINE: '|', /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ +}; diff --git a/node_modules/braces/lib/expand.js b/node_modules/braces/lib/expand.js new file mode 100644 index 0000000..376c748 --- /dev/null +++ b/node_modules/braces/lib/expand.js @@ -0,0 +1,113 @@ +'use strict'; + +const fill = require('fill-range'); +const stringify = require('./stringify'); +const utils = require('./utils'); + +const append = (queue = '', stash = '', enclose = false) => { + let result = []; + + queue = [].concat(queue); + stash = [].concat(stash); + + if (!stash.length) return queue; + if (!queue.length) { + return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; + } + + for (let item of queue) { + if (Array.isArray(item)) { + for (let value of item) { + result.push(append(value, stash, enclose)); + } + } else { + for (let ele of stash) { + if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; + result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele)); + } + } + } + return utils.flatten(result); +}; + +const expand = (ast, options = {}) => { + let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; + + let walk = (node, parent = {}) => { + node.queue = []; + + let p = parent; + let q = parent.queue; + + while (p.type !== 'brace' && p.type !== 'root' && p.parent) { + p = p.parent; + q = p.queue; + } + + if (node.invalid || node.dollar) { + q.push(append(q.pop(), stringify(node, options))); + return; + } + + if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { + q.push(append(q.pop(), ['{}'])); + return; + } + + if (node.nodes && node.ranges > 0) { + let args = utils.reduce(node.nodes); + + if (utils.exceedsLimit(...args, options.step, rangeLimit)) { + throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); + } + + let range = fill(...args, options); + if (range.length === 0) { + range = stringify(node, options); + } + + q.push(append(q.pop(), range)); + node.nodes = []; + return; + } + + let enclose = utils.encloseBrace(node); + let queue = node.queue; + let block = node; + + while (block.type !== 'brace' && block.type !== 'root' && block.parent) { + block = block.parent; + queue = block.queue; + } + + for (let i = 0; i < node.nodes.length; i++) { + let child = node.nodes[i]; + + if (child.type === 'comma' && node.type === 'brace') { + if (i === 1) queue.push(''); + queue.push(''); + continue; + } + + if (child.type === 'close') { + q.push(append(q.pop(), queue, enclose)); + continue; + } + + if (child.value && child.type !== 'open') { + queue.push(append(queue.pop(), child.value)); + continue; + } + + if (child.nodes) { + walk(child, node); + } + } + + return queue; + }; + + return utils.flatten(walk(ast)); +}; + +module.exports = expand; diff --git a/node_modules/braces/lib/parse.js b/node_modules/braces/lib/parse.js new file mode 100644 index 0000000..145ea26 --- /dev/null +++ b/node_modules/braces/lib/parse.js @@ -0,0 +1,333 @@ +'use strict'; + +const stringify = require('./stringify'); + +/** + * Constants + */ + +const { + MAX_LENGTH, + CHAR_BACKSLASH, /* \ */ + CHAR_BACKTICK, /* ` */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_RIGHT_SQUARE_BRACKET, /* ] */ + CHAR_DOUBLE_QUOTE, /* " */ + CHAR_SINGLE_QUOTE, /* ' */ + CHAR_NO_BREAK_SPACE, + CHAR_ZERO_WIDTH_NOBREAK_SPACE +} = require('./constants'); + +/** + * parse + */ + +const parse = (input, options = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); + } + + let opts = options || {}; + let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + if (input.length > max) { + throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); + } + + let ast = { type: 'root', input, nodes: [] }; + let stack = [ast]; + let block = ast; + let prev = ast; + let brackets = 0; + let length = input.length; + let index = 0; + let depth = 0; + let value; + let memo = {}; + + /** + * Helpers + */ + + const advance = () => input[index++]; + const push = node => { + if (node.type === 'text' && prev.type === 'dot') { + prev.type = 'text'; + } + + if (prev && prev.type === 'text' && node.type === 'text') { + prev.value += node.value; + return; + } + + block.nodes.push(node); + node.parent = block; + node.prev = prev; + prev = node; + return node; + }; + + push({ type: 'bos' }); + + while (index < length) { + block = stack[stack.length - 1]; + value = advance(); + + /** + * Invalid chars + */ + + if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { + continue; + } + + /** + * Escaped chars + */ + + if (value === CHAR_BACKSLASH) { + push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); + continue; + } + + /** + * Right square bracket (literal): ']' + */ + + if (value === CHAR_RIGHT_SQUARE_BRACKET) { + push({ type: 'text', value: '\\' + value }); + continue; + } + + /** + * Left square bracket: '[' + */ + + if (value === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; + + let closed = true; + let next; + + while (index < length && (next = advance())) { + value += next; + + if (next === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; + continue; + } + + if (next === CHAR_BACKSLASH) { + value += advance(); + continue; + } + + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + brackets--; + + if (brackets === 0) { + break; + } + } + } + + push({ type: 'text', value }); + continue; + } + + /** + * Parentheses + */ + + if (value === CHAR_LEFT_PARENTHESES) { + block = push({ type: 'paren', nodes: [] }); + stack.push(block); + push({ type: 'text', value }); + continue; + } + + if (value === CHAR_RIGHT_PARENTHESES) { + if (block.type !== 'paren') { + push({ type: 'text', value }); + continue; + } + block = stack.pop(); + push({ type: 'text', value }); + block = stack[stack.length - 1]; + continue; + } + + /** + * Quotes: '|"|` + */ + + if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { + let open = value; + let next; + + if (options.keepQuotes !== true) { + value = ''; + } + + while (index < length && (next = advance())) { + if (next === CHAR_BACKSLASH) { + value += next + advance(); + continue; + } + + if (next === open) { + if (options.keepQuotes === true) value += next; + break; + } + + value += next; + } + + push({ type: 'text', value }); + continue; + } + + /** + * Left curly brace: '{' + */ + + if (value === CHAR_LEFT_CURLY_BRACE) { + depth++; + + let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; + let brace = { + type: 'brace', + open: true, + close: false, + dollar, + depth, + commas: 0, + ranges: 0, + nodes: [] + }; + + block = push(brace); + stack.push(block); + push({ type: 'open', value }); + continue; + } + + /** + * Right curly brace: '}' + */ + + if (value === CHAR_RIGHT_CURLY_BRACE) { + if (block.type !== 'brace') { + push({ type: 'text', value }); + continue; + } + + let type = 'close'; + block = stack.pop(); + block.close = true; + + push({ type, value }); + depth--; + + block = stack[stack.length - 1]; + continue; + } + + /** + * Comma: ',' + */ + + if (value === CHAR_COMMA && depth > 0) { + if (block.ranges > 0) { + block.ranges = 0; + let open = block.nodes.shift(); + block.nodes = [open, { type: 'text', value: stringify(block) }]; + } + + push({ type: 'comma', value }); + block.commas++; + continue; + } + + /** + * Dot: '.' + */ + + if (value === CHAR_DOT && depth > 0 && block.commas === 0) { + let siblings = block.nodes; + + if (depth === 0 || siblings.length === 0) { + push({ type: 'text', value }); + continue; + } + + if (prev.type === 'dot') { + block.range = []; + prev.value += value; + prev.type = 'range'; + + if (block.nodes.length !== 3 && block.nodes.length !== 5) { + block.invalid = true; + block.ranges = 0; + prev.type = 'text'; + continue; + } + + block.ranges++; + block.args = []; + continue; + } + + if (prev.type === 'range') { + siblings.pop(); + + let before = siblings[siblings.length - 1]; + before.value += prev.value + value; + prev = before; + block.ranges--; + continue; + } + + push({ type: 'dot', value }); + continue; + } + + /** + * Text + */ + + push({ type: 'text', value }); + } + + // Mark imbalanced braces and brackets as invalid + do { + block = stack.pop(); + + if (block.type !== 'root') { + block.nodes.forEach(node => { + if (!node.nodes) { + if (node.type === 'open') node.isOpen = true; + if (node.type === 'close') node.isClose = true; + if (!node.nodes) node.type = 'text'; + node.invalid = true; + } + }); + + // get the location of the block on parent.nodes (block's siblings) + let parent = stack[stack.length - 1]; + let index = parent.nodes.indexOf(block); + // replace the (invalid) block with it's nodes + parent.nodes.splice(index, 1, ...block.nodes); + } + } while (stack.length > 0); + + push({ type: 'eos' }); + return ast; +}; + +module.exports = parse; diff --git a/node_modules/braces/lib/stringify.js b/node_modules/braces/lib/stringify.js new file mode 100644 index 0000000..414b7bc --- /dev/null +++ b/node_modules/braces/lib/stringify.js @@ -0,0 +1,32 @@ +'use strict'; + +const utils = require('./utils'); + +module.exports = (ast, options = {}) => { + let stringify = (node, parent = {}) => { + let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent); + let invalidNode = node.invalid === true && options.escapeInvalid === true; + let output = ''; + + if (node.value) { + if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) { + return '\\' + node.value; + } + return node.value; + } + + if (node.value) { + return node.value; + } + + if (node.nodes) { + for (let child of node.nodes) { + output += stringify(child); + } + } + return output; + }; + + return stringify(ast); +}; + diff --git a/node_modules/braces/lib/utils.js b/node_modules/braces/lib/utils.js new file mode 100644 index 0000000..e3551a6 --- /dev/null +++ b/node_modules/braces/lib/utils.js @@ -0,0 +1,112 @@ +'use strict'; + +exports.isInteger = num => { + if (typeof num === 'number') { + return Number.isInteger(num); + } + if (typeof num === 'string' && num.trim() !== '') { + return Number.isInteger(Number(num)); + } + return false; +}; + +/** + * Find a node of the given type + */ + +exports.find = (node, type) => node.nodes.find(node => node.type === type); + +/** + * Find a node of the given type + */ + +exports.exceedsLimit = (min, max, step = 1, limit) => { + if (limit === false) return false; + if (!exports.isInteger(min) || !exports.isInteger(max)) return false; + return ((Number(max) - Number(min)) / Number(step)) >= limit; +}; + +/** + * Escape the given node with '\\' before node.value + */ + +exports.escapeNode = (block, n = 0, type) => { + let node = block.nodes[n]; + if (!node) return; + + if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { + if (node.escaped !== true) { + node.value = '\\' + node.value; + node.escaped = true; + } + } +}; + +/** + * Returns true if the given brace node should be enclosed in literal braces + */ + +exports.encloseBrace = node => { + if (node.type !== 'brace') return false; + if ((node.commas >> 0 + node.ranges >> 0) === 0) { + node.invalid = true; + return true; + } + return false; +}; + +/** + * Returns true if a brace node is invalid. + */ + +exports.isInvalidBrace = block => { + if (block.type !== 'brace') return false; + if (block.invalid === true || block.dollar) return true; + if ((block.commas >> 0 + block.ranges >> 0) === 0) { + block.invalid = true; + return true; + } + if (block.open !== true || block.close !== true) { + block.invalid = true; + return true; + } + return false; +}; + +/** + * Returns true if a node is an open or close node + */ + +exports.isOpenOrClose = node => { + if (node.type === 'open' || node.type === 'close') { + return true; + } + return node.open === true || node.close === true; +}; + +/** + * Reduce an array of text nodes. + */ + +exports.reduce = nodes => nodes.reduce((acc, node) => { + if (node.type === 'text') acc.push(node.value); + if (node.type === 'range') node.type = 'text'; + return acc; +}, []); + +/** + * Flatten an array + */ + +exports.flatten = (...args) => { + const result = []; + const flat = arr => { + for (let i = 0; i < arr.length; i++) { + let ele = arr[i]; + Array.isArray(ele) ? flat(ele, result) : ele !== void 0 && result.push(ele); + } + return result; + }; + flat(args); + return result; +}; diff --git a/node_modules/braces/package.json b/node_modules/braces/package.json new file mode 100644 index 0000000..3f52e34 --- /dev/null +++ b/node_modules/braces/package.json @@ -0,0 +1,77 @@ +{ + "name": "braces", + "description": "Bash-like brace expansion, implemented in JavaScript. Safer than other brace expansion libs, with complete support for the Bash 4.3 braces specification, without sacrificing speed.", + "version": "3.0.2", + "homepage": "https://github.com/micromatch/braces", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "contributors": [ + "Brian Woodward (https://twitter.com/doowb)", + "Elan Shanker (https://github.com/es128)", + "Eugene Sharygin (https://github.com/eush77)", + "hemanth.hm (http://h3manth.com)", + "Jon Schlinkert (http://twitter.com/jonschlinkert)" + ], + "repository": "micromatch/braces", + "bugs": { + "url": "https://github.com/micromatch/braces/issues" + }, + "license": "MIT", + "files": [ + "index.js", + "lib" + ], + "main": "index.js", + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "mocha", + "benchmark": "node benchmark" + }, + "dependencies": { + "fill-range": "^7.0.1" + }, + "devDependencies": { + "ansi-colors": "^3.2.4", + "bash-path": "^2.0.1", + "gulp-format-md": "^2.0.0", + "mocha": "^6.1.1" + }, + "keywords": [ + "alpha", + "alphabetical", + "bash", + "brace", + "braces", + "expand", + "expansion", + "filepath", + "fill", + "fs", + "glob", + "globbing", + "letter", + "match", + "matches", + "matching", + "number", + "numerical", + "path", + "range", + "ranges", + "sh" + ], + "verb": { + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "lint": { + "reflinks": true + }, + "plugins": [ + "gulp-format-md" + ] + } +} diff --git a/node_modules/chalk/license b/node_modules/chalk/license new file mode 100644 index 0000000..fa7ceba --- /dev/null +++ b/node_modules/chalk/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/chalk/package.json b/node_modules/chalk/package.json new file mode 100644 index 0000000..3c50010 --- /dev/null +++ b/node_modules/chalk/package.json @@ -0,0 +1,83 @@ +{ + "name": "chalk", + "version": "5.3.0", + "description": "Terminal string styling done right", + "license": "MIT", + "repository": "chalk/chalk", + "funding": "https://github.com/chalk/chalk?sponsor=1", + "type": "module", + "main": "./source/index.js", + "exports": "./source/index.js", + "imports": { + "#ansi-styles": "./source/vendor/ansi-styles/index.js", + "#supports-color": { + "node": "./source/vendor/supports-color/index.js", + "default": "./source/vendor/supports-color/browser.js" + } + }, + "types": "./source/index.d.ts", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "scripts": { + "test": "xo && c8 ava && tsd", + "bench": "matcha benchmark.js" + }, + "files": [ + "source", + "!source/index.test-d.ts" + ], + "keywords": [ + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "string", + "ansi", + "style", + "styles", + "tty", + "formatting", + "rgb", + "256", + "shell", + "xterm", + "log", + "logging", + "command-line", + "text" + ], + "devDependencies": { + "@types/node": "^16.11.10", + "ava": "^3.15.0", + "c8": "^7.10.0", + "color-convert": "^2.0.1", + "execa": "^6.0.0", + "log-update": "^5.0.0", + "matcha": "^0.7.0", + "tsd": "^0.19.0", + "xo": "^0.53.0", + "yoctodelay": "^2.0.0" + }, + "sideEffects": false, + "xo": { + "rules": { + "unicorn/prefer-string-slice": "off", + "@typescript-eslint/consistent-type-imports": "off", + "@typescript-eslint/consistent-type-exports": "off", + "@typescript-eslint/consistent-type-definitions": "off", + "unicorn/expiring-todo-comments": "off" + } + }, + "c8": { + "reporter": [ + "text", + "lcov" + ], + "exclude": [ + "source/vendor" + ] + } +} diff --git a/node_modules/chalk/readme.md b/node_modules/chalk/readme.md new file mode 100644 index 0000000..93511c0 --- /dev/null +++ b/node_modules/chalk/readme.md @@ -0,0 +1,325 @@ +

+
+
+ Chalk +
+
+
+

+ +> Terminal string styling done right + +[![Coverage Status](https://codecov.io/gh/chalk/chalk/branch/main/graph/badge.svg)](https://codecov.io/gh/chalk/chalk) +[![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) +[![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) +[![run on repl.it](https://img.shields.io/badge/Run_on_Replit-f26207?logo=replit&logoColor=white)](https://repl.it/github/chalk/chalk) + +![](media/screenshot.png) + +
+ +--- + + + +--- + +
+ +## Highlights + +- Expressive API +- Highly performant +- No dependencies +- Ability to nest styles +- [256/Truecolor color support](#256-and-truecolor-color-support) +- Auto-detects color support +- Doesn't extend `String.prototype` +- Clean and focused +- Actively maintained +- [Used by ~86,000 packages](https://www.npmjs.com/browse/depended/chalk) as of October 4, 2022 + +## Install + +```sh +npm install chalk +``` + +**IMPORTANT:** Chalk 5 is ESM. If you want to use Chalk with TypeScript or a build tool, you will probably want to use Chalk 4 for now. [Read more.](https://github.com/chalk/chalk/releases/tag/v5.0.0) + +## Usage + +```js +import chalk from 'chalk'; + +console.log(chalk.blue('Hello world!')); +``` + +Chalk comes with an easy to use composable API where you just chain and nest the styles you want. + +```js +import chalk from 'chalk'; + +const log = console.log; + +// Combine styled and normal strings +log(chalk.blue('Hello') + ' World' + chalk.red('!')); + +// Compose multiple styles using the chainable API +log(chalk.blue.bgRed.bold('Hello world!')); + +// Pass in multiple arguments +log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz')); + +// Nest styles +log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!')); + +// Nest styles of the same type even (color, underline, background) +log(chalk.green( + 'I am a green line ' + + chalk.blue.underline.bold('with a blue substring') + + ' that becomes green again!' +)); + +// ES2015 template literal +log(` +CPU: ${chalk.red('90%')} +RAM: ${chalk.green('40%')} +DISK: ${chalk.yellow('70%')} +`); + +// Use RGB colors in terminal emulators that support it. +log(chalk.rgb(123, 45, 67).underline('Underlined reddish color')); +log(chalk.hex('#DEADED').bold('Bold gray!')); +``` + +Easily define your own themes: + +```js +import chalk from 'chalk'; + +const error = chalk.bold.red; +const warning = chalk.hex('#FFA500'); // Orange color + +console.log(error('Error!')); +console.log(warning('Warning!')); +``` + +Take advantage of console.log [string substitution](https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args): + +```js +import chalk from 'chalk'; + +const name = 'Sindre'; +console.log(chalk.green('Hello %s'), name); +//=> 'Hello Sindre' +``` + +## API + +### chalk.` + + + +
+ +
+
+

✧*。٩(ˊᗜˋ*)و✧*。

+ <% if (Object.keys(it.data).length===0) { %> +

No resources found in JSON file

+ <% } %> + <% Object.entries(it.data).forEach(function([name]) { %> +
    +
  • + /<%= name %> + + <% if (Array.isArray(it.data[name])) { %> + - <%= it.data[name].length %> + <%= it.data[name].length> 1 ? 'items' : 'item' %> + + <% } %> +
  • +
+ <% }) %> +
+ + + \ No newline at end of file diff --git a/node_modules/json5/LICENSE.md b/node_modules/json5/LICENSE.md new file mode 100644 index 0000000..2171aca --- /dev/null +++ b/node_modules/json5/LICENSE.md @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) 2012-2018 Aseem Kishore, and [others]. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +[others]: https://github.com/json5/json5/contributors diff --git a/node_modules/json5/README.md b/node_modules/json5/README.md new file mode 100644 index 0000000..00ee793 --- /dev/null +++ b/node_modules/json5/README.md @@ -0,0 +1,282 @@ +# JSON5 – JSON for Humans + +[![Build Status](https://app.travis-ci.com/json5/json5.svg?branch=main)][Build +Status] [![Coverage +Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage +Status] + +JSON5 is an extension to the popular [JSON] file format that aims to be +easier to **write and maintain _by hand_ (e.g. for config files)**. +It is _not intended_ to be used for machine-to-machine communication. +(Keep using JSON or other file formats for that. 🙂) + +JSON5 was started in 2012, and as of 2022, now gets **[>65M downloads/week](https://www.npmjs.com/package/json5)**, +ranks in the **[top 0.1%](https://gist.github.com/anvaka/8e8fa57c7ee1350e3491)** of the most depended-upon packages on npm, +and has been adopted by major projects like +**[Chromium](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5;drc=5de823b36e68fd99009a29281b17bc3a1d6b329c), +[Next.js](https://github.com/vercel/next.js/blob/b88f20c90bf4659b8ad5cb2a27956005eac2c7e8/packages/next/lib/find-config.ts#L43-L46), +[Babel](https://babeljs.io/docs/en/config-files#supported-file-extensions), +[Retool](https://community.retool.com/t/i-am-attempting-to-append-several-text-fields-to-a-google-sheet-but-receiving-a-json5-invalid-character-error/7626), +[WebStorm](https://www.jetbrains.com/help/webstorm/json.html), +and [more](https://github.com/json5/json5/wiki/In-the-Wild)**. +It's also natively supported on **[Apple platforms](https://developer.apple.com/documentation/foundation/jsondecoder/3766916-allowsjson5)** +like **MacOS** and **iOS**. + +Formally, the **[JSON5 Data Interchange Format](https://spec.json5.org/)** is a superset of JSON +(so valid JSON files will always be valid JSON5 files) +that expands its syntax to include some productions from [ECMAScript 5.1] (ES5). +It's also a strict _subset_ of ES5, so valid JSON5 files will always be valid ES5. + +This JavaScript library is a reference implementation for JSON5 parsing and serialization, +and is directly used in many of the popular projects mentioned above +(where e.g. extreme performance isn't necessary), +but others have created [many other libraries](https://github.com/json5/json5/wiki/In-the-Wild) +across many other platforms. + +[Build Status]: https://app.travis-ci.com/json5/json5 + +[Coverage Status]: https://coveralls.io/github/json5/json5 + +[JSON]: https://tools.ietf.org/html/rfc7159 + +[ECMAScript 5.1]: https://www.ecma-international.org/ecma-262/5.1/ + +## Summary of Features +The following ECMAScript 5.1 features, which are not supported in JSON, have +been extended to JSON5. + +### Objects +- Object keys may be an ECMAScript 5.1 _[IdentifierName]_. +- Objects may have a single trailing comma. + +### Arrays +- Arrays may have a single trailing comma. + +### Strings +- Strings may be single quoted. +- Strings may span multiple lines by escaping new line characters. +- Strings may include character escapes. + +### Numbers +- Numbers may be hexadecimal. +- Numbers may have a leading or trailing decimal point. +- Numbers may be [IEEE 754] positive infinity, negative infinity, and NaN. +- Numbers may begin with an explicit plus sign. + +### Comments +- Single and multi-line comments are allowed. + +### White Space +- Additional white space characters are allowed. + +[IdentifierName]: https://www.ecma-international.org/ecma-262/5.1/#sec-7.6 + +[IEEE 754]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933 + +## Example +Kitchen-sink example: + +```js +{ + // comments + unquoted: 'and you can quote me on that', + singleQuotes: 'I can use "double quotes" here', + lineBreaks: "Look, Mom! \ +No \\n's!", + hexadecimal: 0xdecaf, + leadingDecimalPoint: .8675309, andTrailing: 8675309., + positiveSign: +1, + trailingComma: 'in objects', andIn: ['arrays',], + "backwardsCompatible": "with JSON", +} +``` + +A more real-world example is [this config file](https://github.com/chromium/chromium/blob/feb3c9f670515edf9a88f185301cbd7794ee3e52/third_party/blink/renderer/platform/runtime_enabled_features.json5) +from the Chromium/Blink project. + +## Specification +For a detailed explanation of the JSON5 format, please read the [official +specification](https://json5.github.io/json5-spec/). + +## Installation and Usage +### Node.js +```sh +npm install json5 +``` + +#### CommonJS +```js +const JSON5 = require('json5') +``` + +#### Modules +```js +import JSON5 from 'json5' +``` + +### Browsers +#### UMD +```html + + +``` + +#### Modules +```html + +``` + +## API +The JSON5 API is compatible with the [JSON API]. + +[JSON API]: +https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON + +### JSON5.parse() +Parses a JSON5 string, constructing the JavaScript value or object described by +the string. An optional reviver function can be provided to perform a +transformation on the resulting object before it is returned. + +#### Syntax + JSON5.parse(text[, reviver]) + +#### Parameters +- `text`: The string to parse as JSON5. +- `reviver`: If a function, this prescribes how the value originally produced by + parsing is transformed, before being returned. + +#### Return value +The object corresponding to the given JSON5 text. + +### JSON5.stringify() +Converts a JavaScript value to a JSON5 string, optionally replacing values if a +replacer function is specified, or optionally including only the specified +properties if a replacer array is specified. + +#### Syntax + JSON5.stringify(value[, replacer[, space]]) + JSON5.stringify(value[, options]) + +#### Parameters +- `value`: The value to convert to a JSON5 string. +- `replacer`: A function that alters the behavior of the stringification + process, or an array of String and Number objects that serve as a whitelist + for selecting/filtering the properties of the value object to be included in + the JSON5 string. If this value is null or not provided, all properties of the + object are included in the resulting JSON5 string. +- `space`: A String or Number object that's used to insert white space into the + output JSON5 string for readability purposes. If this is a Number, it + indicates the number of space characters to use as white space; this number is + capped at 10 (if it is greater, the value is just 10). Values less than 1 + indicate that no space should be used. If this is a String, the string (or the + first 10 characters of the string, if it's longer than that) is used as white + space. If this parameter is not provided (or is null), no white space is used. + If white space is used, trailing commas will be used in objects and arrays. +- `options`: An object with the following properties: + - `replacer`: Same as the `replacer` parameter. + - `space`: Same as the `space` parameter. + - `quote`: A String representing the quote character to use when serializing + strings. + +#### Return value +A JSON5 string representing the value. + +### Node.js `require()` JSON5 files +When using Node.js, you can `require()` JSON5 files by adding the following +statement. + +```js +require('json5/lib/register') +``` + +Then you can load a JSON5 file with a Node.js `require()` statement. For +example: + +```js +const config = require('./config.json5') +``` + +## CLI +Since JSON is more widely used than JSON5, this package includes a CLI for +converting JSON5 to JSON and for validating the syntax of JSON5 documents. + +### Installation +```sh +npm install --global json5 +``` + +### Usage +```sh +json5 [options] +``` + +If `` is not provided, then STDIN is used. + +#### Options: +- `-s`, `--space`: The number of spaces to indent or `t` for tabs +- `-o`, `--out-file [file]`: Output to the specified file, otherwise STDOUT +- `-v`, `--validate`: Validate JSON5 but do not output JSON +- `-V`, `--version`: Output the version number +- `-h`, `--help`: Output usage information + +## Contributing +### Development +```sh +git clone https://github.com/json5/json5 +cd json5 +npm install +``` + +When contributing code, please write relevant tests and run `npm test` and `npm +run lint` before submitting pull requests. Please use an editor that supports +[EditorConfig](http://editorconfig.org/). + +### Issues +To report bugs or request features regarding the JSON5 **data format**, +please submit an issue to the official +**[_specification_ repository](https://github.com/json5/json5-spec)**. + +Note that we will never add any features that make JSON5 incompatible with ES5; +that compatibility is a fundamental premise of JSON5. + +To report bugs or request features regarding this **JavaScript implementation** +of JSON5, please submit an issue to **_this_ repository**. + +### Security Vulnerabilities and Disclosures +To report a security vulnerability, please follow the follow the guidelines +described in our [security policy](./SECURITY.md). + +## License +MIT. See [LICENSE.md](./LICENSE.md) for details. + +## Credits +[Aseem Kishore](https://github.com/aseemk) founded this project. +He wrote a [blog post](https://aseemk.substack.com/p/ignore-the-f-ing-haters-json5) +about the journey and lessons learned 10 years in. + +[Michael Bolin](http://bolinfest.com/) independently arrived at and published +some of these same ideas with awesome explanations and detail. Recommended +reading: [Suggested Improvements to JSON](http://bolinfest.com/essays/json.html) + +[Douglas Crockford](http://www.crockford.com/) of course designed and built +JSON, but his state machine diagrams on the [JSON website](http://json.org/), as +cheesy as it may sound, gave us motivation and confidence that building a new +parser to implement these ideas was within reach! The original +implementation of JSON5 was also modeled directly off of Doug’s open-source +[json_parse.js] parser. We’re grateful for that clean and well-documented +code. + +[json_parse.js]: +https://github.com/douglascrockford/JSON-js/blob/03157639c7a7cddd2e9f032537f346f1a87c0f6d/json_parse.js + +[Max Nanasy](https://github.com/MaxNanasy) has been an early and prolific +supporter, contributing multiple patches and ideas. + +[Andrew Eisenberg](https://github.com/aeisenberg) contributed the original +`stringify` method. + +[Jordan Tucker](https://github.com/jordanbtucker) has aligned JSON5 more closely +with ES5, wrote the official JSON5 specification, completely rewrote the +codebase from the ground up, and is actively maintaining this project. diff --git a/node_modules/json5/dist/index.js b/node_modules/json5/dist/index.js new file mode 100644 index 0000000..bf86533 --- /dev/null +++ b/node_modules/json5/dist/index.js @@ -0,0 +1,1737 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.JSON5 = factory()); +}(this, (function () { 'use strict'; + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var _global = createCommonjsModule(function (module) { + // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 + var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self + // eslint-disable-next-line no-new-func + : Function('return this')(); + if (typeof __g == 'number') { __g = global; } // eslint-disable-line no-undef + }); + + var _core = createCommonjsModule(function (module) { + var core = module.exports = { version: '2.6.5' }; + if (typeof __e == 'number') { __e = core; } // eslint-disable-line no-undef + }); + var _core_1 = _core.version; + + var _isObject = function (it) { + return typeof it === 'object' ? it !== null : typeof it === 'function'; + }; + + var _anObject = function (it) { + if (!_isObject(it)) { throw TypeError(it + ' is not an object!'); } + return it; + }; + + var _fails = function (exec) { + try { + return !!exec(); + } catch (e) { + return true; + } + }; + + // Thank's IE8 for his funny defineProperty + var _descriptors = !_fails(function () { + return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; + }); + + var document = _global.document; + // typeof document.createElement is 'object' in old IE + var is = _isObject(document) && _isObject(document.createElement); + var _domCreate = function (it) { + return is ? document.createElement(it) : {}; + }; + + var _ie8DomDefine = !_descriptors && !_fails(function () { + return Object.defineProperty(_domCreate('div'), 'a', { get: function () { return 7; } }).a != 7; + }); + + // 7.1.1 ToPrimitive(input [, PreferredType]) + + // instead of the ES6 spec version, we didn't implement @@toPrimitive case + // and the second argument - flag - preferred type is a string + var _toPrimitive = function (it, S) { + if (!_isObject(it)) { return it; } + var fn, val; + if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) { return val; } + if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) { return val; } + if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) { return val; } + throw TypeError("Can't convert object to primitive value"); + }; + + var dP = Object.defineProperty; + + var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) { + _anObject(O); + P = _toPrimitive(P, true); + _anObject(Attributes); + if (_ie8DomDefine) { try { + return dP(O, P, Attributes); + } catch (e) { /* empty */ } } + if ('get' in Attributes || 'set' in Attributes) { throw TypeError('Accessors not supported!'); } + if ('value' in Attributes) { O[P] = Attributes.value; } + return O; + }; + + var _objectDp = { + f: f + }; + + var _propertyDesc = function (bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; + }; + + var _hide = _descriptors ? function (object, key, value) { + return _objectDp.f(object, key, _propertyDesc(1, value)); + } : function (object, key, value) { + object[key] = value; + return object; + }; + + var hasOwnProperty = {}.hasOwnProperty; + var _has = function (it, key) { + return hasOwnProperty.call(it, key); + }; + + var id = 0; + var px = Math.random(); + var _uid = function (key) { + return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); + }; + + var _library = false; + + var _shared = createCommonjsModule(function (module) { + var SHARED = '__core-js_shared__'; + var store = _global[SHARED] || (_global[SHARED] = {}); + + (module.exports = function (key, value) { + return store[key] || (store[key] = value !== undefined ? value : {}); + })('versions', []).push({ + version: _core.version, + mode: _library ? 'pure' : 'global', + copyright: '© 2019 Denis Pushkarev (zloirock.ru)' + }); + }); + + var _functionToString = _shared('native-function-to-string', Function.toString); + + var _redefine = createCommonjsModule(function (module) { + var SRC = _uid('src'); + + var TO_STRING = 'toString'; + var TPL = ('' + _functionToString).split(TO_STRING); + + _core.inspectSource = function (it) { + return _functionToString.call(it); + }; + + (module.exports = function (O, key, val, safe) { + var isFunction = typeof val == 'function'; + if (isFunction) { _has(val, 'name') || _hide(val, 'name', key); } + if (O[key] === val) { return; } + if (isFunction) { _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key))); } + if (O === _global) { + O[key] = val; + } else if (!safe) { + delete O[key]; + _hide(O, key, val); + } else if (O[key]) { + O[key] = val; + } else { + _hide(O, key, val); + } + // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative + })(Function.prototype, TO_STRING, function toString() { + return typeof this == 'function' && this[SRC] || _functionToString.call(this); + }); + }); + + var _aFunction = function (it) { + if (typeof it != 'function') { throw TypeError(it + ' is not a function!'); } + return it; + }; + + // optional / simple context binding + + var _ctx = function (fn, that, length) { + _aFunction(fn); + if (that === undefined) { return fn; } + switch (length) { + case 1: return function (a) { + return fn.call(that, a); + }; + case 2: return function (a, b) { + return fn.call(that, a, b); + }; + case 3: return function (a, b, c) { + return fn.call(that, a, b, c); + }; + } + return function (/* ...args */) { + return fn.apply(that, arguments); + }; + }; + + var PROTOTYPE = 'prototype'; + + var $export = function (type, name, source) { + var IS_FORCED = type & $export.F; + var IS_GLOBAL = type & $export.G; + var IS_STATIC = type & $export.S; + var IS_PROTO = type & $export.P; + var IS_BIND = type & $export.B; + var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE]; + var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {}); + var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {}); + var key, own, out, exp; + if (IS_GLOBAL) { source = name; } + for (key in source) { + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + // export native or passed + out = (own ? target : source)[key]; + // bind timers to global for call from export context + exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out; + // extend global + if (target) { _redefine(target, key, out, type & $export.U); } + // export + if (exports[key] != out) { _hide(exports, key, exp); } + if (IS_PROTO && expProto[key] != out) { expProto[key] = out; } + } + }; + _global.core = _core; + // type bitmap + $export.F = 1; // forced + $export.G = 2; // global + $export.S = 4; // static + $export.P = 8; // proto + $export.B = 16; // bind + $export.W = 32; // wrap + $export.U = 64; // safe + $export.R = 128; // real proto method for `library` + var _export = $export; + + // 7.1.4 ToInteger + var ceil = Math.ceil; + var floor = Math.floor; + var _toInteger = function (it) { + return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); + }; + + // 7.2.1 RequireObjectCoercible(argument) + var _defined = function (it) { + if (it == undefined) { throw TypeError("Can't call method on " + it); } + return it; + }; + + // true -> String#at + // false -> String#codePointAt + var _stringAt = function (TO_STRING) { + return function (that, pos) { + var s = String(_defined(that)); + var i = _toInteger(pos); + var l = s.length; + var a, b; + if (i < 0 || i >= l) { return TO_STRING ? '' : undefined; } + a = s.charCodeAt(i); + return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff + ? TO_STRING ? s.charAt(i) : a + : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; + }; + }; + + var $at = _stringAt(false); + _export(_export.P, 'String', { + // 21.1.3.3 String.prototype.codePointAt(pos) + codePointAt: function codePointAt(pos) { + return $at(this, pos); + } + }); + + var codePointAt = _core.String.codePointAt; + + var max = Math.max; + var min = Math.min; + var _toAbsoluteIndex = function (index, length) { + index = _toInteger(index); + return index < 0 ? max(index + length, 0) : min(index, length); + }; + + var fromCharCode = String.fromCharCode; + var $fromCodePoint = String.fromCodePoint; + + // length should be 1, old FF problem + _export(_export.S + _export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', { + // 21.1.2.2 String.fromCodePoint(...codePoints) + fromCodePoint: function fromCodePoint(x) { + var arguments$1 = arguments; + // eslint-disable-line no-unused-vars + var res = []; + var aLen = arguments.length; + var i = 0; + var code; + while (aLen > i) { + code = +arguments$1[i++]; + if (_toAbsoluteIndex(code, 0x10ffff) !== code) { throw RangeError(code + ' is not a valid code point'); } + res.push(code < 0x10000 + ? fromCharCode(code) + : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00) + ); + } return res.join(''); + } + }); + + var fromCodePoint = _core.String.fromCodePoint; + + // This is a generated file. Do not edit. + var Space_Separator = /[\u1680\u2000-\u200A\u202F\u205F\u3000]/; + var ID_Start = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/; + var ID_Continue = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/; + + var unicode = { + Space_Separator: Space_Separator, + ID_Start: ID_Start, + ID_Continue: ID_Continue + }; + + var util = { + isSpaceSeparator: function isSpaceSeparator (c) { + return typeof c === 'string' && unicode.Space_Separator.test(c) + }, + + isIdStartChar: function isIdStartChar (c) { + return typeof c === 'string' && ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c === '$') || (c === '_') || + unicode.ID_Start.test(c) + ) + }, + + isIdContinueChar: function isIdContinueChar (c) { + return typeof c === 'string' && ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + (c === '$') || (c === '_') || + (c === '\u200C') || (c === '\u200D') || + unicode.ID_Continue.test(c) + ) + }, + + isDigit: function isDigit (c) { + return typeof c === 'string' && /[0-9]/.test(c) + }, + + isHexDigit: function isHexDigit (c) { + return typeof c === 'string' && /[0-9A-Fa-f]/.test(c) + }, + }; + + var source; + var parseState; + var stack; + var pos; + var line; + var column; + var token; + var key; + var root; + + var parse = function parse (text, reviver) { + source = String(text); + parseState = 'start'; + stack = []; + pos = 0; + line = 1; + column = 0; + token = undefined; + key = undefined; + root = undefined; + + do { + token = lex(); + + // This code is unreachable. + // if (!parseStates[parseState]) { + // throw invalidParseState() + // } + + parseStates[parseState](); + } while (token.type !== 'eof') + + if (typeof reviver === 'function') { + return internalize({'': root}, '', reviver) + } + + return root + }; + + function internalize (holder, name, reviver) { + var value = holder[name]; + if (value != null && typeof value === 'object') { + if (Array.isArray(value)) { + for (var i = 0; i < value.length; i++) { + var key = String(i); + var replacement = internalize(value, key, reviver); + if (replacement === undefined) { + delete value[key]; + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + } else { + for (var key$1 in value) { + var replacement$1 = internalize(value, key$1, reviver); + if (replacement$1 === undefined) { + delete value[key$1]; + } else { + Object.defineProperty(value, key$1, { + value: replacement$1, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + } + } + + return reviver.call(holder, name, value) + } + + var lexState; + var buffer; + var doubleQuote; + var sign; + var c; + + function lex () { + lexState = 'default'; + buffer = ''; + doubleQuote = false; + sign = 1; + + for (;;) { + c = peek(); + + // This code is unreachable. + // if (!lexStates[lexState]) { + // throw invalidLexState(lexState) + // } + + var token = lexStates[lexState](); + if (token) { + return token + } + } + } + + function peek () { + if (source[pos]) { + return String.fromCodePoint(source.codePointAt(pos)) + } + } + + function read () { + var c = peek(); + + if (c === '\n') { + line++; + column = 0; + } else if (c) { + column += c.length; + } else { + column++; + } + + if (c) { + pos += c.length; + } + + return c + } + + var lexStates = { + default: function default$1 () { + switch (c) { + case '\t': + case '\v': + case '\f': + case ' ': + case '\u00A0': + case '\uFEFF': + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read(); + return + + case '/': + read(); + lexState = 'comment'; + return + + case undefined: + read(); + return newToken('eof') + } + + if (util.isSpaceSeparator(c)) { + read(); + return + } + + // This code is unreachable. + // if (!lexStates[parseState]) { + // throw invalidLexState(parseState) + // } + + return lexStates[parseState]() + }, + + comment: function comment () { + switch (c) { + case '*': + read(); + lexState = 'multiLineComment'; + return + + case '/': + read(); + lexState = 'singleLineComment'; + return + } + + throw invalidChar(read()) + }, + + multiLineComment: function multiLineComment () { + switch (c) { + case '*': + read(); + lexState = 'multiLineCommentAsterisk'; + return + + case undefined: + throw invalidChar(read()) + } + + read(); + }, + + multiLineCommentAsterisk: function multiLineCommentAsterisk () { + switch (c) { + case '*': + read(); + return + + case '/': + read(); + lexState = 'default'; + return + + case undefined: + throw invalidChar(read()) + } + + read(); + lexState = 'multiLineComment'; + }, + + singleLineComment: function singleLineComment () { + switch (c) { + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read(); + lexState = 'default'; + return + + case undefined: + read(); + return newToken('eof') + } + + read(); + }, + + value: function value () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + case 'n': + read(); + literal('ull'); + return newToken('null', null) + + case 't': + read(); + literal('rue'); + return newToken('boolean', true) + + case 'f': + read(); + literal('alse'); + return newToken('boolean', false) + + case '-': + case '+': + if (read() === '-') { + sign = -1; + } + + lexState = 'sign'; + return + + case '.': + buffer = read(); + lexState = 'decimalPointLeading'; + return + + case '0': + buffer = read(); + lexState = 'zero'; + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read(); + lexState = 'decimalInteger'; + return + + case 'I': + read(); + literal('nfinity'); + return newToken('numeric', Infinity) + + case 'N': + read(); + literal('aN'); + return newToken('numeric', NaN) + + case '"': + case "'": + doubleQuote = (read() === '"'); + buffer = ''; + lexState = 'string'; + return + } + + throw invalidChar(read()) + }, + + identifierNameStartEscape: function identifierNameStartEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read(); + var u = unicodeEscape(); + switch (u) { + case '$': + case '_': + break + + default: + if (!util.isIdStartChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u; + lexState = 'identifierName'; + }, + + identifierName: function identifierName () { + switch (c) { + case '$': + case '_': + case '\u200C': + case '\u200D': + buffer += read(); + return + + case '\\': + read(); + lexState = 'identifierNameEscape'; + return + } + + if (util.isIdContinueChar(c)) { + buffer += read(); + return + } + + return newToken('identifier', buffer) + }, + + identifierNameEscape: function identifierNameEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read(); + var u = unicodeEscape(); + switch (u) { + case '$': + case '_': + case '\u200C': + case '\u200D': + break + + default: + if (!util.isIdContinueChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u; + lexState = 'identifierName'; + }, + + sign: function sign$1 () { + switch (c) { + case '.': + buffer = read(); + lexState = 'decimalPointLeading'; + return + + case '0': + buffer = read(); + lexState = 'zero'; + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read(); + lexState = 'decimalInteger'; + return + + case 'I': + read(); + literal('nfinity'); + return newToken('numeric', sign * Infinity) + + case 'N': + read(); + literal('aN'); + return newToken('numeric', NaN) + } + + throw invalidChar(read()) + }, + + zero: function zero () { + switch (c) { + case '.': + buffer += read(); + lexState = 'decimalPoint'; + return + + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + + case 'x': + case 'X': + buffer += read(); + lexState = 'hexadecimal'; + return + } + + return newToken('numeric', sign * 0) + }, + + decimalInteger: function decimalInteger () { + switch (c) { + case '.': + buffer += read(); + lexState = 'decimalPoint'; + return + + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalPointLeading: function decimalPointLeading () { + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalFraction'; + return + } + + throw invalidChar(read()) + }, + + decimalPoint: function decimalPoint () { + switch (c) { + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalFraction'; + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalFraction: function decimalFraction () { + switch (c) { + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalExponent: function decimalExponent () { + switch (c) { + case '+': + case '-': + buffer += read(); + lexState = 'decimalExponentSign'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalExponentInteger'; + return + } + + throw invalidChar(read()) + }, + + decimalExponentSign: function decimalExponentSign () { + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalExponentInteger'; + return + } + + throw invalidChar(read()) + }, + + decimalExponentInteger: function decimalExponentInteger () { + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + hexadecimal: function hexadecimal () { + if (util.isHexDigit(c)) { + buffer += read(); + lexState = 'hexadecimalInteger'; + return + } + + throw invalidChar(read()) + }, + + hexadecimalInteger: function hexadecimalInteger () { + if (util.isHexDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + string: function string () { + switch (c) { + case '\\': + read(); + buffer += escape(); + return + + case '"': + if (doubleQuote) { + read(); + return newToken('string', buffer) + } + + buffer += read(); + return + + case "'": + if (!doubleQuote) { + read(); + return newToken('string', buffer) + } + + buffer += read(); + return + + case '\n': + case '\r': + throw invalidChar(read()) + + case '\u2028': + case '\u2029': + separatorChar(c); + break + + case undefined: + throw invalidChar(read()) + } + + buffer += read(); + }, + + start: function start () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + // This code is unreachable since the default lexState handles eof. + // case undefined: + // return newToken('eof') + } + + lexState = 'value'; + }, + + beforePropertyName: function beforePropertyName () { + switch (c) { + case '$': + case '_': + buffer = read(); + lexState = 'identifierName'; + return + + case '\\': + read(); + lexState = 'identifierNameStartEscape'; + return + + case '}': + return newToken('punctuator', read()) + + case '"': + case "'": + doubleQuote = (read() === '"'); + lexState = 'string'; + return + } + + if (util.isIdStartChar(c)) { + buffer += read(); + lexState = 'identifierName'; + return + } + + throw invalidChar(read()) + }, + + afterPropertyName: function afterPropertyName () { + if (c === ':') { + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforePropertyValue: function beforePropertyValue () { + lexState = 'value'; + }, + + afterPropertyValue: function afterPropertyValue () { + switch (c) { + case ',': + case '}': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforeArrayValue: function beforeArrayValue () { + if (c === ']') { + return newToken('punctuator', read()) + } + + lexState = 'value'; + }, + + afterArrayValue: function afterArrayValue () { + switch (c) { + case ',': + case ']': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + end: function end () { + // This code is unreachable since it's handled by the default lexState. + // if (c === undefined) { + // read() + // return newToken('eof') + // } + + throw invalidChar(read()) + }, + }; + + function newToken (type, value) { + return { + type: type, + value: value, + line: line, + column: column, + } + } + + function literal (s) { + for (var i = 0, list = s; i < list.length; i += 1) { + var c = list[i]; + + var p = peek(); + + if (p !== c) { + throw invalidChar(read()) + } + + read(); + } + } + + function escape () { + var c = peek(); + switch (c) { + case 'b': + read(); + return '\b' + + case 'f': + read(); + return '\f' + + case 'n': + read(); + return '\n' + + case 'r': + read(); + return '\r' + + case 't': + read(); + return '\t' + + case 'v': + read(); + return '\v' + + case '0': + read(); + if (util.isDigit(peek())) { + throw invalidChar(read()) + } + + return '\0' + + case 'x': + read(); + return hexEscape() + + case 'u': + read(); + return unicodeEscape() + + case '\n': + case '\u2028': + case '\u2029': + read(); + return '' + + case '\r': + read(); + if (peek() === '\n') { + read(); + } + + return '' + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + throw invalidChar(read()) + + case undefined: + throw invalidChar(read()) + } + + return read() + } + + function hexEscape () { + var buffer = ''; + var c = peek(); + + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + + c = peek(); + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + + return String.fromCodePoint(parseInt(buffer, 16)) + } + + function unicodeEscape () { + var buffer = ''; + var count = 4; + + while (count-- > 0) { + var c = peek(); + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + } + + return String.fromCodePoint(parseInt(buffer, 16)) + } + + var parseStates = { + start: function start () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push(); + }, + + beforePropertyName: function beforePropertyName () { + switch (token.type) { + case 'identifier': + case 'string': + key = token.value; + parseState = 'afterPropertyName'; + return + + case 'punctuator': + // This code is unreachable since it's handled by the lexState. + // if (token.value !== '}') { + // throw invalidToken() + // } + + pop(); + return + + case 'eof': + throw invalidEOF() + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterPropertyName: function afterPropertyName () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator' || token.value !== ':') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + parseState = 'beforePropertyValue'; + }, + + beforePropertyValue: function beforePropertyValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push(); + }, + + beforeArrayValue: function beforeArrayValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + if (token.type === 'punctuator' && token.value === ']') { + pop(); + return + } + + push(); + }, + + afterPropertyValue: function afterPropertyValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforePropertyName'; + return + + case '}': + pop(); + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterArrayValue: function afterArrayValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforeArrayValue'; + return + + case ']': + pop(); + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + end: function end () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'eof') { + // throw invalidToken() + // } + }, + }; + + function push () { + var value; + + switch (token.type) { + case 'punctuator': + switch (token.value) { + case '{': + value = {}; + break + + case '[': + value = []; + break + } + + break + + case 'null': + case 'boolean': + case 'numeric': + case 'string': + value = token.value; + break + + // This code is unreachable. + // default: + // throw invalidToken() + } + + if (root === undefined) { + root = value; + } else { + var parent = stack[stack.length - 1]; + if (Array.isArray(parent)) { + parent.push(value); + } else { + Object.defineProperty(parent, key, { + value: value, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + + if (value !== null && typeof value === 'object') { + stack.push(value); + + if (Array.isArray(value)) { + parseState = 'beforeArrayValue'; + } else { + parseState = 'beforePropertyName'; + } + } else { + var current = stack[stack.length - 1]; + if (current == null) { + parseState = 'end'; + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue'; + } else { + parseState = 'afterPropertyValue'; + } + } + } + + function pop () { + stack.pop(); + + var current = stack[stack.length - 1]; + if (current == null) { + parseState = 'end'; + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue'; + } else { + parseState = 'afterPropertyValue'; + } + } + + // This code is unreachable. + // function invalidParseState () { + // return new Error(`JSON5: invalid parse state '${parseState}'`) + // } + + // This code is unreachable. + // function invalidLexState (state) { + // return new Error(`JSON5: invalid lex state '${state}'`) + // } + + function invalidChar (c) { + if (c === undefined) { + return syntaxError(("JSON5: invalid end of input at " + line + ":" + column)) + } + + return syntaxError(("JSON5: invalid character '" + (formatChar(c)) + "' at " + line + ":" + column)) + } + + function invalidEOF () { + return syntaxError(("JSON5: invalid end of input at " + line + ":" + column)) + } + + // This code is unreachable. + // function invalidToken () { + // if (token.type === 'eof') { + // return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) + // } + + // const c = String.fromCodePoint(token.value.codePointAt(0)) + // return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) + // } + + function invalidIdentifier () { + column -= 5; + return syntaxError(("JSON5: invalid identifier character at " + line + ":" + column)) + } + + function separatorChar (c) { + console.warn(("JSON5: '" + (formatChar(c)) + "' in strings is not valid ECMAScript; consider escaping")); + } + + function formatChar (c) { + var replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + }; + + if (replacements[c]) { + return replacements[c] + } + + if (c < ' ') { + var hexString = c.charCodeAt(0).toString(16); + return '\\x' + ('00' + hexString).substring(hexString.length) + } + + return c + } + + function syntaxError (message) { + var err = new SyntaxError(message); + err.lineNumber = line; + err.columnNumber = column; + return err + } + + var stringify = function stringify (value, replacer, space) { + var stack = []; + var indent = ''; + var propertyList; + var replacerFunc; + var gap = ''; + var quote; + + if ( + replacer != null && + typeof replacer === 'object' && + !Array.isArray(replacer) + ) { + space = replacer.space; + quote = replacer.quote; + replacer = replacer.replacer; + } + + if (typeof replacer === 'function') { + replacerFunc = replacer; + } else if (Array.isArray(replacer)) { + propertyList = []; + for (var i = 0, list = replacer; i < list.length; i += 1) { + var v = list[i]; + + var item = (void 0); + + if (typeof v === 'string') { + item = v; + } else if ( + typeof v === 'number' || + v instanceof String || + v instanceof Number + ) { + item = String(v); + } + + if (item !== undefined && propertyList.indexOf(item) < 0) { + propertyList.push(item); + } + } + } + + if (space instanceof Number) { + space = Number(space); + } else if (space instanceof String) { + space = String(space); + } + + if (typeof space === 'number') { + if (space > 0) { + space = Math.min(10, Math.floor(space)); + gap = ' '.substr(0, space); + } + } else if (typeof space === 'string') { + gap = space.substr(0, 10); + } + + return serializeProperty('', {'': value}) + + function serializeProperty (key, holder) { + var value = holder[key]; + if (value != null) { + if (typeof value.toJSON5 === 'function') { + value = value.toJSON5(key); + } else if (typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + } + + if (replacerFunc) { + value = replacerFunc.call(holder, key, value); + } + + if (value instanceof Number) { + value = Number(value); + } else if (value instanceof String) { + value = String(value); + } else if (value instanceof Boolean) { + value = value.valueOf(); + } + + switch (value) { + case null: return 'null' + case true: return 'true' + case false: return 'false' + } + + if (typeof value === 'string') { + return quoteString(value, false) + } + + if (typeof value === 'number') { + return String(value) + } + + if (typeof value === 'object') { + return Array.isArray(value) ? serializeArray(value) : serializeObject(value) + } + + return undefined + } + + function quoteString (value) { + var quotes = { + "'": 0.1, + '"': 0.2, + }; + + var replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + }; + + var product = ''; + + for (var i = 0; i < value.length; i++) { + var c = value[i]; + switch (c) { + case "'": + case '"': + quotes[c]++; + product += c; + continue + + case '\0': + if (util.isDigit(value[i + 1])) { + product += '\\x00'; + continue + } + } + + if (replacements[c]) { + product += replacements[c]; + continue + } + + if (c < ' ') { + var hexString = c.charCodeAt(0).toString(16); + product += '\\x' + ('00' + hexString).substring(hexString.length); + continue + } + + product += c; + } + + var quoteChar = quote || Object.keys(quotes).reduce(function (a, b) { return (quotes[a] < quotes[b]) ? a : b; }); + + product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]); + + return quoteChar + product + quoteChar + } + + function serializeObject (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value); + + var stepback = indent; + indent = indent + gap; + + var keys = propertyList || Object.keys(value); + var partial = []; + for (var i = 0, list = keys; i < list.length; i += 1) { + var key = list[i]; + + var propertyString = serializeProperty(key, value); + if (propertyString !== undefined) { + var member = serializeKey(key) + ':'; + if (gap !== '') { + member += ' '; + } + member += propertyString; + partial.push(member); + } + } + + var final; + if (partial.length === 0) { + final = '{}'; + } else { + var properties; + if (gap === '') { + properties = partial.join(','); + final = '{' + properties + '}'; + } else { + var separator = ',\n' + indent; + properties = partial.join(separator); + final = '{\n' + indent + properties + ',\n' + stepback + '}'; + } + } + + stack.pop(); + indent = stepback; + return final + } + + function serializeKey (key) { + if (key.length === 0) { + return quoteString(key, true) + } + + var firstChar = String.fromCodePoint(key.codePointAt(0)); + if (!util.isIdStartChar(firstChar)) { + return quoteString(key, true) + } + + for (var i = firstChar.length; i < key.length; i++) { + if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) { + return quoteString(key, true) + } + } + + return key + } + + function serializeArray (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value); + + var stepback = indent; + indent = indent + gap; + + var partial = []; + for (var i = 0; i < value.length; i++) { + var propertyString = serializeProperty(String(i), value); + partial.push((propertyString !== undefined) ? propertyString : 'null'); + } + + var final; + if (partial.length === 0) { + final = '[]'; + } else { + if (gap === '') { + var properties = partial.join(','); + final = '[' + properties + ']'; + } else { + var separator = ',\n' + indent; + var properties$1 = partial.join(separator); + final = '[\n' + indent + properties$1 + ',\n' + stepback + ']'; + } + } + + stack.pop(); + indent = stepback; + return final + } + }; + + var JSON5 = { + parse: parse, + stringify: stringify, + }; + + var lib = JSON5; + + var es5 = lib; + + return es5; + +}))); diff --git a/node_modules/json5/dist/index.min.js b/node_modules/json5/dist/index.min.js new file mode 100644 index 0000000..ddce3e2 --- /dev/null +++ b/node_modules/json5/dist/index.min.js @@ -0,0 +1 @@ +!function(u,D){"object"==typeof exports&&"undefined"!=typeof module?module.exports=D():"function"==typeof define&&define.amd?define(D):u.JSON5=D()}(this,function(){"use strict";function u(u,D){return u(D={exports:{}},D.exports),D.exports}var D=u(function(u){var D=u.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=D)}),e=u(function(u){var D=u.exports={version:"2.6.5"};"number"==typeof __e&&(__e=D)}),r=(e.version,function(u){return"object"==typeof u?null!==u:"function"==typeof u}),t=function(u){if(!r(u))throw TypeError(u+" is not an object!");return u},n=function(u){try{return!!u()}catch(u){return!0}},F=!n(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}),C=D.document,A=r(C)&&r(C.createElement),i=!F&&!n(function(){return 7!=Object.defineProperty((u="div",A?C.createElement(u):{}),"a",{get:function(){return 7}}).a;var u}),E=Object.defineProperty,o={f:F?Object.defineProperty:function(u,D,e){if(t(u),D=function(u,D){if(!r(u))return u;var e,t;if(D&&"function"==typeof(e=u.toString)&&!r(t=e.call(u)))return t;if("function"==typeof(e=u.valueOf)&&!r(t=e.call(u)))return t;if(!D&&"function"==typeof(e=u.toString)&&!r(t=e.call(u)))return t;throw TypeError("Can't convert object to primitive value")}(D,!0),t(e),i)try{return E(u,D,e)}catch(u){}if("get"in e||"set"in e)throw TypeError("Accessors not supported!");return"value"in e&&(u[D]=e.value),u}},a=F?function(u,D,e){return o.f(u,D,function(u,D){return{enumerable:!(1&u),configurable:!(2&u),writable:!(4&u),value:D}}(1,e))}:function(u,D,e){return u[D]=e,u},c={}.hasOwnProperty,B=function(u,D){return c.call(u,D)},s=0,f=Math.random(),l=u(function(u){var r=D["__core-js_shared__"]||(D["__core-js_shared__"]={});(u.exports=function(u,D){return r[u]||(r[u]=void 0!==D?D:{})})("versions",[]).push({version:e.version,mode:"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})})("native-function-to-string",Function.toString),d=u(function(u){var r,t="Symbol(".concat(void 0===(r="src")?"":r,")_",(++s+f).toString(36)),n=(""+l).split("toString");e.inspectSource=function(u){return l.call(u)},(u.exports=function(u,e,r,F){var C="function"==typeof r;C&&(B(r,"name")||a(r,"name",e)),u[e]!==r&&(C&&(B(r,t)||a(r,t,u[e]?""+u[e]:n.join(String(e)))),u===D?u[e]=r:F?u[e]?u[e]=r:a(u,e,r):(delete u[e],a(u,e,r)))})(Function.prototype,"toString",function(){return"function"==typeof this&&this[t]||l.call(this)})}),v=function(u,D,e){if(function(u){if("function"!=typeof u)throw TypeError(u+" is not a function!")}(u),void 0===D)return u;switch(e){case 1:return function(e){return u.call(D,e)};case 2:return function(e,r){return u.call(D,e,r)};case 3:return function(e,r,t){return u.call(D,e,r,t)}}return function(){return u.apply(D,arguments)}},p=function(u,r,t){var n,F,C,A,i=u&p.F,E=u&p.G,o=u&p.S,c=u&p.P,B=u&p.B,s=E?D:o?D[r]||(D[r]={}):(D[r]||{}).prototype,f=E?e:e[r]||(e[r]={}),l=f.prototype||(f.prototype={});for(n in E&&(t=r),t)C=((F=!i&&s&&void 0!==s[n])?s:t)[n],A=B&&F?v(C,D):c&&"function"==typeof C?v(Function.call,C):C,s&&d(s,n,C,u&p.U),f[n]!=C&&a(f,n,A),c&&l[n]!=C&&(l[n]=C)};D.core=e,p.F=1,p.G=2,p.S=4,p.P=8,p.B=16,p.W=32,p.U=64,p.R=128;var h,m=p,g=Math.ceil,y=Math.floor,w=function(u){return isNaN(u=+u)?0:(u>0?y:g)(u)},b=(h=!1,function(u,D){var e,r,t=String(function(u){if(null==u)throw TypeError("Can't call method on "+u);return u}(u)),n=w(D),F=t.length;return n<0||n>=F?h?"":void 0:(e=t.charCodeAt(n))<55296||e>56319||n+1===F||(r=t.charCodeAt(n+1))<56320||r>57343?h?t.charAt(n):e:h?t.slice(n,n+2):r-56320+(e-55296<<10)+65536});m(m.P,"String",{codePointAt:function(u){return b(this,u)}});e.String.codePointAt;var S=Math.max,x=Math.min,N=String.fromCharCode,P=String.fromCodePoint;m(m.S+m.F*(!!P&&1!=P.length),"String",{fromCodePoint:function(u){for(var D,e,r,t=arguments,n=[],F=arguments.length,C=0;F>C;){if(D=+t[C++],r=1114111,((e=w(e=D))<0?S(e+r,0):x(e,r))!==D)throw RangeError(D+" is not a valid code point");n.push(D<65536?N(D):N(55296+((D-=65536)>>10),D%1024+56320))}return n.join("")}});e.String.fromCodePoint;var _,O,j,I,V,J,M,k,L,T,z,H,$,R,G={Space_Separator:/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ID_Start:/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ID_Continue:/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/},U={isSpaceSeparator:function(u){return"string"==typeof u&&G.Space_Separator.test(u)},isIdStartChar:function(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||"$"===u||"_"===u||G.ID_Start.test(u))},isIdContinueChar:function(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||u>="0"&&u<="9"||"$"===u||"_"===u||"‌"===u||"‍"===u||G.ID_Continue.test(u))},isDigit:function(u){return"string"==typeof u&&/[0-9]/.test(u)},isHexDigit:function(u){return"string"==typeof u&&/[0-9A-Fa-f]/.test(u)}};function Z(){for(T="default",z="",H=!1,$=1;;){R=q();var u=X[T]();if(u)return u}}function q(){if(_[I])return String.fromCodePoint(_.codePointAt(I))}function W(){var u=q();return"\n"===u?(V++,J=0):u?J+=u.length:J++,u&&(I+=u.length),u}var X={default:function(){switch(R){case"\t":case"\v":case"\f":case" ":case" ":case"\ufeff":case"\n":case"\r":case"\u2028":case"\u2029":return void W();case"/":return W(),void(T="comment");case void 0:return W(),K("eof")}if(!U.isSpaceSeparator(R))return X[O]();W()},comment:function(){switch(R){case"*":return W(),void(T="multiLineComment");case"/":return W(),void(T="singleLineComment")}throw ru(W())},multiLineComment:function(){switch(R){case"*":return W(),void(T="multiLineCommentAsterisk");case void 0:throw ru(W())}W()},multiLineCommentAsterisk:function(){switch(R){case"*":return void W();case"/":return W(),void(T="default");case void 0:throw ru(W())}W(),T="multiLineComment"},singleLineComment:function(){switch(R){case"\n":case"\r":case"\u2028":case"\u2029":return W(),void(T="default");case void 0:return W(),K("eof")}W()},value:function(){switch(R){case"{":case"[":return K("punctuator",W());case"n":return W(),Q("ull"),K("null",null);case"t":return W(),Q("rue"),K("boolean",!0);case"f":return W(),Q("alse"),K("boolean",!1);case"-":case"+":return"-"===W()&&($=-1),void(T="sign");case".":return z=W(),void(T="decimalPointLeading");case"0":return z=W(),void(T="zero");case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return z=W(),void(T="decimalInteger");case"I":return W(),Q("nfinity"),K("numeric",1/0);case"N":return W(),Q("aN"),K("numeric",NaN);case'"':case"'":return H='"'===W(),z="",void(T="string")}throw ru(W())},identifierNameStartEscape:function(){if("u"!==R)throw ru(W());W();var u=Y();switch(u){case"$":case"_":break;default:if(!U.isIdStartChar(u))throw nu()}z+=u,T="identifierName"},identifierName:function(){switch(R){case"$":case"_":case"‌":case"‍":return void(z+=W());case"\\":return W(),void(T="identifierNameEscape")}if(!U.isIdContinueChar(R))return K("identifier",z);z+=W()},identifierNameEscape:function(){if("u"!==R)throw ru(W());W();var u=Y();switch(u){case"$":case"_":case"‌":case"‍":break;default:if(!U.isIdContinueChar(u))throw nu()}z+=u,T="identifierName"},sign:function(){switch(R){case".":return z=W(),void(T="decimalPointLeading");case"0":return z=W(),void(T="zero");case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return z=W(),void(T="decimalInteger");case"I":return W(),Q("nfinity"),K("numeric",$*(1/0));case"N":return W(),Q("aN"),K("numeric",NaN)}throw ru(W())},zero:function(){switch(R){case".":return z+=W(),void(T="decimalPoint");case"e":case"E":return z+=W(),void(T="decimalExponent");case"x":case"X":return z+=W(),void(T="hexadecimal")}return K("numeric",0*$)},decimalInteger:function(){switch(R){case".":return z+=W(),void(T="decimalPoint");case"e":case"E":return z+=W(),void(T="decimalExponent")}if(!U.isDigit(R))return K("numeric",$*Number(z));z+=W()},decimalPointLeading:function(){if(U.isDigit(R))return z+=W(),void(T="decimalFraction");throw ru(W())},decimalPoint:function(){switch(R){case"e":case"E":return z+=W(),void(T="decimalExponent")}return U.isDigit(R)?(z+=W(),void(T="decimalFraction")):K("numeric",$*Number(z))},decimalFraction:function(){switch(R){case"e":case"E":return z+=W(),void(T="decimalExponent")}if(!U.isDigit(R))return K("numeric",$*Number(z));z+=W()},decimalExponent:function(){switch(R){case"+":case"-":return z+=W(),void(T="decimalExponentSign")}if(U.isDigit(R))return z+=W(),void(T="decimalExponentInteger");throw ru(W())},decimalExponentSign:function(){if(U.isDigit(R))return z+=W(),void(T="decimalExponentInteger");throw ru(W())},decimalExponentInteger:function(){if(!U.isDigit(R))return K("numeric",$*Number(z));z+=W()},hexadecimal:function(){if(U.isHexDigit(R))return z+=W(),void(T="hexadecimalInteger");throw ru(W())},hexadecimalInteger:function(){if(!U.isHexDigit(R))return K("numeric",$*Number(z));z+=W()},string:function(){switch(R){case"\\":return W(),void(z+=function(){switch(q()){case"b":return W(),"\b";case"f":return W(),"\f";case"n":return W(),"\n";case"r":return W(),"\r";case"t":return W(),"\t";case"v":return W(),"\v";case"0":if(W(),U.isDigit(q()))throw ru(W());return"\0";case"x":return W(),function(){var u="",D=q();if(!U.isHexDigit(D))throw ru(W());if(u+=W(),D=q(),!U.isHexDigit(D))throw ru(W());return u+=W(),String.fromCodePoint(parseInt(u,16))}();case"u":return W(),Y();case"\n":case"\u2028":case"\u2029":return W(),"";case"\r":return W(),"\n"===q()&&W(),"";case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case void 0:throw ru(W())}return W()}());case'"':return H?(W(),K("string",z)):void(z+=W());case"'":return H?void(z+=W()):(W(),K("string",z));case"\n":case"\r":throw ru(W());case"\u2028":case"\u2029":!function(u){console.warn("JSON5: '"+Fu(u)+"' in strings is not valid ECMAScript; consider escaping")}(R);break;case void 0:throw ru(W())}z+=W()},start:function(){switch(R){case"{":case"[":return K("punctuator",W())}T="value"},beforePropertyName:function(){switch(R){case"$":case"_":return z=W(),void(T="identifierName");case"\\":return W(),void(T="identifierNameStartEscape");case"}":return K("punctuator",W());case'"':case"'":return H='"'===W(),void(T="string")}if(U.isIdStartChar(R))return z+=W(),void(T="identifierName");throw ru(W())},afterPropertyName:function(){if(":"===R)return K("punctuator",W());throw ru(W())},beforePropertyValue:function(){T="value"},afterPropertyValue:function(){switch(R){case",":case"}":return K("punctuator",W())}throw ru(W())},beforeArrayValue:function(){if("]"===R)return K("punctuator",W());T="value"},afterArrayValue:function(){switch(R){case",":case"]":return K("punctuator",W())}throw ru(W())},end:function(){throw ru(W())}};function K(u,D){return{type:u,value:D,line:V,column:J}}function Q(u){for(var D=0,e=u;D0;){var e=q();if(!U.isHexDigit(e))throw ru(W());u+=W()}return String.fromCodePoint(parseInt(u,16))}var uu={start:function(){if("eof"===M.type)throw tu();Du()},beforePropertyName:function(){switch(M.type){case"identifier":case"string":return k=M.value,void(O="afterPropertyName");case"punctuator":return void eu();case"eof":throw tu()}},afterPropertyName:function(){if("eof"===M.type)throw tu();O="beforePropertyValue"},beforePropertyValue:function(){if("eof"===M.type)throw tu();Du()},beforeArrayValue:function(){if("eof"===M.type)throw tu();"punctuator"!==M.type||"]"!==M.value?Du():eu()},afterPropertyValue:function(){if("eof"===M.type)throw tu();switch(M.value){case",":return void(O="beforePropertyName");case"}":eu()}},afterArrayValue:function(){if("eof"===M.type)throw tu();switch(M.value){case",":return void(O="beforeArrayValue");case"]":eu()}},end:function(){}};function Du(){var u;switch(M.type){case"punctuator":switch(M.value){case"{":u={};break;case"[":u=[]}break;case"null":case"boolean":case"numeric":case"string":u=M.value}if(void 0===L)L=u;else{var D=j[j.length-1];Array.isArray(D)?D.push(u):Object.defineProperty(D,k,{value:u,writable:!0,enumerable:!0,configurable:!0})}if(null!==u&&"object"==typeof u)j.push(u),O=Array.isArray(u)?"beforeArrayValue":"beforePropertyName";else{var e=j[j.length-1];O=null==e?"end":Array.isArray(e)?"afterArrayValue":"afterPropertyValue"}}function eu(){j.pop();var u=j[j.length-1];O=null==u?"end":Array.isArray(u)?"afterArrayValue":"afterPropertyValue"}function ru(u){return Cu(void 0===u?"JSON5: invalid end of input at "+V+":"+J:"JSON5: invalid character '"+Fu(u)+"' at "+V+":"+J)}function tu(){return Cu("JSON5: invalid end of input at "+V+":"+J)}function nu(){return Cu("JSON5: invalid identifier character at "+V+":"+(J-=5))}function Fu(u){var D={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(D[u])return D[u];if(u<" "){var e=u.charCodeAt(0).toString(16);return"\\x"+("00"+e).substring(e.length)}return u}function Cu(u){var D=new SyntaxError(u);return D.lineNumber=V,D.columnNumber=J,D}return{parse:function(u,D){_=String(u),O="start",j=[],I=0,V=1,J=0,M=void 0,k=void 0,L=void 0;do{M=Z(),uu[O]()}while("eof"!==M.type);return"function"==typeof D?function u(D,e,r){var t=D[e];if(null!=t&&"object"==typeof t)if(Array.isArray(t))for(var n=0;n0&&(e=Math.min(10,Math.floor(e)),A=" ".substr(0,e)):"string"==typeof e&&(A=e.substr(0,10)),c("",{"":u});function c(u,D){var e=D[u];switch(null!=e&&("function"==typeof e.toJSON5?e=e.toJSON5(u):"function"==typeof e.toJSON&&(e=e.toJSON(u))),t&&(e=t.call(D,u,e)),e instanceof Number?e=Number(e):e instanceof String?e=String(e):e instanceof Boolean&&(e=e.valueOf()),e){case null:return"null";case!0:return"true";case!1:return"false"}return"string"==typeof e?B(e):"number"==typeof e?String(e):"object"==typeof e?Array.isArray(e)?function(u){if(F.indexOf(u)>=0)throw TypeError("Converting circular structure to JSON5");F.push(u);var D=C;C+=A;for(var e,r=[],t=0;t=0)throw TypeError("Converting circular structure to JSON5");F.push(u);var D=C;C+=A;for(var e,t,n=r||Object.keys(u),i=[],E=0,o=n;E"string"==typeof u&&unicode.Space_Separator.test(u),isIdStartChar:u=>"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||"$"===u||"_"===u||unicode.ID_Start.test(u)),isIdContinueChar:u=>"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||u>="0"&&u<="9"||"$"===u||"_"===u||"‌"===u||"‍"===u||unicode.ID_Continue.test(u)),isDigit:u=>"string"==typeof u&&/[0-9]/.test(u),isHexDigit:u=>"string"==typeof u&&/[0-9A-Fa-f]/.test(u)};let source,parseState,stack,pos,line,column,token,key,root;var parse=function(u,D){source=String(u),parseState="start",stack=[],pos=0,line=1,column=0,token=void 0,key=void 0,root=void 0;do{token=lex(),parseStates[parseState]()}while("eof"!==token.type);return"function"==typeof D?internalize({"":root},"",D):root};function internalize(u,D,e){const r=u[D];if(null!=r&&"object"==typeof r)if(Array.isArray(r))for(let u=0;u0;){const D=peek();if(!util.isHexDigit(D))throw invalidChar(read());u+=read()}return String.fromCodePoint(parseInt(u,16))}const parseStates={start(){if("eof"===token.type)throw invalidEOF();push()},beforePropertyName(){switch(token.type){case"identifier":case"string":return key=token.value,void(parseState="afterPropertyName");case"punctuator":return void pop();case"eof":throw invalidEOF()}},afterPropertyName(){if("eof"===token.type)throw invalidEOF();parseState="beforePropertyValue"},beforePropertyValue(){if("eof"===token.type)throw invalidEOF();push()},beforeArrayValue(){if("eof"===token.type)throw invalidEOF();"punctuator"!==token.type||"]"!==token.value?push():pop()},afterPropertyValue(){if("eof"===token.type)throw invalidEOF();switch(token.value){case",":return void(parseState="beforePropertyName");case"}":pop()}},afterArrayValue(){if("eof"===token.type)throw invalidEOF();switch(token.value){case",":return void(parseState="beforeArrayValue");case"]":pop()}},end(){}};function push(){let u;switch(token.type){case"punctuator":switch(token.value){case"{":u={};break;case"[":u=[]}break;case"null":case"boolean":case"numeric":case"string":u=token.value}if(void 0===root)root=u;else{const D=stack[stack.length-1];Array.isArray(D)?D.push(u):Object.defineProperty(D,key,{value:u,writable:!0,enumerable:!0,configurable:!0})}if(null!==u&&"object"==typeof u)stack.push(u),parseState=Array.isArray(u)?"beforeArrayValue":"beforePropertyName";else{const u=stack[stack.length-1];parseState=null==u?"end":Array.isArray(u)?"afterArrayValue":"afterPropertyValue"}}function pop(){stack.pop();const u=stack[stack.length-1];parseState=null==u?"end":Array.isArray(u)?"afterArrayValue":"afterPropertyValue"}function invalidChar(u){return syntaxError(void 0===u?`JSON5: invalid end of input at ${line}:${column}`:`JSON5: invalid character '${formatChar(u)}' at ${line}:${column}`)}function invalidEOF(){return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)}function invalidIdentifier(){return syntaxError(`JSON5: invalid identifier character at ${line}:${column-=5}`)}function separatorChar(u){console.warn(`JSON5: '${formatChar(u)}' in strings is not valid ECMAScript; consider escaping`)}function formatChar(u){const D={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(D[u])return D[u];if(u<" "){const D=u.charCodeAt(0).toString(16);return"\\x"+("00"+D).substring(D.length)}return u}function syntaxError(u){const D=new SyntaxError(u);return D.lineNumber=line,D.columnNumber=column,D}var stringify=function(u,D,e){const r=[];let t,F,C,a="",A="";if(null==D||"object"!=typeof D||Array.isArray(D)||(e=D.space,C=D.quote,D=D.replacer),"function"==typeof D)F=D;else if(Array.isArray(D)){t=[];for(const u of D){let D;"string"==typeof u?D=u:("number"==typeof u||u instanceof String||u instanceof Number)&&(D=String(u)),void 0!==D&&t.indexOf(D)<0&&t.push(D)}}return e instanceof Number?e=Number(e):e instanceof String&&(e=String(e)),"number"==typeof e?e>0&&(e=Math.min(10,Math.floor(e)),A=" ".substr(0,e)):"string"==typeof e&&(A=e.substr(0,10)),n("",{"":u});function n(u,D){let e=D[u];switch(null!=e&&("function"==typeof e.toJSON5?e=e.toJSON5(u):"function"==typeof e.toJSON&&(e=e.toJSON(u))),F&&(e=F.call(D,u,e)),e instanceof Number?e=Number(e):e instanceof String?e=String(e):e instanceof Boolean&&(e=e.valueOf()),e){case null:return"null";case!0:return"true";case!1:return"false"}return"string"==typeof e?E(e):"number"==typeof e?String(e):"object"==typeof e?Array.isArray(e)?function(u){if(r.indexOf(u)>=0)throw TypeError("Converting circular structure to JSON5");r.push(u);let D=a;a+=A;let e,t=[];for(let D=0;D=0)throw TypeError("Converting circular structure to JSON5");r.push(u);let D=a;a+=A;let e,F=t||Object.keys(u),C=[];for(const D of F){const e=n(D,u);if(void 0!==e){let u=i(D)+":";""!==A&&(u+=" "),u+=e,C.push(u)}}if(0===C.length)e="{}";else{let u;if(""===A)u=C.join(","),e="{"+u+"}";else{let r=",\n"+a;u=C.join(r),e="{\n"+a+u+",\n"+D+"}"}}return r.pop(),a=D,e}(e):void 0}function E(u){const D={"'":.1,'"':.2},e={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};let r="";for(let t=0;tD[u]= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c === '$') || (c === '_') || + unicode.ID_Start.test(c) + ) + }, + + isIdContinueChar (c) { + return typeof c === 'string' && ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + (c === '$') || (c === '_') || + (c === '\u200C') || (c === '\u200D') || + unicode.ID_Continue.test(c) + ) + }, + + isDigit (c) { + return typeof c === 'string' && /[0-9]/.test(c) + }, + + isHexDigit (c) { + return typeof c === 'string' && /[0-9A-Fa-f]/.test(c) + }, +}; + +let source; +let parseState; +let stack; +let pos; +let line; +let column; +let token; +let key; +let root; + +var parse = function parse (text, reviver) { + source = String(text); + parseState = 'start'; + stack = []; + pos = 0; + line = 1; + column = 0; + token = undefined; + key = undefined; + root = undefined; + + do { + token = lex(); + + // This code is unreachable. + // if (!parseStates[parseState]) { + // throw invalidParseState() + // } + + parseStates[parseState](); + } while (token.type !== 'eof') + + if (typeof reviver === 'function') { + return internalize({'': root}, '', reviver) + } + + return root +}; + +function internalize (holder, name, reviver) { + const value = holder[name]; + if (value != null && typeof value === 'object') { + if (Array.isArray(value)) { + for (let i = 0; i < value.length; i++) { + const key = String(i); + const replacement = internalize(value, key, reviver); + if (replacement === undefined) { + delete value[key]; + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + } else { + for (const key in value) { + const replacement = internalize(value, key, reviver); + if (replacement === undefined) { + delete value[key]; + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + } + } + + return reviver.call(holder, name, value) +} + +let lexState; +let buffer; +let doubleQuote; +let sign; +let c; + +function lex () { + lexState = 'default'; + buffer = ''; + doubleQuote = false; + sign = 1; + + for (;;) { + c = peek(); + + // This code is unreachable. + // if (!lexStates[lexState]) { + // throw invalidLexState(lexState) + // } + + const token = lexStates[lexState](); + if (token) { + return token + } + } +} + +function peek () { + if (source[pos]) { + return String.fromCodePoint(source.codePointAt(pos)) + } +} + +function read () { + const c = peek(); + + if (c === '\n') { + line++; + column = 0; + } else if (c) { + column += c.length; + } else { + column++; + } + + if (c) { + pos += c.length; + } + + return c +} + +const lexStates = { + default () { + switch (c) { + case '\t': + case '\v': + case '\f': + case ' ': + case '\u00A0': + case '\uFEFF': + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read(); + return + + case '/': + read(); + lexState = 'comment'; + return + + case undefined: + read(); + return newToken('eof') + } + + if (util.isSpaceSeparator(c)) { + read(); + return + } + + // This code is unreachable. + // if (!lexStates[parseState]) { + // throw invalidLexState(parseState) + // } + + return lexStates[parseState]() + }, + + comment () { + switch (c) { + case '*': + read(); + lexState = 'multiLineComment'; + return + + case '/': + read(); + lexState = 'singleLineComment'; + return + } + + throw invalidChar(read()) + }, + + multiLineComment () { + switch (c) { + case '*': + read(); + lexState = 'multiLineCommentAsterisk'; + return + + case undefined: + throw invalidChar(read()) + } + + read(); + }, + + multiLineCommentAsterisk () { + switch (c) { + case '*': + read(); + return + + case '/': + read(); + lexState = 'default'; + return + + case undefined: + throw invalidChar(read()) + } + + read(); + lexState = 'multiLineComment'; + }, + + singleLineComment () { + switch (c) { + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read(); + lexState = 'default'; + return + + case undefined: + read(); + return newToken('eof') + } + + read(); + }, + + value () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + case 'n': + read(); + literal('ull'); + return newToken('null', null) + + case 't': + read(); + literal('rue'); + return newToken('boolean', true) + + case 'f': + read(); + literal('alse'); + return newToken('boolean', false) + + case '-': + case '+': + if (read() === '-') { + sign = -1; + } + + lexState = 'sign'; + return + + case '.': + buffer = read(); + lexState = 'decimalPointLeading'; + return + + case '0': + buffer = read(); + lexState = 'zero'; + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read(); + lexState = 'decimalInteger'; + return + + case 'I': + read(); + literal('nfinity'); + return newToken('numeric', Infinity) + + case 'N': + read(); + literal('aN'); + return newToken('numeric', NaN) + + case '"': + case "'": + doubleQuote = (read() === '"'); + buffer = ''; + lexState = 'string'; + return + } + + throw invalidChar(read()) + }, + + identifierNameStartEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read(); + const u = unicodeEscape(); + switch (u) { + case '$': + case '_': + break + + default: + if (!util.isIdStartChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u; + lexState = 'identifierName'; + }, + + identifierName () { + switch (c) { + case '$': + case '_': + case '\u200C': + case '\u200D': + buffer += read(); + return + + case '\\': + read(); + lexState = 'identifierNameEscape'; + return + } + + if (util.isIdContinueChar(c)) { + buffer += read(); + return + } + + return newToken('identifier', buffer) + }, + + identifierNameEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read(); + const u = unicodeEscape(); + switch (u) { + case '$': + case '_': + case '\u200C': + case '\u200D': + break + + default: + if (!util.isIdContinueChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u; + lexState = 'identifierName'; + }, + + sign () { + switch (c) { + case '.': + buffer = read(); + lexState = 'decimalPointLeading'; + return + + case '0': + buffer = read(); + lexState = 'zero'; + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read(); + lexState = 'decimalInteger'; + return + + case 'I': + read(); + literal('nfinity'); + return newToken('numeric', sign * Infinity) + + case 'N': + read(); + literal('aN'); + return newToken('numeric', NaN) + } + + throw invalidChar(read()) + }, + + zero () { + switch (c) { + case '.': + buffer += read(); + lexState = 'decimalPoint'; + return + + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + + case 'x': + case 'X': + buffer += read(); + lexState = 'hexadecimal'; + return + } + + return newToken('numeric', sign * 0) + }, + + decimalInteger () { + switch (c) { + case '.': + buffer += read(); + lexState = 'decimalPoint'; + return + + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalPointLeading () { + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalFraction'; + return + } + + throw invalidChar(read()) + }, + + decimalPoint () { + switch (c) { + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalFraction'; + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalFraction () { + switch (c) { + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalExponent () { + switch (c) { + case '+': + case '-': + buffer += read(); + lexState = 'decimalExponentSign'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalExponentInteger'; + return + } + + throw invalidChar(read()) + }, + + decimalExponentSign () { + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalExponentInteger'; + return + } + + throw invalidChar(read()) + }, + + decimalExponentInteger () { + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + hexadecimal () { + if (util.isHexDigit(c)) { + buffer += read(); + lexState = 'hexadecimalInteger'; + return + } + + throw invalidChar(read()) + }, + + hexadecimalInteger () { + if (util.isHexDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + string () { + switch (c) { + case '\\': + read(); + buffer += escape(); + return + + case '"': + if (doubleQuote) { + read(); + return newToken('string', buffer) + } + + buffer += read(); + return + + case "'": + if (!doubleQuote) { + read(); + return newToken('string', buffer) + } + + buffer += read(); + return + + case '\n': + case '\r': + throw invalidChar(read()) + + case '\u2028': + case '\u2029': + separatorChar(c); + break + + case undefined: + throw invalidChar(read()) + } + + buffer += read(); + }, + + start () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + // This code is unreachable since the default lexState handles eof. + // case undefined: + // return newToken('eof') + } + + lexState = 'value'; + }, + + beforePropertyName () { + switch (c) { + case '$': + case '_': + buffer = read(); + lexState = 'identifierName'; + return + + case '\\': + read(); + lexState = 'identifierNameStartEscape'; + return + + case '}': + return newToken('punctuator', read()) + + case '"': + case "'": + doubleQuote = (read() === '"'); + lexState = 'string'; + return + } + + if (util.isIdStartChar(c)) { + buffer += read(); + lexState = 'identifierName'; + return + } + + throw invalidChar(read()) + }, + + afterPropertyName () { + if (c === ':') { + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforePropertyValue () { + lexState = 'value'; + }, + + afterPropertyValue () { + switch (c) { + case ',': + case '}': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforeArrayValue () { + if (c === ']') { + return newToken('punctuator', read()) + } + + lexState = 'value'; + }, + + afterArrayValue () { + switch (c) { + case ',': + case ']': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + end () { + // This code is unreachable since it's handled by the default lexState. + // if (c === undefined) { + // read() + // return newToken('eof') + // } + + throw invalidChar(read()) + }, +}; + +function newToken (type, value) { + return { + type, + value, + line, + column, + } +} + +function literal (s) { + for (const c of s) { + const p = peek(); + + if (p !== c) { + throw invalidChar(read()) + } + + read(); + } +} + +function escape () { + const c = peek(); + switch (c) { + case 'b': + read(); + return '\b' + + case 'f': + read(); + return '\f' + + case 'n': + read(); + return '\n' + + case 'r': + read(); + return '\r' + + case 't': + read(); + return '\t' + + case 'v': + read(); + return '\v' + + case '0': + read(); + if (util.isDigit(peek())) { + throw invalidChar(read()) + } + + return '\0' + + case 'x': + read(); + return hexEscape() + + case 'u': + read(); + return unicodeEscape() + + case '\n': + case '\u2028': + case '\u2029': + read(); + return '' + + case '\r': + read(); + if (peek() === '\n') { + read(); + } + + return '' + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + throw invalidChar(read()) + + case undefined: + throw invalidChar(read()) + } + + return read() +} + +function hexEscape () { + let buffer = ''; + let c = peek(); + + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + + c = peek(); + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + + return String.fromCodePoint(parseInt(buffer, 16)) +} + +function unicodeEscape () { + let buffer = ''; + let count = 4; + + while (count-- > 0) { + const c = peek(); + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + } + + return String.fromCodePoint(parseInt(buffer, 16)) +} + +const parseStates = { + start () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push(); + }, + + beforePropertyName () { + switch (token.type) { + case 'identifier': + case 'string': + key = token.value; + parseState = 'afterPropertyName'; + return + + case 'punctuator': + // This code is unreachable since it's handled by the lexState. + // if (token.value !== '}') { + // throw invalidToken() + // } + + pop(); + return + + case 'eof': + throw invalidEOF() + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterPropertyName () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator' || token.value !== ':') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + parseState = 'beforePropertyValue'; + }, + + beforePropertyValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push(); + }, + + beforeArrayValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + if (token.type === 'punctuator' && token.value === ']') { + pop(); + return + } + + push(); + }, + + afterPropertyValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforePropertyName'; + return + + case '}': + pop(); + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterArrayValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforeArrayValue'; + return + + case ']': + pop(); + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + end () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'eof') { + // throw invalidToken() + // } + }, +}; + +function push () { + let value; + + switch (token.type) { + case 'punctuator': + switch (token.value) { + case '{': + value = {}; + break + + case '[': + value = []; + break + } + + break + + case 'null': + case 'boolean': + case 'numeric': + case 'string': + value = token.value; + break + + // This code is unreachable. + // default: + // throw invalidToken() + } + + if (root === undefined) { + root = value; + } else { + const parent = stack[stack.length - 1]; + if (Array.isArray(parent)) { + parent.push(value); + } else { + Object.defineProperty(parent, key, { + value, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + + if (value !== null && typeof value === 'object') { + stack.push(value); + + if (Array.isArray(value)) { + parseState = 'beforeArrayValue'; + } else { + parseState = 'beforePropertyName'; + } + } else { + const current = stack[stack.length - 1]; + if (current == null) { + parseState = 'end'; + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue'; + } else { + parseState = 'afterPropertyValue'; + } + } +} + +function pop () { + stack.pop(); + + const current = stack[stack.length - 1]; + if (current == null) { + parseState = 'end'; + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue'; + } else { + parseState = 'afterPropertyValue'; + } +} + +// This code is unreachable. +// function invalidParseState () { +// return new Error(`JSON5: invalid parse state '${parseState}'`) +// } + +// This code is unreachable. +// function invalidLexState (state) { +// return new Error(`JSON5: invalid lex state '${state}'`) +// } + +function invalidChar (c) { + if (c === undefined) { + return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) + } + + return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) +} + +function invalidEOF () { + return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) +} + +// This code is unreachable. +// function invalidToken () { +// if (token.type === 'eof') { +// return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) +// } + +// const c = String.fromCodePoint(token.value.codePointAt(0)) +// return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) +// } + +function invalidIdentifier () { + column -= 5; + return syntaxError(`JSON5: invalid identifier character at ${line}:${column}`) +} + +function separatorChar (c) { + console.warn(`JSON5: '${formatChar(c)}' in strings is not valid ECMAScript; consider escaping`); +} + +function formatChar (c) { + const replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + }; + + if (replacements[c]) { + return replacements[c] + } + + if (c < ' ') { + const hexString = c.charCodeAt(0).toString(16); + return '\\x' + ('00' + hexString).substring(hexString.length) + } + + return c +} + +function syntaxError (message) { + const err = new SyntaxError(message); + err.lineNumber = line; + err.columnNumber = column; + return err +} + +var stringify = function stringify (value, replacer, space) { + const stack = []; + let indent = ''; + let propertyList; + let replacerFunc; + let gap = ''; + let quote; + + if ( + replacer != null && + typeof replacer === 'object' && + !Array.isArray(replacer) + ) { + space = replacer.space; + quote = replacer.quote; + replacer = replacer.replacer; + } + + if (typeof replacer === 'function') { + replacerFunc = replacer; + } else if (Array.isArray(replacer)) { + propertyList = []; + for (const v of replacer) { + let item; + + if (typeof v === 'string') { + item = v; + } else if ( + typeof v === 'number' || + v instanceof String || + v instanceof Number + ) { + item = String(v); + } + + if (item !== undefined && propertyList.indexOf(item) < 0) { + propertyList.push(item); + } + } + } + + if (space instanceof Number) { + space = Number(space); + } else if (space instanceof String) { + space = String(space); + } + + if (typeof space === 'number') { + if (space > 0) { + space = Math.min(10, Math.floor(space)); + gap = ' '.substr(0, space); + } + } else if (typeof space === 'string') { + gap = space.substr(0, 10); + } + + return serializeProperty('', {'': value}) + + function serializeProperty (key, holder) { + let value = holder[key]; + if (value != null) { + if (typeof value.toJSON5 === 'function') { + value = value.toJSON5(key); + } else if (typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + } + + if (replacerFunc) { + value = replacerFunc.call(holder, key, value); + } + + if (value instanceof Number) { + value = Number(value); + } else if (value instanceof String) { + value = String(value); + } else if (value instanceof Boolean) { + value = value.valueOf(); + } + + switch (value) { + case null: return 'null' + case true: return 'true' + case false: return 'false' + } + + if (typeof value === 'string') { + return quoteString(value, false) + } + + if (typeof value === 'number') { + return String(value) + } + + if (typeof value === 'object') { + return Array.isArray(value) ? serializeArray(value) : serializeObject(value) + } + + return undefined + } + + function quoteString (value) { + const quotes = { + "'": 0.1, + '"': 0.2, + }; + + const replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + }; + + let product = ''; + + for (let i = 0; i < value.length; i++) { + const c = value[i]; + switch (c) { + case "'": + case '"': + quotes[c]++; + product += c; + continue + + case '\0': + if (util.isDigit(value[i + 1])) { + product += '\\x00'; + continue + } + } + + if (replacements[c]) { + product += replacements[c]; + continue + } + + if (c < ' ') { + let hexString = c.charCodeAt(0).toString(16); + product += '\\x' + ('00' + hexString).substring(hexString.length); + continue + } + + product += c; + } + + const quoteChar = quote || Object.keys(quotes).reduce((a, b) => (quotes[a] < quotes[b]) ? a : b); + + product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]); + + return quoteChar + product + quoteChar + } + + function serializeObject (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value); + + let stepback = indent; + indent = indent + gap; + + let keys = propertyList || Object.keys(value); + let partial = []; + for (const key of keys) { + const propertyString = serializeProperty(key, value); + if (propertyString !== undefined) { + let member = serializeKey(key) + ':'; + if (gap !== '') { + member += ' '; + } + member += propertyString; + partial.push(member); + } + } + + let final; + if (partial.length === 0) { + final = '{}'; + } else { + let properties; + if (gap === '') { + properties = partial.join(','); + final = '{' + properties + '}'; + } else { + let separator = ',\n' + indent; + properties = partial.join(separator); + final = '{\n' + indent + properties + ',\n' + stepback + '}'; + } + } + + stack.pop(); + indent = stepback; + return final + } + + function serializeKey (key) { + if (key.length === 0) { + return quoteString(key, true) + } + + const firstChar = String.fromCodePoint(key.codePointAt(0)); + if (!util.isIdStartChar(firstChar)) { + return quoteString(key, true) + } + + for (let i = firstChar.length; i < key.length; i++) { + if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) { + return quoteString(key, true) + } + } + + return key + } + + function serializeArray (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value); + + let stepback = indent; + indent = indent + gap; + + let partial = []; + for (let i = 0; i < value.length; i++) { + const propertyString = serializeProperty(String(i), value); + partial.push((propertyString !== undefined) ? propertyString : 'null'); + } + + let final; + if (partial.length === 0) { + final = '[]'; + } else { + if (gap === '') { + let properties = partial.join(','); + final = '[' + properties + ']'; + } else { + let separator = ',\n' + indent; + let properties = partial.join(separator); + final = '[\n' + indent + properties + ',\n' + stepback + ']'; + } + } + + stack.pop(); + indent = stepback; + return final + } +}; + +const JSON5 = { + parse, + stringify, +}; + +var lib = JSON5; + +export default lib; diff --git a/node_modules/json5/lib/cli.js b/node_modules/json5/lib/cli.js new file mode 100755 index 0000000..93cb809 --- /dev/null +++ b/node_modules/json5/lib/cli.js @@ -0,0 +1,152 @@ +#!/usr/bin/env node + +const fs = require('fs') +const path = require('path') +const pkg = require('../package.json') +const JSON5 = require('./') + +const argv = parseArgs() + +if (argv.version) { + version() +} else if (argv.help) { + usage() +} else { + const inFilename = argv.defaults[0] + + let readStream + if (inFilename) { + readStream = fs.createReadStream(inFilename) + } else { + readStream = process.stdin + } + + let json5 = '' + readStream.on('data', data => { + json5 += data + }) + + readStream.on('end', () => { + let space + if (argv.space === 't' || argv.space === 'tab') { + space = '\t' + } else { + space = Number(argv.space) + } + + let value + try { + value = JSON5.parse(json5) + if (!argv.validate) { + const json = JSON.stringify(value, null, space) + + let writeStream + + // --convert is for backward compatibility with v0.5.1. If + // specified with and not --out-file, then a file with + // the same name but with a .json extension will be written. + if (argv.convert && inFilename && !argv.outFile) { + const parsedFilename = path.parse(inFilename) + const outFilename = path.format( + Object.assign( + parsedFilename, + {base: path.basename(parsedFilename.base, parsedFilename.ext) + '.json'} + ) + ) + + writeStream = fs.createWriteStream(outFilename) + } else if (argv.outFile) { + writeStream = fs.createWriteStream(argv.outFile) + } else { + writeStream = process.stdout + } + + writeStream.write(json) + } + } catch (err) { + console.error(err.message) + process.exit(1) + } + }) +} + +function parseArgs () { + let convert + let space + let validate + let outFile + let version + let help + const defaults = [] + + const args = process.argv.slice(2) + for (let i = 0; i < args.length; i++) { + const arg = args[i] + switch (arg) { + case '--convert': + case '-c': + convert = true + break + + case '--space': + case '-s': + space = args[++i] + break + + case '--validate': + case '-v': + validate = true + break + + case '--out-file': + case '-o': + outFile = args[++i] + break + + case '--version': + case '-V': + version = true + break + + case '--help': + case '-h': + help = true + break + + default: + defaults.push(arg) + break + } + } + + return { + convert, + space, + validate, + outFile, + version, + help, + defaults, + } +} + +function version () { + console.log(pkg.version) +} + +function usage () { + console.log( + ` + Usage: json5 [options] + + If is not provided, then STDIN is used. + + Options: + + -s, --space The number of spaces to indent or 't' for tabs + -o, --out-file [file] Output to the specified file, otherwise STDOUT + -v, --validate Validate JSON5 but do not output JSON + -V, --version Output the version number + -h, --help Output usage information` + ) +} diff --git a/node_modules/json5/lib/index.d.ts b/node_modules/json5/lib/index.d.ts new file mode 100644 index 0000000..1c45bca --- /dev/null +++ b/node_modules/json5/lib/index.d.ts @@ -0,0 +1,4 @@ +import parse = require('./parse') +import stringify = require('./stringify') + +export {parse, stringify} diff --git a/node_modules/json5/lib/index.js b/node_modules/json5/lib/index.js new file mode 100644 index 0000000..3679638 --- /dev/null +++ b/node_modules/json5/lib/index.js @@ -0,0 +1,9 @@ +const parse = require('./parse') +const stringify = require('./stringify') + +const JSON5 = { + parse, + stringify, +} + +module.exports = JSON5 diff --git a/node_modules/json5/lib/parse.d.ts b/node_modules/json5/lib/parse.d.ts new file mode 100644 index 0000000..8c8d883 --- /dev/null +++ b/node_modules/json5/lib/parse.d.ts @@ -0,0 +1,15 @@ +/** + * Parses a JSON5 string, constructing the JavaScript value or object described + * by the string. + * @template T The type of the return value. + * @param text The string to parse as JSON5. + * @param reviver A function that prescribes how the value originally produced + * by parsing is transformed before being returned. + * @returns The JavaScript value converted from the JSON5 string. + */ +declare function parse( + text: string, + reviver?: ((this: any, key: string, value: any) => any) | null, +): T + +export = parse diff --git a/node_modules/json5/lib/parse.js b/node_modules/json5/lib/parse.js new file mode 100644 index 0000000..da2078a --- /dev/null +++ b/node_modules/json5/lib/parse.js @@ -0,0 +1,1114 @@ +const util = require('./util') + +let source +let parseState +let stack +let pos +let line +let column +let token +let key +let root + +module.exports = function parse (text, reviver) { + source = String(text) + parseState = 'start' + stack = [] + pos = 0 + line = 1 + column = 0 + token = undefined + key = undefined + root = undefined + + do { + token = lex() + + // This code is unreachable. + // if (!parseStates[parseState]) { + // throw invalidParseState() + // } + + parseStates[parseState]() + } while (token.type !== 'eof') + + if (typeof reviver === 'function') { + return internalize({'': root}, '', reviver) + } + + return root +} + +function internalize (holder, name, reviver) { + const value = holder[name] + if (value != null && typeof value === 'object') { + if (Array.isArray(value)) { + for (let i = 0; i < value.length; i++) { + const key = String(i) + const replacement = internalize(value, key, reviver) + if (replacement === undefined) { + delete value[key] + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }) + } + } + } else { + for (const key in value) { + const replacement = internalize(value, key, reviver) + if (replacement === undefined) { + delete value[key] + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }) + } + } + } + } + + return reviver.call(holder, name, value) +} + +let lexState +let buffer +let doubleQuote +let sign +let c + +function lex () { + lexState = 'default' + buffer = '' + doubleQuote = false + sign = 1 + + for (;;) { + c = peek() + + // This code is unreachable. + // if (!lexStates[lexState]) { + // throw invalidLexState(lexState) + // } + + const token = lexStates[lexState]() + if (token) { + return token + } + } +} + +function peek () { + if (source[pos]) { + return String.fromCodePoint(source.codePointAt(pos)) + } +} + +function read () { + const c = peek() + + if (c === '\n') { + line++ + column = 0 + } else if (c) { + column += c.length + } else { + column++ + } + + if (c) { + pos += c.length + } + + return c +} + +const lexStates = { + default () { + switch (c) { + case '\t': + case '\v': + case '\f': + case ' ': + case '\u00A0': + case '\uFEFF': + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read() + return + + case '/': + read() + lexState = 'comment' + return + + case undefined: + read() + return newToken('eof') + } + + if (util.isSpaceSeparator(c)) { + read() + return + } + + // This code is unreachable. + // if (!lexStates[parseState]) { + // throw invalidLexState(parseState) + // } + + return lexStates[parseState]() + }, + + comment () { + switch (c) { + case '*': + read() + lexState = 'multiLineComment' + return + + case '/': + read() + lexState = 'singleLineComment' + return + } + + throw invalidChar(read()) + }, + + multiLineComment () { + switch (c) { + case '*': + read() + lexState = 'multiLineCommentAsterisk' + return + + case undefined: + throw invalidChar(read()) + } + + read() + }, + + multiLineCommentAsterisk () { + switch (c) { + case '*': + read() + return + + case '/': + read() + lexState = 'default' + return + + case undefined: + throw invalidChar(read()) + } + + read() + lexState = 'multiLineComment' + }, + + singleLineComment () { + switch (c) { + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read() + lexState = 'default' + return + + case undefined: + read() + return newToken('eof') + } + + read() + }, + + value () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + case 'n': + read() + literal('ull') + return newToken('null', null) + + case 't': + read() + literal('rue') + return newToken('boolean', true) + + case 'f': + read() + literal('alse') + return newToken('boolean', false) + + case '-': + case '+': + if (read() === '-') { + sign = -1 + } + + lexState = 'sign' + return + + case '.': + buffer = read() + lexState = 'decimalPointLeading' + return + + case '0': + buffer = read() + lexState = 'zero' + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read() + lexState = 'decimalInteger' + return + + case 'I': + read() + literal('nfinity') + return newToken('numeric', Infinity) + + case 'N': + read() + literal('aN') + return newToken('numeric', NaN) + + case '"': + case "'": + doubleQuote = (read() === '"') + buffer = '' + lexState = 'string' + return + } + + throw invalidChar(read()) + }, + + identifierNameStartEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read() + const u = unicodeEscape() + switch (u) { + case '$': + case '_': + break + + default: + if (!util.isIdStartChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u + lexState = 'identifierName' + }, + + identifierName () { + switch (c) { + case '$': + case '_': + case '\u200C': + case '\u200D': + buffer += read() + return + + case '\\': + read() + lexState = 'identifierNameEscape' + return + } + + if (util.isIdContinueChar(c)) { + buffer += read() + return + } + + return newToken('identifier', buffer) + }, + + identifierNameEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read() + const u = unicodeEscape() + switch (u) { + case '$': + case '_': + case '\u200C': + case '\u200D': + break + + default: + if (!util.isIdContinueChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u + lexState = 'identifierName' + }, + + sign () { + switch (c) { + case '.': + buffer = read() + lexState = 'decimalPointLeading' + return + + case '0': + buffer = read() + lexState = 'zero' + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read() + lexState = 'decimalInteger' + return + + case 'I': + read() + literal('nfinity') + return newToken('numeric', sign * Infinity) + + case 'N': + read() + literal('aN') + return newToken('numeric', NaN) + } + + throw invalidChar(read()) + }, + + zero () { + switch (c) { + case '.': + buffer += read() + lexState = 'decimalPoint' + return + + case 'e': + case 'E': + buffer += read() + lexState = 'decimalExponent' + return + + case 'x': + case 'X': + buffer += read() + lexState = 'hexadecimal' + return + } + + return newToken('numeric', sign * 0) + }, + + decimalInteger () { + switch (c) { + case '.': + buffer += read() + lexState = 'decimalPoint' + return + + case 'e': + case 'E': + buffer += read() + lexState = 'decimalExponent' + return + } + + if (util.isDigit(c)) { + buffer += read() + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalPointLeading () { + if (util.isDigit(c)) { + buffer += read() + lexState = 'decimalFraction' + return + } + + throw invalidChar(read()) + }, + + decimalPoint () { + switch (c) { + case 'e': + case 'E': + buffer += read() + lexState = 'decimalExponent' + return + } + + if (util.isDigit(c)) { + buffer += read() + lexState = 'decimalFraction' + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalFraction () { + switch (c) { + case 'e': + case 'E': + buffer += read() + lexState = 'decimalExponent' + return + } + + if (util.isDigit(c)) { + buffer += read() + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalExponent () { + switch (c) { + case '+': + case '-': + buffer += read() + lexState = 'decimalExponentSign' + return + } + + if (util.isDigit(c)) { + buffer += read() + lexState = 'decimalExponentInteger' + return + } + + throw invalidChar(read()) + }, + + decimalExponentSign () { + if (util.isDigit(c)) { + buffer += read() + lexState = 'decimalExponentInteger' + return + } + + throw invalidChar(read()) + }, + + decimalExponentInteger () { + if (util.isDigit(c)) { + buffer += read() + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + hexadecimal () { + if (util.isHexDigit(c)) { + buffer += read() + lexState = 'hexadecimalInteger' + return + } + + throw invalidChar(read()) + }, + + hexadecimalInteger () { + if (util.isHexDigit(c)) { + buffer += read() + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + string () { + switch (c) { + case '\\': + read() + buffer += escape() + return + + case '"': + if (doubleQuote) { + read() + return newToken('string', buffer) + } + + buffer += read() + return + + case "'": + if (!doubleQuote) { + read() + return newToken('string', buffer) + } + + buffer += read() + return + + case '\n': + case '\r': + throw invalidChar(read()) + + case '\u2028': + case '\u2029': + separatorChar(c) + break + + case undefined: + throw invalidChar(read()) + } + + buffer += read() + }, + + start () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + // This code is unreachable since the default lexState handles eof. + // case undefined: + // return newToken('eof') + } + + lexState = 'value' + }, + + beforePropertyName () { + switch (c) { + case '$': + case '_': + buffer = read() + lexState = 'identifierName' + return + + case '\\': + read() + lexState = 'identifierNameStartEscape' + return + + case '}': + return newToken('punctuator', read()) + + case '"': + case "'": + doubleQuote = (read() === '"') + lexState = 'string' + return + } + + if (util.isIdStartChar(c)) { + buffer += read() + lexState = 'identifierName' + return + } + + throw invalidChar(read()) + }, + + afterPropertyName () { + if (c === ':') { + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforePropertyValue () { + lexState = 'value' + }, + + afterPropertyValue () { + switch (c) { + case ',': + case '}': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforeArrayValue () { + if (c === ']') { + return newToken('punctuator', read()) + } + + lexState = 'value' + }, + + afterArrayValue () { + switch (c) { + case ',': + case ']': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + end () { + // This code is unreachable since it's handled by the default lexState. + // if (c === undefined) { + // read() + // return newToken('eof') + // } + + throw invalidChar(read()) + }, +} + +function newToken (type, value) { + return { + type, + value, + line, + column, + } +} + +function literal (s) { + for (const c of s) { + const p = peek() + + if (p !== c) { + throw invalidChar(read()) + } + + read() + } +} + +function escape () { + const c = peek() + switch (c) { + case 'b': + read() + return '\b' + + case 'f': + read() + return '\f' + + case 'n': + read() + return '\n' + + case 'r': + read() + return '\r' + + case 't': + read() + return '\t' + + case 'v': + read() + return '\v' + + case '0': + read() + if (util.isDigit(peek())) { + throw invalidChar(read()) + } + + return '\0' + + case 'x': + read() + return hexEscape() + + case 'u': + read() + return unicodeEscape() + + case '\n': + case '\u2028': + case '\u2029': + read() + return '' + + case '\r': + read() + if (peek() === '\n') { + read() + } + + return '' + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + throw invalidChar(read()) + + case undefined: + throw invalidChar(read()) + } + + return read() +} + +function hexEscape () { + let buffer = '' + let c = peek() + + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read() + + c = peek() + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read() + + return String.fromCodePoint(parseInt(buffer, 16)) +} + +function unicodeEscape () { + let buffer = '' + let count = 4 + + while (count-- > 0) { + const c = peek() + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read() + } + + return String.fromCodePoint(parseInt(buffer, 16)) +} + +const parseStates = { + start () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push() + }, + + beforePropertyName () { + switch (token.type) { + case 'identifier': + case 'string': + key = token.value + parseState = 'afterPropertyName' + return + + case 'punctuator': + // This code is unreachable since it's handled by the lexState. + // if (token.value !== '}') { + // throw invalidToken() + // } + + pop() + return + + case 'eof': + throw invalidEOF() + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterPropertyName () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator' || token.value !== ':') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + parseState = 'beforePropertyValue' + }, + + beforePropertyValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push() + }, + + beforeArrayValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + if (token.type === 'punctuator' && token.value === ']') { + pop() + return + } + + push() + }, + + afterPropertyValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforePropertyName' + return + + case '}': + pop() + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterArrayValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforeArrayValue' + return + + case ']': + pop() + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + end () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'eof') { + // throw invalidToken() + // } + }, +} + +function push () { + let value + + switch (token.type) { + case 'punctuator': + switch (token.value) { + case '{': + value = {} + break + + case '[': + value = [] + break + } + + break + + case 'null': + case 'boolean': + case 'numeric': + case 'string': + value = token.value + break + + // This code is unreachable. + // default: + // throw invalidToken() + } + + if (root === undefined) { + root = value + } else { + const parent = stack[stack.length - 1] + if (Array.isArray(parent)) { + parent.push(value) + } else { + Object.defineProperty(parent, key, { + value, + writable: true, + enumerable: true, + configurable: true, + }) + } + } + + if (value !== null && typeof value === 'object') { + stack.push(value) + + if (Array.isArray(value)) { + parseState = 'beforeArrayValue' + } else { + parseState = 'beforePropertyName' + } + } else { + const current = stack[stack.length - 1] + if (current == null) { + parseState = 'end' + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue' + } else { + parseState = 'afterPropertyValue' + } + } +} + +function pop () { + stack.pop() + + const current = stack[stack.length - 1] + if (current == null) { + parseState = 'end' + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue' + } else { + parseState = 'afterPropertyValue' + } +} + +// This code is unreachable. +// function invalidParseState () { +// return new Error(`JSON5: invalid parse state '${parseState}'`) +// } + +// This code is unreachable. +// function invalidLexState (state) { +// return new Error(`JSON5: invalid lex state '${state}'`) +// } + +function invalidChar (c) { + if (c === undefined) { + return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) + } + + return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) +} + +function invalidEOF () { + return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) +} + +// This code is unreachable. +// function invalidToken () { +// if (token.type === 'eof') { +// return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) +// } + +// const c = String.fromCodePoint(token.value.codePointAt(0)) +// return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) +// } + +function invalidIdentifier () { + column -= 5 + return syntaxError(`JSON5: invalid identifier character at ${line}:${column}`) +} + +function separatorChar (c) { + console.warn(`JSON5: '${formatChar(c)}' in strings is not valid ECMAScript; consider escaping`) +} + +function formatChar (c) { + const replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + } + + if (replacements[c]) { + return replacements[c] + } + + if (c < ' ') { + const hexString = c.charCodeAt(0).toString(16) + return '\\x' + ('00' + hexString).substring(hexString.length) + } + + return c +} + +function syntaxError (message) { + const err = new SyntaxError(message) + err.lineNumber = line + err.columnNumber = column + return err +} diff --git a/node_modules/json5/lib/register.js b/node_modules/json5/lib/register.js new file mode 100644 index 0000000..935cdba --- /dev/null +++ b/node_modules/json5/lib/register.js @@ -0,0 +1,13 @@ +const fs = require('fs') +const JSON5 = require('./') + +// eslint-disable-next-line node/no-deprecated-api +require.extensions['.json5'] = function (module, filename) { + const content = fs.readFileSync(filename, 'utf8') + try { + module.exports = JSON5.parse(content) + } catch (err) { + err.message = filename + ': ' + err.message + throw err + } +} diff --git a/node_modules/json5/lib/require.js b/node_modules/json5/lib/require.js new file mode 100644 index 0000000..3aa29be --- /dev/null +++ b/node_modules/json5/lib/require.js @@ -0,0 +1,4 @@ +// This file is for backward compatibility with v0.5.1. +require('./register') + +console.warn("'json5/require' is deprecated. Please use 'json5/register' instead.") diff --git a/node_modules/json5/lib/stringify.d.ts b/node_modules/json5/lib/stringify.d.ts new file mode 100644 index 0000000..3c34838 --- /dev/null +++ b/node_modules/json5/lib/stringify.d.ts @@ -0,0 +1,89 @@ +declare type StringifyOptions = { + /** + * A function that alters the behavior of the stringification process, or an + * array of String and Number objects that serve as a allowlist for + * selecting/filtering the properties of the value object to be included in + * the JSON5 string. If this value is null or not provided, all properties + * of the object are included in the resulting JSON5 string. + */ + replacer?: + | ((this: any, key: string, value: any) => any) + | (string | number)[] + | null + + /** + * A String or Number object that's used to insert white space into the + * output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this + * number is capped at 10 (if it is greater, the value is just 10). Values + * less than 1 indicate that no space should be used. If this is a String, + * the string (or the first 10 characters of the string, if it's longer than + * that) is used as white space. If this parameter is not provided (or is + * null), no white space is used. If white space is used, trailing commas + * will be used in objects and arrays. + */ + space?: string | number | null + + /** + * A String representing the quote character to use when serializing + * strings. + */ + quote?: string | null +} + +/** + * Converts a JavaScript value to a JSON5 string. + * @param value The value to convert to a JSON5 string. + * @param replacer A function that alters the behavior of the stringification + * process. If this value is null or not provided, all properties of the object + * are included in the resulting JSON5 string. + * @param space A String or Number object that's used to insert white space into + * the output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this number + * is capped at 10 (if it is greater, the value is just 10). Values less than 1 + * indicate that no space should be used. If this is a String, the string (or + * the first 10 characters of the string, if it's longer than that) is used as + * white space. If this parameter is not provided (or is null), no white space + * is used. If white space is used, trailing commas will be used in objects and + * arrays. + * @returns The JSON5 string converted from the JavaScript value. + */ +declare function stringify( + value: any, + replacer?: ((this: any, key: string, value: any) => any) | null, + space?: string | number | null, +): string + +/** + * Converts a JavaScript value to a JSON5 string. + * @param value The value to convert to a JSON5 string. + * @param replacer An array of String and Number objects that serve as a + * allowlist for selecting/filtering the properties of the value object to be + * included in the JSON5 string. If this value is null or not provided, all + * properties of the object are included in the resulting JSON5 string. + * @param space A String or Number object that's used to insert white space into + * the output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this number + * is capped at 10 (if it is greater, the value is just 10). Values less than 1 + * indicate that no space should be used. If this is a String, the string (or + * the first 10 characters of the string, if it's longer than that) is used as + * white space. If this parameter is not provided (or is null), no white space + * is used. If white space is used, trailing commas will be used in objects and + * arrays. + * @returns The JSON5 string converted from the JavaScript value. + */ +declare function stringify( + value: any, + replacer: (string | number)[], + space?: string | number | null, +): string + +/** + * Converts a JavaScript value to a JSON5 string. + * @param value The value to convert to a JSON5 string. + * @param options An object specifying options. + * @returns The JSON5 string converted from the JavaScript value. + */ +declare function stringify(value: any, options: StringifyOptions): string + +export = stringify diff --git a/node_modules/json5/lib/stringify.js b/node_modules/json5/lib/stringify.js new file mode 100644 index 0000000..7cb3b0e --- /dev/null +++ b/node_modules/json5/lib/stringify.js @@ -0,0 +1,261 @@ +const util = require('./util') + +module.exports = function stringify (value, replacer, space) { + const stack = [] + let indent = '' + let propertyList + let replacerFunc + let gap = '' + let quote + + if ( + replacer != null && + typeof replacer === 'object' && + !Array.isArray(replacer) + ) { + space = replacer.space + quote = replacer.quote + replacer = replacer.replacer + } + + if (typeof replacer === 'function') { + replacerFunc = replacer + } else if (Array.isArray(replacer)) { + propertyList = [] + for (const v of replacer) { + let item + + if (typeof v === 'string') { + item = v + } else if ( + typeof v === 'number' || + v instanceof String || + v instanceof Number + ) { + item = String(v) + } + + if (item !== undefined && propertyList.indexOf(item) < 0) { + propertyList.push(item) + } + } + } + + if (space instanceof Number) { + space = Number(space) + } else if (space instanceof String) { + space = String(space) + } + + if (typeof space === 'number') { + if (space > 0) { + space = Math.min(10, Math.floor(space)) + gap = ' '.substr(0, space) + } + } else if (typeof space === 'string') { + gap = space.substr(0, 10) + } + + return serializeProperty('', {'': value}) + + function serializeProperty (key, holder) { + let value = holder[key] + if (value != null) { + if (typeof value.toJSON5 === 'function') { + value = value.toJSON5(key) + } else if (typeof value.toJSON === 'function') { + value = value.toJSON(key) + } + } + + if (replacerFunc) { + value = replacerFunc.call(holder, key, value) + } + + if (value instanceof Number) { + value = Number(value) + } else if (value instanceof String) { + value = String(value) + } else if (value instanceof Boolean) { + value = value.valueOf() + } + + switch (value) { + case null: return 'null' + case true: return 'true' + case false: return 'false' + } + + if (typeof value === 'string') { + return quoteString(value, false) + } + + if (typeof value === 'number') { + return String(value) + } + + if (typeof value === 'object') { + return Array.isArray(value) ? serializeArray(value) : serializeObject(value) + } + + return undefined + } + + function quoteString (value) { + const quotes = { + "'": 0.1, + '"': 0.2, + } + + const replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + } + + let product = '' + + for (let i = 0; i < value.length; i++) { + const c = value[i] + switch (c) { + case "'": + case '"': + quotes[c]++ + product += c + continue + + case '\0': + if (util.isDigit(value[i + 1])) { + product += '\\x00' + continue + } + } + + if (replacements[c]) { + product += replacements[c] + continue + } + + if (c < ' ') { + let hexString = c.charCodeAt(0).toString(16) + product += '\\x' + ('00' + hexString).substring(hexString.length) + continue + } + + product += c + } + + const quoteChar = quote || Object.keys(quotes).reduce((a, b) => (quotes[a] < quotes[b]) ? a : b) + + product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]) + + return quoteChar + product + quoteChar + } + + function serializeObject (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value) + + let stepback = indent + indent = indent + gap + + let keys = propertyList || Object.keys(value) + let partial = [] + for (const key of keys) { + const propertyString = serializeProperty(key, value) + if (propertyString !== undefined) { + let member = serializeKey(key) + ':' + if (gap !== '') { + member += ' ' + } + member += propertyString + partial.push(member) + } + } + + let final + if (partial.length === 0) { + final = '{}' + } else { + let properties + if (gap === '') { + properties = partial.join(',') + final = '{' + properties + '}' + } else { + let separator = ',\n' + indent + properties = partial.join(separator) + final = '{\n' + indent + properties + ',\n' + stepback + '}' + } + } + + stack.pop() + indent = stepback + return final + } + + function serializeKey (key) { + if (key.length === 0) { + return quoteString(key, true) + } + + const firstChar = String.fromCodePoint(key.codePointAt(0)) + if (!util.isIdStartChar(firstChar)) { + return quoteString(key, true) + } + + for (let i = firstChar.length; i < key.length; i++) { + if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) { + return quoteString(key, true) + } + } + + return key + } + + function serializeArray (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value) + + let stepback = indent + indent = indent + gap + + let partial = [] + for (let i = 0; i < value.length; i++) { + const propertyString = serializeProperty(String(i), value) + partial.push((propertyString !== undefined) ? propertyString : 'null') + } + + let final + if (partial.length === 0) { + final = '[]' + } else { + if (gap === '') { + let properties = partial.join(',') + final = '[' + properties + ']' + } else { + let separator = ',\n' + indent + let properties = partial.join(separator) + final = '[\n' + indent + properties + ',\n' + stepback + ']' + } + } + + stack.pop() + indent = stepback + return final + } +} diff --git a/node_modules/json5/lib/unicode.d.ts b/node_modules/json5/lib/unicode.d.ts new file mode 100644 index 0000000..610f805 --- /dev/null +++ b/node_modules/json5/lib/unicode.d.ts @@ -0,0 +1,3 @@ +export declare const Space_Separator: RegExp +export declare const ID_Start: RegExp +export declare const ID_Continue: RegExp diff --git a/node_modules/json5/lib/unicode.js b/node_modules/json5/lib/unicode.js new file mode 100644 index 0000000..215ccd8 --- /dev/null +++ b/node_modules/json5/lib/unicode.js @@ -0,0 +1,4 @@ +// This is a generated file. Do not edit. +module.exports.Space_Separator = /[\u1680\u2000-\u200A\u202F\u205F\u3000]/ +module.exports.ID_Start = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/ +module.exports.ID_Continue = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/ diff --git a/node_modules/json5/lib/util.d.ts b/node_modules/json5/lib/util.d.ts new file mode 100644 index 0000000..a940cea --- /dev/null +++ b/node_modules/json5/lib/util.d.ts @@ -0,0 +1,5 @@ +export declare function isSpaceSeparator(c?: string): boolean +export declare function isIdStartChar(c?: string): boolean +export declare function isIdContinueChar(c?: string): boolean +export declare function isDigit(c?: string): boolean +export declare function isHexDigit(c?: string): boolean diff --git a/node_modules/json5/lib/util.js b/node_modules/json5/lib/util.js new file mode 100644 index 0000000..40bfe2f --- /dev/null +++ b/node_modules/json5/lib/util.js @@ -0,0 +1,35 @@ +const unicode = require('../lib/unicode') + +module.exports = { + isSpaceSeparator (c) { + return typeof c === 'string' && unicode.Space_Separator.test(c) + }, + + isIdStartChar (c) { + return typeof c === 'string' && ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c === '$') || (c === '_') || + unicode.ID_Start.test(c) + ) + }, + + isIdContinueChar (c) { + return typeof c === 'string' && ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + (c === '$') || (c === '_') || + (c === '\u200C') || (c === '\u200D') || + unicode.ID_Continue.test(c) + ) + }, + + isDigit (c) { + return typeof c === 'string' && /[0-9]/.test(c) + }, + + isHexDigit (c) { + return typeof c === 'string' && /[0-9A-Fa-f]/.test(c) + }, +} diff --git a/node_modules/json5/package.json b/node_modules/json5/package.json new file mode 100644 index 0000000..60c51d9 --- /dev/null +++ b/node_modules/json5/package.json @@ -0,0 +1,72 @@ +{ + "name": "json5", + "version": "2.2.3", + "description": "JSON for Humans", + "main": "lib/index.js", + "module": "dist/index.mjs", + "bin": "lib/cli.js", + "browser": "dist/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib/", + "dist/" + ], + "engines": { + "node": ">=6" + }, + "scripts": { + "build": "rollup -c", + "build-package": "node build/package.js", + "build-unicode": "node build/unicode.js", + "coverage": "tap --coverage-report html test", + "lint": "eslint --fix .", + "lint-report": "eslint .", + "prepublishOnly": "npm run production", + "preversion": "npm run production", + "production": "run-s test build", + "tap": "tap -Rspec --100 test", + "test": "run-s lint-report tap", + "version": "npm run build-package && git add package.json5" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/json5/json5.git" + }, + "keywords": [ + "json", + "json5", + "es5", + "es2015", + "ecmascript" + ], + "author": "Aseem Kishore ", + "contributors": [ + "Max Nanasy ", + "Andrew Eisenberg ", + "Jordan Tucker " + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/json5/json5/issues" + }, + "homepage": "http://json5.org/", + "devDependencies": { + "core-js": "^2.6.5", + "eslint": "^5.15.3", + "eslint-config-standard": "^12.0.0", + "eslint-plugin-import": "^2.16.0", + "eslint-plugin-node": "^8.0.1", + "eslint-plugin-promise": "^4.0.1", + "eslint-plugin-standard": "^4.0.0", + "npm-run-all": "^4.1.5", + "regenerate": "^1.4.0", + "rollup": "^0.64.1", + "rollup-plugin-buble": "^0.19.6", + "rollup-plugin-commonjs": "^9.2.1", + "rollup-plugin-node-resolve": "^3.4.0", + "rollup-plugin-terser": "^1.0.1", + "sinon": "^6.3.5", + "tap": "^12.6.0", + "unicode-10.0.0": "^0.7.5" + } +} diff --git a/node_modules/lowdb/LICENSE b/node_modules/lowdb/LICENSE new file mode 100644 index 0000000..049c9dc --- /dev/null +++ b/node_modules/lowdb/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 typicode + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/lowdb/README.md b/node_modules/lowdb/README.md new file mode 100644 index 0000000..08a0c0a --- /dev/null +++ b/node_modules/lowdb/README.md @@ -0,0 +1,404 @@ +# lowdb [![](http://img.shields.io/npm/dm/lowdb.svg?style=flat)](https://www.npmjs.org/package/lowdb) [![Node.js CI](https://github.com/typicode/lowdb/actions/workflows/node.js.yml/badge.svg)](https://github.com/typicode/lowdb/actions/workflows/node.js.yml) + +> Simple to use type-safe local JSON database 🦉 + +Read or create `db.json` + +```js +const db = await JSONFilePreset('db.json', { posts: [] }) +``` + +Update data using `Array.prototype.*` and automatically write to `db.json` + +```js +const post = { id: 1, title: 'lowdb is awesome', views: 100 } +await db.update(({ posts }) => posts.push(post)) +``` + +```js +// db.json +{ + "posts": [ + { "id": 1, "title": "lowdb is awesome", "views": 100 } + ] +} +``` + +In the same spirit, query using native `Array.prototype.*` + +```js +const { posts } = db.data +const first = posts.at(0) +const results = posts.filter((post) => post.title.includes('lowdb')) +const post1 = posts.find((post) => post.id === 1) +const sortedPosts = posts.toSorted((a, b) => a.views - b.views) +``` + +It's that simple. + +## Sponsors + +
+
+ +

+ + + +

+ +
+
+ +[Become a sponsor and have your company logo here](https://github.com/sponsors/typicode) 👉 [GitHub Sponsors](https://github.com/sponsors/typicode) + +## Features + +- **Lightweight** +- **Minimalist** +- **TypeScript** +- **Plain JavaScript** +- Safe atomic writes +- Hackable: + - Change storage, file format (JSON, YAML, ...) or add encryption via [adapters](#adapters) + - Extend it with lodash, ramda, ... for super powers! +- Automatically switches to fast in-memory mode during tests + +## Install + +```sh +npm install lowdb +``` + +## Usage + +_Lowdb is a pure ESM package. If you're having trouble using it in your project, please [read this](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c)._ + +```js +import { JSONFilePreset } from 'lowdb/node' + +// Read or create db.json +const defaultData = { posts: [] } +const db = await JSONFilePreset('db.json', defaultData) + +// Update db.json +await db.update(({ posts }) => posts.push('hello world')) + +// Alternatively you can call db.write() explicitely later +// to write to db.json +db.data.posts.push('hello world') +await db.write() +``` + +```js +// db.json +{ + "posts": [ "hello world" ] +} +``` + +### TypeScript + +You can use TypeScript to check your data types. + +```ts +type Data = { + messages: string[] +} + +const defaultData: Data = { messages: [] } +const db = await JSONPreset('db.json', defaultData) + +db.data.messages.push('foo') // ✅ Success +db.data.messages.push(1) // ❌ TypeScript error +``` + +### Lodash + +You can extend lowdb with Lodash (or other libraries). To be able to extend it, we're not using `JSONPreset` here. Instead, we're using lower components. + +```ts +import { Low } from 'lowdb' +import { JSONFile } from 'lowdb/node' +import lodash from 'lodash' + +type Post = { + id: number + title: string +} + +type Data = { + posts: Post[] +} + +// Extend Low class with a new `chain` field +class LowWithLodash extends Low { + chain: lodash.ExpChain = lodash.chain(this).get('data') +} + +const defaultData: Data = { + posts: [], +} +const adapter = new JSONFile('db.json', defaultData) + +const db = new LowWithLodash(adapter) +await db.read() + +// Instead of db.data use db.chain to access lodash API +const post = db.chain.get('posts').find({ id: 1 }).value() // Important: value() must be called to execute chain +``` + +### CLI, Server, Browser and in tests usage + +See [`src/examples/`](src/examples) directory. + +## API + +### Presets + +Lowdb provides four presets for common cases. + +- `JSONFilePreset(filename, defaultData)` +- `JSONFileSyncPreset(filename, defaultData)` +- `LocalStoragePreset(name, defaultData)` +- `SessionStoragePreset(name, defaultData)` + +See [`src/examples/`](src/examples) directory for usage. + +Lowdb is extremely flexible, if you need to extend it or modify its behavior, use the classes and adapters below instead of the presets. + +### Classes + +Lowdb has two classes (for asynchronous and synchronous adapters). + +#### `new Low(adapter, defaultData)` + +```js +import { Low } from 'lowdb' +import { JSONFile } from 'lowdb/node' + +const db = new Low(new JSONFile('file.json'), {}) +await db.read() +await db.write() +``` + +#### `new LowSync(adapterSync, defaultData)` + +```js +import { LowSync } from 'lowdb' +import { JSONFileSync } from 'lowdb/node' + +const db = new LowSync(new JSONFileSync('file.json'), {}) +db.read() +db.write() +``` + +### Methods + +#### `db.read()` + +Calls `adapter.read()` and sets `db.data`. + +**Note:** `JSONFile` and `JSONFileSync` adapters will set `db.data` to `null` if file doesn't exist. + +```js +db.data // === null +db.read() +db.data // !== null +``` + +#### `db.write()` + +Calls `adapter.write(db.data)`. + +```js +db.data = { posts: [] } +db.write() // file.json will be { posts: [] } +db.data = {} +db.write() // file.json will be {} +``` + +#### `db.update(fn)` + +Calls `fn()` then `db.write()`. + +```js +db.update((data) => { + // make changes to data + // ... +}) +// files.json will be updated +``` + +### Properties + +#### `db.data` + +Holds your db content. If you're using the adapters coming with lowdb, it can be any type supported by [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). + +For example: + +```js +db.data = 'string' +db.data = [1, 2, 3] +db.data = { key: 'value' } +``` + +## Adapters + +### Lowdb adapters + +#### `JSONFile` `JSONFileSync` + +Adapters for reading and writing JSON files. + +```js +import { JSONFile, JSONFileSync } from 'lowdb/node' + +new Low(new JSONFile(filename), {}) +new LowSync(new JSONFileSync(filename), {}) +``` + +#### `Memory` `MemorySync` + +In-memory adapters. Useful for speeding up unit tests. See [`src/examples/`](src/examples) directory. + +```js +import { Memory, MemorySync } from 'lowdb' + +new Low(new Memory(), {}) +new LowSync(new MemorySync(), {}) +``` + +#### `LocalStorage` `SessionStorage` + +Synchronous adapter for `window.localStorage` and `window.sessionStorage`. + +```js +import { LocalStorage, SessionStorage } from 'lowdb/browser' +new LowSync(new LocalStorage(name), {}) +new LowSync(new SessionStorage(name), {}) +``` + +### Utility adapters + +#### `TextFile` `TextFileSync` + +Adapters for reading and writing text. Useful for creating custom adapters. + +#### `DataFile` `DataFileSync` + +Adapters for easily supporting other data formats or adding behaviors (encrypt, compress...). + +```js +import { DataFile } from 'lowdb' +new DataFile(filename, { + parse: YAML.parse, + stringify: YAML.stringify +}) +new DataFile(filename, { + parse: (data) => { decypt(JSON.parse(data)) }, + stringify: (str) => { encrypt(JSON.stringify(str)) } +}) +``` + +### Third-party adapters + +If you've published an adapter for lowdb, feel free to create a PR to add it here. + +### Writing your own adapter + +You may want to create an adapter to write `db.data` to YAML, XML, encrypt data, a remote storage, ... + +An adapter is a simple class that just needs to expose two methods: + +```js +class AsyncAdapter { + read() { + /* ... */ + } // should return Promise + write(data) { + /* ... */ + } // should return Promise +} + +class SyncAdapter { + read() { + /* ... */ + } // should return data + write(data) { + /* ... */ + } // should return nothing +} +``` + +For example, let's say you have some async storage and want to create an adapter for it: + +```js +import { api } from './AsyncStorage' + +class CustomAsyncAdapter { + // Optional: your adapter can take arguments + constructor(args) { + // ... + } + + async read() { + const data = await api.read() + return data + } + + async write(data) { + await api.write(data) + } +} + +const adapter = new CustomAsyncAdapter() +const db = new Low(adapter) +``` + +See [`src/adapters/`](src/adapters) for more examples. + +#### Custom serialization + +To create an adapter for another format than JSON, you can use `TextFile` or `TextFileSync`. + +For example: + +```js +import { Adapter, Low } from 'lowdb' +import { TextFile } from 'lowdb/node' +import YAML from 'yaml' + +class YAMLFile { + constructor(filename) { + this.adapter = new TextFile(filename) + } + + async read() { + const data = await this.adapter.read() + if (data === null) { + return null + } else { + return YAML.parse(data) + } + } + + write(obj) { + return this.adapter.write(YAML.stringify(obj)) + } +} + +const adapter = new YAMLFile('file.yaml') +const db = new Low(adapter) +``` + +## Limits + +Lowdb doesn't support Node's cluster module. + +If you have large JavaScript objects (`~10-100MB`) you may hit some performance issues. This is because whenever you call `db.write`, the whole `db.data` is serialized using `JSON.stringify` and written to storage. + +Depending on your use case, this can be fine or not. It can be mitigated by doing batch operations and calling `db.write` only when you need it. + +If you plan to scale, it's highly recommended to use databases like PostgreSQL or MongoDB instead. diff --git a/node_modules/lowdb/lib/adapters/Memory.d.ts b/node_modules/lowdb/lib/adapters/Memory.d.ts new file mode 100644 index 0000000..9e79cef --- /dev/null +++ b/node_modules/lowdb/lib/adapters/Memory.d.ts @@ -0,0 +1,11 @@ +import { Adapter, SyncAdapter } from '../core/Low.js'; +export declare class Memory implements Adapter { + #private; + read(): Promise; + write(obj: T): Promise; +} +export declare class MemorySync implements SyncAdapter { + #private; + read(): T | null; + write(obj: T): void; +} diff --git a/node_modules/lowdb/lib/adapters/Memory.js b/node_modules/lowdb/lib/adapters/Memory.js new file mode 100644 index 0000000..d6cfb94 --- /dev/null +++ b/node_modules/lowdb/lib/adapters/Memory.js @@ -0,0 +1,19 @@ +export class Memory { + #data = null; + read() { + return Promise.resolve(this.#data); + } + write(obj) { + this.#data = obj; + return Promise.resolve(); + } +} +export class MemorySync { + #data = null; + read() { + return this.#data || null; + } + write(obj) { + this.#data = obj; + } +} diff --git a/node_modules/lowdb/lib/adapters/browser/LocalStorage.d.ts b/node_modules/lowdb/lib/adapters/browser/LocalStorage.d.ts new file mode 100644 index 0000000..13df237 --- /dev/null +++ b/node_modules/lowdb/lib/adapters/browser/LocalStorage.d.ts @@ -0,0 +1,4 @@ +import { WebStorage } from './WebStorage.js'; +export declare class LocalStorage extends WebStorage { + constructor(key: string); +} diff --git a/node_modules/lowdb/lib/adapters/browser/LocalStorage.js b/node_modules/lowdb/lib/adapters/browser/LocalStorage.js new file mode 100644 index 0000000..1a6b2fc --- /dev/null +++ b/node_modules/lowdb/lib/adapters/browser/LocalStorage.js @@ -0,0 +1,6 @@ +import { WebStorage } from './WebStorage.js'; +export class LocalStorage extends WebStorage { + constructor(key) { + super(key, localStorage); + } +} diff --git a/node_modules/lowdb/lib/adapters/browser/SessionStorage.d.ts b/node_modules/lowdb/lib/adapters/browser/SessionStorage.d.ts new file mode 100644 index 0000000..5f9e6e2 --- /dev/null +++ b/node_modules/lowdb/lib/adapters/browser/SessionStorage.d.ts @@ -0,0 +1,4 @@ +import { WebStorage } from './WebStorage.js'; +export declare class SessionStorage extends WebStorage { + constructor(key: string); +} diff --git a/node_modules/lowdb/lib/adapters/browser/SessionStorage.js b/node_modules/lowdb/lib/adapters/browser/SessionStorage.js new file mode 100644 index 0000000..5679f3f --- /dev/null +++ b/node_modules/lowdb/lib/adapters/browser/SessionStorage.js @@ -0,0 +1,6 @@ +import { WebStorage } from './WebStorage.js'; +export class SessionStorage extends WebStorage { + constructor(key) { + super(key, sessionStorage); + } +} diff --git a/node_modules/lowdb/lib/adapters/browser/WebStorage.d.ts b/node_modules/lowdb/lib/adapters/browser/WebStorage.d.ts new file mode 100644 index 0000000..0833a90 --- /dev/null +++ b/node_modules/lowdb/lib/adapters/browser/WebStorage.d.ts @@ -0,0 +1,7 @@ +import { SyncAdapter } from '../../core/Low.js'; +export declare class WebStorage implements SyncAdapter { + #private; + constructor(key: string, storage: Storage); + read(): T | null; + write(obj: T): void; +} diff --git a/node_modules/lowdb/lib/adapters/browser/WebStorage.js b/node_modules/lowdb/lib/adapters/browser/WebStorage.js new file mode 100644 index 0000000..f0bd7ea --- /dev/null +++ b/node_modules/lowdb/lib/adapters/browser/WebStorage.js @@ -0,0 +1,18 @@ +export class WebStorage { + #key; + #storage; + constructor(key, storage) { + this.#key = key; + this.#storage = storage; + } + read() { + const value = this.#storage.getItem(this.#key); + if (value === null) { + return null; + } + return JSON.parse(value); + } + write(obj) { + this.#storage.setItem(this.#key, JSON.stringify(obj)); + } +} diff --git a/node_modules/lowdb/lib/adapters/node/DataFile.d.ts b/node_modules/lowdb/lib/adapters/node/DataFile.d.ts new file mode 100644 index 0000000..65f569e --- /dev/null +++ b/node_modules/lowdb/lib/adapters/node/DataFile.d.ts @@ -0,0 +1,21 @@ +/// +import { PathLike } from 'fs'; +import { Adapter, SyncAdapter } from '../../core/Low.js'; +export declare class DataFile implements Adapter { + #private; + constructor(filename: PathLike, { parse, stringify, }: { + parse: (str: string) => T; + stringify: (data: T) => string; + }); + read(): Promise; + write(obj: T): Promise; +} +export declare class DataFileSync implements SyncAdapter { + #private; + constructor(filename: PathLike, { parse, stringify, }: { + parse: (str: string) => T; + stringify: (data: T) => string; + }); + read(): T | null; + write(obj: T): void; +} diff --git a/node_modules/lowdb/lib/adapters/node/DataFile.js b/node_modules/lowdb/lib/adapters/node/DataFile.js new file mode 100644 index 0000000..cde9d6d --- /dev/null +++ b/node_modules/lowdb/lib/adapters/node/DataFile.js @@ -0,0 +1,45 @@ +import { TextFile, TextFileSync } from './TextFile.js'; +export class DataFile { + #adapter; + #parse; + #stringify; + constructor(filename, { parse, stringify, }) { + this.#adapter = new TextFile(filename); + this.#parse = parse; + this.#stringify = stringify; + } + async read() { + const data = await this.#adapter.read(); + if (data === null) { + return null; + } + else { + return this.#parse(data); + } + } + write(obj) { + return this.#adapter.write(this.#stringify(obj)); + } +} +export class DataFileSync { + #adapter; + #parse; + #stringify; + constructor(filename, { parse, stringify, }) { + this.#adapter = new TextFileSync(filename); + this.#parse = parse; + this.#stringify = stringify; + } + read() { + const data = this.#adapter.read(); + if (data === null) { + return null; + } + else { + return this.#parse(data); + } + } + write(obj) { + this.#adapter.write(this.#stringify(obj)); + } +} diff --git a/node_modules/lowdb/lib/adapters/node/JSONFile.d.ts b/node_modules/lowdb/lib/adapters/node/JSONFile.d.ts new file mode 100644 index 0000000..03c11ce --- /dev/null +++ b/node_modules/lowdb/lib/adapters/node/JSONFile.d.ts @@ -0,0 +1,9 @@ +/// +import { PathLike } from 'fs'; +import { DataFile, DataFileSync } from './DataFile.js'; +export declare class JSONFile extends DataFile { + constructor(filename: PathLike); +} +export declare class JSONFileSync extends DataFileSync { + constructor(filename: PathLike); +} diff --git a/node_modules/lowdb/lib/adapters/node/JSONFile.js b/node_modules/lowdb/lib/adapters/node/JSONFile.js new file mode 100644 index 0000000..a7527f7 --- /dev/null +++ b/node_modules/lowdb/lib/adapters/node/JSONFile.js @@ -0,0 +1,17 @@ +import { DataFile, DataFileSync } from './DataFile.js'; +export class JSONFile extends DataFile { + constructor(filename) { + super(filename, { + parse: JSON.parse, + stringify: (data) => JSON.stringify(data, null, 2), + }); + } +} +export class JSONFileSync extends DataFileSync { + constructor(filename) { + super(filename, { + parse: JSON.parse, + stringify: (data) => JSON.stringify(data, null, 2), + }); + } +} diff --git a/node_modules/lowdb/lib/adapters/node/TextFile.d.ts b/node_modules/lowdb/lib/adapters/node/TextFile.d.ts new file mode 100644 index 0000000..7f9d214 --- /dev/null +++ b/node_modules/lowdb/lib/adapters/node/TextFile.d.ts @@ -0,0 +1,15 @@ +/// +import { PathLike } from 'node:fs'; +import { Adapter, SyncAdapter } from '../../core/Low.js'; +export declare class TextFile implements Adapter { + #private; + constructor(filename: PathLike); + read(): Promise; + write(str: string): Promise; +} +export declare class TextFileSync implements SyncAdapter { + #private; + constructor(filename: PathLike); + read(): string | null; + write(str: string): void; +} diff --git a/node_modules/lowdb/lib/adapters/node/TextFile.js b/node_modules/lowdb/lib/adapters/node/TextFile.js new file mode 100644 index 0000000..f083241 --- /dev/null +++ b/node_modules/lowdb/lib/adapters/node/TextFile.js @@ -0,0 +1,54 @@ +import { readFileSync, renameSync, writeFileSync } from 'node:fs'; +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { Writer } from 'steno'; +export class TextFile { + #filename; + #writer; + constructor(filename) { + this.#filename = filename; + this.#writer = new Writer(filename); + } + async read() { + let data; + try { + data = await readFile(this.#filename, 'utf-8'); + } + catch (e) { + if (e.code === 'ENOENT') { + return null; + } + throw e; + } + return data; + } + write(str) { + return this.#writer.write(str); + } +} +export class TextFileSync { + #tempFilename; + #filename; + constructor(filename) { + this.#filename = filename; + const f = filename.toString(); + this.#tempFilename = path.join(path.dirname(f), `.${path.basename(f)}.tmp`); + } + read() { + let data; + try { + data = readFileSync(this.#filename, 'utf-8'); + } + catch (e) { + if (e.code === 'ENOENT') { + return null; + } + throw e; + } + return data; + } + write(str) { + writeFileSync(this.#tempFilename, str); + renameSync(this.#tempFilename, this.#filename); + } +} diff --git a/node_modules/lowdb/lib/browser.d.ts b/node_modules/lowdb/lib/browser.d.ts new file mode 100644 index 0000000..c580f33 --- /dev/null +++ b/node_modules/lowdb/lib/browser.d.ts @@ -0,0 +1,3 @@ +export * from './adapters/browser/LocalStorage.js'; +export * from './adapters/browser/SessionStorage.js'; +export * from './presets/browser.js'; diff --git a/node_modules/lowdb/lib/browser.js b/node_modules/lowdb/lib/browser.js new file mode 100644 index 0000000..c580f33 --- /dev/null +++ b/node_modules/lowdb/lib/browser.js @@ -0,0 +1,3 @@ +export * from './adapters/browser/LocalStorage.js'; +export * from './adapters/browser/SessionStorage.js'; +export * from './presets/browser.js'; diff --git a/node_modules/lowdb/lib/core/Low.d.ts b/node_modules/lowdb/lib/core/Low.d.ts new file mode 100644 index 0000000..55d430c --- /dev/null +++ b/node_modules/lowdb/lib/core/Low.d.ts @@ -0,0 +1,24 @@ +export interface Adapter { + read: () => Promise; + write: (data: T) => Promise; +} +export interface SyncAdapter { + read: () => T | null; + write: (data: T) => void; +} +export declare class Low { + adapter: Adapter; + data: T; + constructor(adapter: Adapter, defaultData: T); + read(): Promise; + write(): Promise; + update(fn: (data: T) => unknown): Promise; +} +export declare class LowSync { + adapter: SyncAdapter; + data: T; + constructor(adapter: SyncAdapter, defaultData: T); + read(): void; + write(): void; + update(fn: (data: T) => unknown): void; +} diff --git a/node_modules/lowdb/lib/core/Low.js b/node_modules/lowdb/lib/core/Low.js new file mode 100644 index 0000000..528e618 --- /dev/null +++ b/node_modules/lowdb/lib/core/Low.js @@ -0,0 +1,50 @@ +function checkArgs(adapter, defaultData) { + if (adapter === undefined) + throw new Error('lowdb: missing adapter'); + if (defaultData === undefined) + throw new Error('lowdb: missing default data'); +} +export class Low { + adapter; + data; + constructor(adapter, defaultData) { + checkArgs(adapter, defaultData); + this.adapter = adapter; + this.data = defaultData; + } + async read() { + const data = await this.adapter.read(); + if (data) + this.data = data; + } + async write() { + if (this.data) + await this.adapter.write(this.data); + } + async update(fn) { + fn(this.data); + await this.write(); + } +} +export class LowSync { + adapter; + data; + constructor(adapter, defaultData) { + checkArgs(adapter, defaultData); + this.adapter = adapter; + this.data = defaultData; + } + read() { + const data = this.adapter.read(); + if (data) + this.data = data; + } + write() { + if (this.data) + this.adapter.write(this.data); + } + update(fn) { + fn(this.data); + this.write(); + } +} diff --git a/node_modules/lowdb/lib/index.d.ts b/node_modules/lowdb/lib/index.d.ts new file mode 100644 index 0000000..57a9950 --- /dev/null +++ b/node_modules/lowdb/lib/index.d.ts @@ -0,0 +1,2 @@ +export * from './adapters/Memory.js'; +export * from './core/Low.js'; diff --git a/node_modules/lowdb/lib/index.js b/node_modules/lowdb/lib/index.js new file mode 100644 index 0000000..57a9950 --- /dev/null +++ b/node_modules/lowdb/lib/index.js @@ -0,0 +1,2 @@ +export * from './adapters/Memory.js'; +export * from './core/Low.js'; diff --git a/node_modules/lowdb/lib/node.d.ts b/node_modules/lowdb/lib/node.d.ts new file mode 100644 index 0000000..81c5f4a --- /dev/null +++ b/node_modules/lowdb/lib/node.d.ts @@ -0,0 +1,4 @@ +export * from './adapters/node/DataFile.js'; +export * from './adapters/node/JSONFile.js'; +export * from './adapters/node/TextFile.js'; +export * from './presets/node.js'; diff --git a/node_modules/lowdb/lib/node.js b/node_modules/lowdb/lib/node.js new file mode 100644 index 0000000..81c5f4a --- /dev/null +++ b/node_modules/lowdb/lib/node.js @@ -0,0 +1,4 @@ +export * from './adapters/node/DataFile.js'; +export * from './adapters/node/JSONFile.js'; +export * from './adapters/node/TextFile.js'; +export * from './presets/node.js'; diff --git a/node_modules/lowdb/lib/presets/browser.d.ts b/node_modules/lowdb/lib/presets/browser.d.ts new file mode 100644 index 0000000..84a96d8 --- /dev/null +++ b/node_modules/lowdb/lib/presets/browser.d.ts @@ -0,0 +1,3 @@ +import { LowSync } from '../index.js'; +export declare function LocalStoragePreset(key: string, defaultData: Data): LowSync; +export declare function SessionStoragePreset(key: string, defaultData: Data): LowSync; diff --git a/node_modules/lowdb/lib/presets/browser.js b/node_modules/lowdb/lib/presets/browser.js new file mode 100644 index 0000000..60226a4 --- /dev/null +++ b/node_modules/lowdb/lib/presets/browser.js @@ -0,0 +1,15 @@ +import { LocalStorage } from '../adapters/browser/LocalStorage.js'; +import { SessionStorage } from '../adapters/browser/SessionStorage.js'; +import { LowSync } from '../index.js'; +export function LocalStoragePreset(key, defaultData) { + const adapter = new LocalStorage(key); + const db = new LowSync(adapter, defaultData); + db.read(); + return db; +} +export function SessionStoragePreset(key, defaultData) { + const adapter = new SessionStorage(key); + const db = new LowSync(adapter, defaultData); + db.read(); + return db; +} diff --git a/node_modules/lowdb/lib/presets/node.d.ts b/node_modules/lowdb/lib/presets/node.d.ts new file mode 100644 index 0000000..5315ae0 --- /dev/null +++ b/node_modules/lowdb/lib/presets/node.d.ts @@ -0,0 +1,5 @@ +/// +import { PathLike } from 'node:fs'; +import { Low, LowSync } from '../core/Low.js'; +export declare function JSONFilePreset(filename: PathLike, defaultData: Data): Promise>; +export declare function JSONFileSyncPreset(filename: PathLike, defaultData: Data): LowSync; diff --git a/node_modules/lowdb/lib/presets/node.js b/node_modules/lowdb/lib/presets/node.js new file mode 100644 index 0000000..ee261db --- /dev/null +++ b/node_modules/lowdb/lib/presets/node.js @@ -0,0 +1,19 @@ +import { Memory, MemorySync } from '../adapters/Memory.js'; +import { JSONFile, JSONFileSync } from '../adapters/node/JSONFile.js'; +import { Low, LowSync } from '../core/Low.js'; +export async function JSONFilePreset(filename, defaultData) { + const adapter = process.env.NODE_ENV === 'test' + ? new Memory() + : new JSONFile(filename); + const db = new Low(adapter, defaultData); + await db.read(); + return db; +} +export function JSONFileSyncPreset(filename, defaultData) { + const adapter = process.env.NODE_ENV === 'test' + ? new MemorySync() + : new JSONFileSync(filename); + const db = new LowSync(adapter, defaultData); + db.read(); + return db; +} diff --git a/node_modules/lowdb/package.json b/node_modules/lowdb/package.json new file mode 100644 index 0000000..baffdfd --- /dev/null +++ b/node_modules/lowdb/package.json @@ -0,0 +1,85 @@ +{ + "name": "lowdb", + "version": "7.0.1", + "description": "Tiny local JSON database for Node, Electron and the browser", + "keywords": [ + "database", + "db", + "electron", + "embed", + "embedded", + "flat", + "JSON", + "local", + "localStorage", + "sessionStorage", + "browser", + "esm" + ], + "homepage": "https://github.com/typicode/lowdb#readme", + "bugs": { + "url": "https://github.com/typicode/lowdb/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/typicode/lowdb.git" + }, + "funding": "https://github.com/sponsors/typicode", + "license": "MIT", + "author": "Typicode ", + "type": "module", + "exports": { + ".": "./lib/index.js", + "./node": "./lib/node.js", + "./browser": "./lib/browser.js" + }, + "types": "./lib", + "typesVersions": { + "*": { + "node": [ + "lib/node.d.ts" + ], + "browser": [ + "lib/browser.d.ts" + ] + } + }, + "files": [ + "lib", + "!lib/examples/**/*", + "!lib/**/*.test.*" + ], + "scripts": { + "test": "node --import tsx/esm --test src/**/*.test.ts src/**/**/*.test.ts", + "lint": "eslint src --ext .ts --ignore-path .gitignore", + "build": "del-cli lib && tsc", + "prepublishOnly": "npm run build", + "postversion": "git push --follow-tags && npm publish", + "prepare": "husky install" + }, + "dependencies": { + "steno": "^4.0.2" + }, + "devDependencies": { + "@commitlint/cli": "^18.4.3", + "@commitlint/config-conventional": "^18.4.3", + "@commitlint/prompt-cli": "^18.4.3", + "@sindresorhus/tsconfig": "^5.0.0", + "@types/express": "^4.17.21", + "@types/lodash": "^4.14.202", + "@types/node": "^20.10.5", + "@typicode/eslint-config": "^1.2.0", + "del-cli": "^5.1.0", + "eslint": "^8.56.0", + "express-async-handler": "^1.2.0", + "husky": "^8.0.3", + "lodash": "^4.17.21", + "tempy": "^3.1.0", + "ts-node": "^10.9.2", + "tsx": "^4.7.0", + "typescript": "^5.3.3" + }, + "engines": { + "node": ">=18" + } +} diff --git a/node_modules/milliparsec/LICENSE b/node_modules/milliparsec/LICENSE new file mode 100644 index 0000000..2ef86be --- /dev/null +++ b/node_modules/milliparsec/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 v 1 r t l + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/milliparsec/README.md b/node_modules/milliparsec/README.md new file mode 100644 index 0000000..8932d5b --- /dev/null +++ b/node_modules/milliparsec/README.md @@ -0,0 +1,113 @@ +
+


+ +

+ +![Vulnerabilities][vulns-badge-url] +[![Version][v-badge-url]][npm-url] [![Coverage][cov-img]][cov-url] [![Github actions][gh-actions-img]][github-actions] [![Downloads][dl-badge-url]][npm-url] + +
+
+ +Tiniest body parser in the universe. Built for modern Node.js. + +Check out [deno-libs/parsec](https://github.com/deno-libs/parsec) for Deno port. + +## Features + +- ⏩ built with `async` / `await` +- 🛠 JSON / raw / urlencoded data support +- 📦 tiny package size (728B) +- 🔥 no dependencies +- ⚡ [tinyhttp](https://github.com/talentlessguy/tinyhttp) and Express support + +## Install + +```sh +# pnpm +pnpm i milliparsec + +# yarn +yarn add milliparsec + +# npm +npm i milliparsec +``` + +## Usage + +### Basic example + +Use a middleware inside a server: + +```js +import { createServer } from 'http' +import { json } from 'milliparsec' + +const server = createServer(async (req: ReqWithBody, res) => { + await json()(req, res, (err) => void err && console.log(err)) + + res.setHeader('Content-Type', 'application/json') + + res.end(JSON.stringify(req.body)) +}) +``` + +### Web frameworks integration + +#### tinyhttp + +```ts +import { App } from '@tinyhttp/app' +import { urlencoded } from 'milliparsec' + +new App() + .use(urlencoded()) + .post('/', (req, res) => void res.send(req.body)) + .listen(3000, () => console.log(`Started on http://localhost:3000`)) +``` + +## API + +### `raw(req, res, cb)` + +Minimal body parsing without any formatting. + +### `text(req, res, cb)` + +Converts request body to string. + +### `urlencoded(req, res, cb)` + +Parses request body using `new URLSearchParams`. + +### `json(req, res, cb)` + +Parses request body using `JSON.parse`. + +### `custom(fn)(req, res, cb)` + +Custom function for `parsec`. + +```js +// curl -d "this text must be uppercased" localhost +await custom( + req, + (d) => d.toUpperCase(), + (err) => {} +) +res.end(req.body) // "THIS TEXT MUST BE UPPERCASED" +``` + +### What is "parsec"? + +The parsec is a unit of length used to measure large distances to astronomical objects outside the Solar System. + +[vulns-badge-url]: https://img.shields.io/snyk/vulnerabilities/npm/milliparsec.svg?style=for-the-badge&color=25608B&label=vulns +[v-badge-url]: https://img.shields.io/npm/v/milliparsec.svg?style=for-the-badge&color=25608B&logo=npm&label= +[npm-url]: https://www.npmjs.com/package/milliparsec +[dl-badge-url]: https://img.shields.io/npm/dt/milliparsec?style=for-the-badge&color=25608B +[github-actions]: https://github.com/talentlessguy/milliparsec/actions +[gh-actions-img]: https://img.shields.io/github/workflow/status/talentlessguy/milliparsec/CI?style=for-the-badge&color=25608B&label=&logo=github +[cov-img]: https://img.shields.io/coveralls/github/tinyhttp/milliparsec?style=for-the-badge&color=25608B +[cov-url]: https://coveralls.io/github/tinyhttp/milliparsec diff --git a/node_modules/milliparsec/dist/index.d.ts b/node_modules/milliparsec/dist/index.d.ts new file mode 100644 index 0000000..cabd61a --- /dev/null +++ b/node_modules/milliparsec/dist/index.d.ts @@ -0,0 +1,16 @@ +/// +/// +import { ServerResponse as Response, IncomingMessage } from 'http'; +import { EventEmitter } from 'events'; +type NextFunction = (err?: any) => void; +export type ReqWithBody = IncomingMessage & { + body?: T; +} & EventEmitter; +export declare const hasBody: (method: string) => boolean; +export declare const p: (fn: (body: any) => any) => (req: ReqWithBody, _res: Response, next: (err?: any) => void) => Promise; +declare const custom: (fn: (body: any) => any) => (req: ReqWithBody, _res: Response, next: NextFunction) => Promise; +declare const json: () => (req: ReqWithBody, res: Response, next: NextFunction) => Promise; +declare const raw: () => (req: ReqWithBody, _res: Response, next: NextFunction) => Promise; +declare const text: () => (req: ReqWithBody, _res: Response, next: NextFunction) => Promise; +declare const urlencoded: () => (req: ReqWithBody, res: Response, next: NextFunction) => Promise; +export { custom, json, raw, text, urlencoded }; diff --git a/node_modules/milliparsec/dist/index.js b/node_modules/milliparsec/dist/index.js new file mode 100644 index 0000000..df1de07 --- /dev/null +++ b/node_modules/milliparsec/dist/index.js @@ -0,0 +1,55 @@ +const hasBody = (method) => ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method); +// Main function +const p = (fn) => async (req, _res, next) => { + try { + let body = ''; + for await (const chunk of req) + body += chunk; + return fn(body); + } + catch (e) { + next(e); + } +}; +// JSON, raw, FormData +const custom = (fn) => async (req, _res, next) => { + req.body = await p(fn)(req, undefined, next); + next(); +}; +const json = () => async (req, res, next) => { + if (hasBody(req.method)) { + req.body = await p((x) => (x ? JSON.parse(x.toString()) : {}))(req, res, next); + next(); + } + else + next(); +}; +const raw = () => async (req, _res, next) => { + if (hasBody(req.method)) { + req.body = await p((x) => x)(req, _res, next); + next(); + } + else + next(); +}; +const text = () => async (req, _res, next) => { + if (hasBody(req.method)) { + req.body = await p((x) => x.toString())(req, _res, next); + next(); + } + else + next(); +}; +const urlencoded = () => async (req, res, next) => { + if (hasBody(req.method)) { + req.body = await p((x) => { + const urlSearchParam = new URLSearchParams(x.toString()); + return Object.fromEntries(urlSearchParam.entries()); + })(req, res, next); + next(); + } + else + next(); +}; + +export { custom, hasBody, json, p, raw, text, urlencoded }; diff --git a/node_modules/milliparsec/package.json b/node_modules/milliparsec/package.json new file mode 100644 index 0000000..18f68e8 --- /dev/null +++ b/node_modules/milliparsec/package.json @@ -0,0 +1,41 @@ +{ + "name": "milliparsec", + "version": "2.3.0", + "description": "tiniest body parser in the universe", + "repository": "https://github.com/talentlessguy/parsec.git", + "author": "talentlessguy ", + "license": "MIT", + "types": "./dist/index.d.ts", + "type": "module", + "keywords": [ + "body-parser", + "express", + "http", + "body-parsing" + ], + "engines": { + "node": ">=12.4" + }, + "exports": "./dist/index.js", + "devDependencies": { + "@rollup/plugin-typescript": "^11.1.0", + "@tinyhttp/app": "^2.0.31", + "@types/node": "^18.16.3", + "c8": "7.13.0", + "rollup": "^3.21.4", + "supertest-fetch": "^1.5.0", + "tslib": "^2.5.0", + "tsm": "^2.3.0", + "typescript": "^5.0.4", + "uvu": "^0.5.6" + }, + "files": [ + "dist" + ], + "scripts": { + "test": "uvu -r tsm", + "test:coverage": "c8 --include=src pnpm test", + "test:report": "c8 report --reporter=text-lcov > coverage.lcov", + "build": "rollup -c" + } +} \ No newline at end of file diff --git a/node_modules/mime/LICENSE b/node_modules/mime/LICENSE new file mode 100644 index 0000000..8cd5a84 --- /dev/null +++ b/node_modules/mime/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Robert Kieffer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/node_modules/mime/README.md b/node_modules/mime/README.md new file mode 100644 index 0000000..540e742 --- /dev/null +++ b/node_modules/mime/README.md @@ -0,0 +1,143 @@ + +# Mime + +[![NPM downloads](https://img.shields.io/npm/dm/mime)](https://www.npmjs.com/package/mime) +[![Mime CI](https://github.com/broofa/mime/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/broofa/mime/actions/workflows/ci.yml?query=branch%3Amain) + +An API for MIME type information. + +- All `mime-db` types +- Compact and dependency-free [![mime's badge](https://deno.bundlejs.com/?q=mime&badge)](https://bundlejs.com/?q=mime) +- Full TS support + + +> [!Note] +> `mime@4` is now `latest`. If you're upgrading from `mime@3`, note the following: +> * `mime@4` is API-compatible with `mime@3`, with ~~one~~ two exceptions: +> * Direct imports of `mime` properties [no longer supported](https://github.com/broofa/mime/issues/295) +> * `mime.define()` cannot be called on the default `mime` object +> * ESM module support is required. [ESM Module FAQ](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c). +> * Requires an [ES2020](https://caniuse.com/?search=es2020) or newer runtime +> * Built-in Typescript types (`@types/mime` no longer needed) + +## Installation + +```bash +npm install mime +``` + +## Quick Start + +For the full version (800+ MIME types, 1,000+ extensions): + +```javascript +import mime from 'mime'; + +mime.getType('txt'); // ⇨ 'text/plain' +mime.getExtension('text/plain'); // ⇨ 'txt' +``` + +### Lite Version [![mime/lite's badge](https://deno.bundlejs.com/?q=mime/lite&badge)](https://bundlejs.com/?q=mime/lite) + +`mime/lite` is a drop-in `mime` replacement, stripped of unofficial ("`prs.*`", "`x-*`", "`vnd.*`") types: + +```javascript +import mime from 'mime/lite'; +``` + +## API + +### `mime.getType(pathOrExtension)` + +Get mime type for the given file path or extension. E.g. + +```javascript +mime.getType('js'); // ⇨ 'application/javascript' +mime.getType('json'); // ⇨ 'application/json' + +mime.getType('txt'); // ⇨ 'text/plain' +mime.getType('dir/text.txt'); // ⇨ 'text/plain' +mime.getType('dir\\text.txt'); // ⇨ 'text/plain' +mime.getType('.text.txt'); // ⇨ 'text/plain' +mime.getType('.txt'); // ⇨ 'text/plain' +``` + +`null` is returned in cases where an extension is not detected or recognized + +```javascript +mime.getType('foo/txt'); // ⇨ null +mime.getType('bogus_type'); // ⇨ null +``` + +### `mime.getExtension(type)` + +Get file extension for the given mime type. Charset options (often included in Content-Type headers) are ignored. + +```javascript +mime.getExtension('text/plain'); // ⇨ 'txt' +mime.getExtension('application/json'); // ⇨ 'json' +mime.getExtension('text/html; charset=utf8'); // ⇨ 'html' +``` + +### `mime.getAllExtensions(type)` + +> [!Note] +> New in `mime@4` + +Get all file extensions for the given mime type. + +```javascript --run default +mime.getAllExtensions('image/jpeg'); // ⇨ Set(3) { 'jpeg', 'jpg', 'jpe' } +``` + +## Custom `Mime` instances + +The default `mime` objects are immutable. Custom, mutable versions can be created as follows... +### new Mime(type map [, type map, ...]) + +Create a new, custom mime instance. For example, to create a mutable version of the default `mime` instance: + +```javascript +import { Mime } from 'mime/lite'; + +import standardTypes from 'mime/types/standard.js'; +import otherTypes from 'mime/types/other.js'; + +const mime = new Mime(standardTypes, otherTypes); +``` + +Each argument is passed to the `define()` method, below. For example `new Mime(standardTypes, otherTypes)` is synonomous with `new Mime().define(standardTypes).define(otherTypes)` + +### `mime.define(type map [, force = false])` + +> [!Note] +> Only available on custom `Mime` instances + +Define MIME type -> extensions. + +Attempting to map a type to an already-defined extension will `throw` unless the `force` argument is set to `true`. + +```javascript +mime.define({'text/x-abc': ['abc', 'abcd']}); + +mime.getType('abcd'); // ⇨ 'text/x-abc' +mime.getExtension('text/x-abc') // ⇨ 'abc' +``` + +## Command Line + +### Extension -> type + +```bash +$ mime scripts/jquery.js +application/javascript +``` + +### Type -> extension + +```bash +$ mime -r image/jpeg +jpeg +``` diff --git a/node_modules/mime/bin/cli.js b/node_modules/mime/bin/cli.js new file mode 100755 index 0000000..88227a1 --- /dev/null +++ b/node_modules/mime/bin/cli.js @@ -0,0 +1,6 @@ +#!/usr/bin/env node + +// Thin wrapper around mime +import mime_cli from '../dist/src/mime_cli.js'; + +await mime_cli(); diff --git a/node_modules/mime/dist/src/Mime.d.ts b/node_modules/mime/dist/src/Mime.d.ts new file mode 100644 index 0000000..b1b9e2f --- /dev/null +++ b/node_modules/mime/dist/src/Mime.d.ts @@ -0,0 +1,17 @@ +type TypeMap = { + [key: string]: string[]; +}; +export default class Mime { + #private; + constructor(...args: TypeMap[]); + define(typeMap: TypeMap, force?: boolean): this; + getType(path: string): string | null; + getExtension(type: string): string | null; + getAllExtensions(type: string): Set | null; + _freeze(): this; + _getTestState(): { + types: Map; + extensions: Map; + }; +} +export {}; diff --git a/node_modules/mime/dist/src/Mime.js b/node_modules/mime/dist/src/Mime.js new file mode 100644 index 0000000..1ec9223 --- /dev/null +++ b/node_modules/mime/dist/src/Mime.js @@ -0,0 +1,85 @@ +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _Mime_extensionToType, _Mime_typeToExtension, _Mime_typeToExtensions; +class Mime { + constructor(...args) { + _Mime_extensionToType.set(this, new Map()); + _Mime_typeToExtension.set(this, new Map()); + _Mime_typeToExtensions.set(this, new Map()); + for (const arg of args) { + this.define(arg); + } + } + define(typeMap, force = false) { + for (let [type, extensions] of Object.entries(typeMap)) { + type = type.toLowerCase(); + extensions = extensions.map((ext) => ext.toLowerCase()); + if (!__classPrivateFieldGet(this, _Mime_typeToExtensions, "f").has(type)) { + __classPrivateFieldGet(this, _Mime_typeToExtensions, "f").set(type, new Set()); + } + const allExtensions = __classPrivateFieldGet(this, _Mime_typeToExtensions, "f").get(type); + let first = true; + for (let extension of extensions) { + const starred = extension.startsWith('*'); + extension = starred ? extension.slice(1) : extension; + allExtensions?.add(extension); + if (first) { + __classPrivateFieldGet(this, _Mime_typeToExtension, "f").set(type, extension); + } + first = false; + if (starred) + continue; + const currentType = __classPrivateFieldGet(this, _Mime_extensionToType, "f").get(extension); + if (currentType && currentType != type && !force) { + throw new Error(`"${type} -> ${extension}" conflicts with "${currentType} -> ${extension}". Pass \`force=true\` to override this definition.`); + } + __classPrivateFieldGet(this, _Mime_extensionToType, "f").set(extension, type); + } + } + return this; + } + getType(path) { + if (typeof path !== 'string') + return null; + const last = path.replace(/^.*[/\\]/, '').toLowerCase(); + const ext = last.replace(/^.*\./, '').toLowerCase(); + const hasPath = last.length < path.length; + const hasDot = ext.length < last.length - 1; + if (!hasDot && hasPath) + return null; + return __classPrivateFieldGet(this, _Mime_extensionToType, "f").get(ext) ?? null; + } + getExtension(type) { + if (typeof type !== 'string') + return null; + type = type?.split?.(';')[0]; + return ((type && __classPrivateFieldGet(this, _Mime_typeToExtension, "f").get(type.trim().toLowerCase())) ?? null); + } + getAllExtensions(type) { + if (typeof type !== 'string') + return null; + return __classPrivateFieldGet(this, _Mime_typeToExtensions, "f").get(type.toLowerCase()) ?? null; + } + _freeze() { + this.define = () => { + throw new Error('define() not allowed for built-in Mime objects. See https://github.com/broofa/mime/blob/main/README.md#custom-mime-instances'); + }; + Object.freeze(this); + for (const extensions of __classPrivateFieldGet(this, _Mime_typeToExtensions, "f").values()) { + Object.freeze(extensions); + } + return this; + } + _getTestState() { + return { + types: __classPrivateFieldGet(this, _Mime_extensionToType, "f"), + extensions: __classPrivateFieldGet(this, _Mime_typeToExtension, "f"), + }; + } +} +_Mime_extensionToType = new WeakMap(), _Mime_typeToExtension = new WeakMap(), _Mime_typeToExtensions = new WeakMap(); +export default Mime; +//# sourceMappingURL=Mime.js.map \ No newline at end of file diff --git a/node_modules/mime/dist/src/Mime.js.map b/node_modules/mime/dist/src/Mime.js.map new file mode 100644 index 0000000..2066177 --- /dev/null +++ b/node_modules/mime/dist/src/Mime.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Mime.js","sourceRoot":"","sources":["../../src/Mime.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/mime/dist/src/index.d.ts b/node_modules/mime/dist/src/index.d.ts new file mode 100644 index 0000000..8bb12ed --- /dev/null +++ b/node_modules/mime/dist/src/index.d.ts @@ -0,0 +1,4 @@ +import Mime from './Mime.js'; +export { default as Mime } from './Mime.js'; +declare const _default: Mime; +export default _default; diff --git a/node_modules/mime/dist/src/index.js b/node_modules/mime/dist/src/index.js new file mode 100644 index 0000000..77702b8 --- /dev/null +++ b/node_modules/mime/dist/src/index.js @@ -0,0 +1,6 @@ +import otherTypes from '../types/other.js'; +import standardTypes from '../types/standard.js'; +import Mime from './Mime.js'; +export { default as Mime } from './Mime.js'; +export default new Mime(standardTypes, otherTypes)._freeze(); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/mime/dist/src/index.js.map b/node_modules/mime/dist/src/index.js.map new file mode 100644 index 0000000..d6f5906 --- /dev/null +++ b/node_modules/mime/dist/src/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAC3C,OAAO,aAAa,MAAM,sBAAsB,CAAC;AACjD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,WAAW,CAAC;AAE5C,eAAe,IAAI,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC"} \ No newline at end of file diff --git a/node_modules/mime/dist/src/index_lite.d.ts b/node_modules/mime/dist/src/index_lite.d.ts new file mode 100644 index 0000000..8bb12ed --- /dev/null +++ b/node_modules/mime/dist/src/index_lite.d.ts @@ -0,0 +1,4 @@ +import Mime from './Mime.js'; +export { default as Mime } from './Mime.js'; +declare const _default: Mime; +export default _default; diff --git a/node_modules/mime/dist/src/index_lite.js b/node_modules/mime/dist/src/index_lite.js new file mode 100644 index 0000000..fd86b44 --- /dev/null +++ b/node_modules/mime/dist/src/index_lite.js @@ -0,0 +1,5 @@ +import standardTypes from '../types/standard.js'; +import Mime from './Mime.js'; +export { default as Mime } from './Mime.js'; +export default new Mime(standardTypes)._freeze(); +//# sourceMappingURL=index_lite.js.map \ No newline at end of file diff --git a/node_modules/mime/dist/src/index_lite.js.map b/node_modules/mime/dist/src/index_lite.js.map new file mode 100644 index 0000000..cf1e26e --- /dev/null +++ b/node_modules/mime/dist/src/index_lite.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index_lite.js","sourceRoot":"","sources":["../../src/index_lite.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,sBAAsB,CAAC;AACjD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,WAAW,CAAC;AAE5C,eAAe,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAC"} \ No newline at end of file diff --git a/node_modules/mime/dist/src/mime_cli.d.ts b/node_modules/mime/dist/src/mime_cli.d.ts new file mode 100644 index 0000000..51c22ed --- /dev/null +++ b/node_modules/mime/dist/src/mime_cli.d.ts @@ -0,0 +1,2 @@ +#!/usr/bin/env node +export default function (): Promise; diff --git a/node_modules/mime/dist/src/mime_cli.js b/node_modules/mime/dist/src/mime_cli.js new file mode 100644 index 0000000..6ffd25a --- /dev/null +++ b/node_modules/mime/dist/src/mime_cli.js @@ -0,0 +1,67 @@ +#!/usr/bin/env node +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import mime from './index.js'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +export default async function () { + process.title = 'mime'; + const json = await fs.readFile(path.join(__dirname, '../../package.json'), 'utf-8'); + const pkg = JSON.parse(json); + const args = process.argv.splice(2); + if (args.includes('--version') || + args.includes('-v') || + args.includes('--v')) { + console.log(pkg.version); + process.exit(0); + } + else if (args.includes('--name') || + args.includes('-n') || + args.includes('--n')) { + console.log(pkg.name); + process.exit(0); + } + else if (args.includes('--help') || + args.includes('-h') || + args.includes('--h')) { + console.log(pkg.name + ' - ' + pkg.description + '\n'); + console.log(`Usage: + + mime [flags] [path_or_extension] + + Flags: + --help, -h Show this message + --version, -v Display the version + --name, -n Print the name of the program + --reverse, -r Print the extension of the mime type + + Note: the command will exit after it executes if a command is specified + The path_or_extension is the path to the file or the extension of the file. + + Examples: + mime --help + mime --version + mime --name + mime -v + mime --reverse application/text + mime src/log.js + mime new.py + mime foo.sh + `); + process.exit(0); + } + else if (args.includes('--reverse') || args.includes('-r')) { + const mimeType = args[args.length - 1]; + const extension = mime.getExtension(mimeType); + if (!extension) + process.exit(1); + process.stdout.write(extension + '\n'); + process.exit(0); + } + const file = args[0]; + const type = mime.getType(file); + if (!type) + process.exit(1); + process.stdout.write(type + '\n'); +} +//# sourceMappingURL=mime_cli.js.map \ No newline at end of file diff --git a/node_modules/mime/dist/src/mime_cli.js.map b/node_modules/mime/dist/src/mime_cli.js.map new file mode 100644 index 0000000..cbd7cbd --- /dev/null +++ b/node_modules/mime/dist/src/mime_cli.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mime_cli.js","sourceRoot":"","sources":["../../src/mime_cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,YAAY,CAAC;AAE9B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,MAAM,CAAC,OAAO,CAAC,KAAK;IAClB,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC;IAMvB,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC5B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,EAC1C,OAAO,CACR,CAAC;IACF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE7B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAEpC,IACE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACnB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EACpB;QACA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;SAAM,IACL,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACnB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EACpB;QACA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;SAAM,IACL,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACnB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EACpB;QACA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,GAAG,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;GAsBb,CAAC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;SAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE9C,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEhC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AACpC,CAAC"} \ No newline at end of file diff --git a/node_modules/mime/dist/types/other.d.ts b/node_modules/mime/dist/types/other.d.ts new file mode 100644 index 0000000..12f015a --- /dev/null +++ b/node_modules/mime/dist/types/other.d.ts @@ -0,0 +1,4 @@ +declare const types: { + [key: string]: string[]; +}; +export default types; diff --git a/node_modules/mime/dist/types/other.js b/node_modules/mime/dist/types/other.js new file mode 100644 index 0000000..0207b28 --- /dev/null +++ b/node_modules/mime/dist/types/other.js @@ -0,0 +1,4 @@ +const types = { "application/prs.cww": ["cww"], "application/prs.xsf+xml": ["xsf"], "application/vnd.1000minds.decision-model+xml": ["1km"], "application/vnd.3gpp.pic-bw-large": ["plb"], "application/vnd.3gpp.pic-bw-small": ["psb"], "application/vnd.3gpp.pic-bw-var": ["pvb"], "application/vnd.3gpp2.tcap": ["tcap"], "application/vnd.3m.post-it-notes": ["pwn"], "application/vnd.accpac.simply.aso": ["aso"], "application/vnd.accpac.simply.imp": ["imp"], "application/vnd.acucobol": ["acu"], "application/vnd.acucorp": ["atc", "acutc"], "application/vnd.adobe.air-application-installer-package+zip": ["air"], "application/vnd.adobe.formscentral.fcdt": ["fcdt"], "application/vnd.adobe.fxp": ["fxp", "fxpl"], "application/vnd.adobe.xdp+xml": ["xdp"], "application/vnd.adobe.xfdf": ["*xfdf"], "application/vnd.age": ["age"], "application/vnd.ahead.space": ["ahead"], "application/vnd.airzip.filesecure.azf": ["azf"], "application/vnd.airzip.filesecure.azs": ["azs"], "application/vnd.amazon.ebook": ["azw"], "application/vnd.americandynamics.acc": ["acc"], "application/vnd.amiga.ami": ["ami"], "application/vnd.android.package-archive": ["apk"], "application/vnd.anser-web-certificate-issue-initiation": ["cii"], "application/vnd.anser-web-funds-transfer-initiation": ["fti"], "application/vnd.antix.game-component": ["atx"], "application/vnd.apple.installer+xml": ["mpkg"], "application/vnd.apple.keynote": ["key"], "application/vnd.apple.mpegurl": ["m3u8"], "application/vnd.apple.numbers": ["numbers"], "application/vnd.apple.pages": ["pages"], "application/vnd.apple.pkpass": ["pkpass"], "application/vnd.aristanetworks.swi": ["swi"], "application/vnd.astraea-software.iota": ["iota"], "application/vnd.audiograph": ["aep"], "application/vnd.balsamiq.bmml+xml": ["bmml"], "application/vnd.blueice.multipass": ["mpm"], "application/vnd.bmi": ["bmi"], "application/vnd.businessobjects": ["rep"], "application/vnd.chemdraw+xml": ["cdxml"], "application/vnd.chipnuts.karaoke-mmd": ["mmd"], "application/vnd.cinderella": ["cdy"], "application/vnd.citationstyles.style+xml": ["csl"], "application/vnd.claymore": ["cla"], "application/vnd.cloanto.rp9": ["rp9"], "application/vnd.clonk.c4group": ["c4g", "c4d", "c4f", "c4p", "c4u"], "application/vnd.cluetrust.cartomobile-config": ["c11amc"], "application/vnd.cluetrust.cartomobile-config-pkg": ["c11amz"], "application/vnd.commonspace": ["csp"], "application/vnd.contact.cmsg": ["cdbcmsg"], "application/vnd.cosmocaller": ["cmc"], "application/vnd.crick.clicker": ["clkx"], "application/vnd.crick.clicker.keyboard": ["clkk"], "application/vnd.crick.clicker.palette": ["clkp"], "application/vnd.crick.clicker.template": ["clkt"], "application/vnd.crick.clicker.wordbank": ["clkw"], "application/vnd.criticaltools.wbs+xml": ["wbs"], "application/vnd.ctc-posml": ["pml"], "application/vnd.cups-ppd": ["ppd"], "application/vnd.curl.car": ["car"], "application/vnd.curl.pcurl": ["pcurl"], "application/vnd.dart": ["dart"], "application/vnd.data-vision.rdz": ["rdz"], "application/vnd.dbf": ["dbf"], "application/vnd.dece.data": ["uvf", "uvvf", "uvd", "uvvd"], "application/vnd.dece.ttml+xml": ["uvt", "uvvt"], "application/vnd.dece.unspecified": ["uvx", "uvvx"], "application/vnd.dece.zip": ["uvz", "uvvz"], "application/vnd.denovo.fcselayout-link": ["fe_launch"], "application/vnd.dna": ["dna"], "application/vnd.dolby.mlp": ["mlp"], "application/vnd.dpgraph": ["dpg"], "application/vnd.dreamfactory": ["dfac"], "application/vnd.ds-keypoint": ["kpxx"], "application/vnd.dvb.ait": ["ait"], "application/vnd.dvb.service": ["svc"], "application/vnd.dynageo": ["geo"], "application/vnd.ecowin.chart": ["mag"], "application/vnd.enliven": ["nml"], "application/vnd.epson.esf": ["esf"], "application/vnd.epson.msf": ["msf"], "application/vnd.epson.quickanime": ["qam"], "application/vnd.epson.salt": ["slt"], "application/vnd.epson.ssf": ["ssf"], "application/vnd.eszigno3+xml": ["es3", "et3"], "application/vnd.ezpix-album": ["ez2"], "application/vnd.ezpix-package": ["ez3"], "application/vnd.fdf": ["*fdf"], "application/vnd.fdsn.mseed": ["mseed"], "application/vnd.fdsn.seed": ["seed", "dataless"], "application/vnd.flographit": ["gph"], "application/vnd.fluxtime.clip": ["ftc"], "application/vnd.framemaker": ["fm", "frame", "maker", "book"], "application/vnd.frogans.fnc": ["fnc"], "application/vnd.frogans.ltf": ["ltf"], "application/vnd.fsc.weblaunch": ["fsc"], "application/vnd.fujitsu.oasys": ["oas"], "application/vnd.fujitsu.oasys2": ["oa2"], "application/vnd.fujitsu.oasys3": ["oa3"], "application/vnd.fujitsu.oasysgp": ["fg5"], "application/vnd.fujitsu.oasysprs": ["bh2"], "application/vnd.fujixerox.ddd": ["ddd"], "application/vnd.fujixerox.docuworks": ["xdw"], "application/vnd.fujixerox.docuworks.binder": ["xbd"], "application/vnd.fuzzysheet": ["fzs"], "application/vnd.genomatix.tuxedo": ["txd"], "application/vnd.geogebra.file": ["ggb"], "application/vnd.geogebra.tool": ["ggt"], "application/vnd.geometry-explorer": ["gex", "gre"], "application/vnd.geonext": ["gxt"], "application/vnd.geoplan": ["g2w"], "application/vnd.geospace": ["g3w"], "application/vnd.gmx": ["gmx"], "application/vnd.google-apps.document": ["gdoc"], "application/vnd.google-apps.presentation": ["gslides"], "application/vnd.google-apps.spreadsheet": ["gsheet"], "application/vnd.google-earth.kml+xml": ["kml"], "application/vnd.google-earth.kmz": ["kmz"], "application/vnd.grafeq": ["gqf", "gqs"], "application/vnd.groove-account": ["gac"], "application/vnd.groove-help": ["ghf"], "application/vnd.groove-identity-message": ["gim"], "application/vnd.groove-injector": ["grv"], "application/vnd.groove-tool-message": ["gtm"], "application/vnd.groove-tool-template": ["tpl"], "application/vnd.groove-vcard": ["vcg"], "application/vnd.hal+xml": ["hal"], "application/vnd.handheld-entertainment+xml": ["zmm"], "application/vnd.hbci": ["hbci"], "application/vnd.hhe.lesson-player": ["les"], "application/vnd.hp-hpgl": ["hpgl"], "application/vnd.hp-hpid": ["hpid"], "application/vnd.hp-hps": ["hps"], "application/vnd.hp-jlyt": ["jlt"], "application/vnd.hp-pcl": ["pcl"], "application/vnd.hp-pclxl": ["pclxl"], "application/vnd.hydrostatix.sof-data": ["sfd-hdstx"], "application/vnd.ibm.minipay": ["mpy"], "application/vnd.ibm.modcap": ["afp", "listafp", "list3820"], "application/vnd.ibm.rights-management": ["irm"], "application/vnd.ibm.secure-container": ["sc"], "application/vnd.iccprofile": ["icc", "icm"], "application/vnd.igloader": ["igl"], "application/vnd.immervision-ivp": ["ivp"], "application/vnd.immervision-ivu": ["ivu"], "application/vnd.insors.igm": ["igm"], "application/vnd.intercon.formnet": ["xpw", "xpx"], "application/vnd.intergeo": ["i2g"], "application/vnd.intu.qbo": ["qbo"], "application/vnd.intu.qfx": ["qfx"], "application/vnd.ipunplugged.rcprofile": ["rcprofile"], "application/vnd.irepository.package+xml": ["irp"], "application/vnd.is-xpr": ["xpr"], "application/vnd.isac.fcs": ["fcs"], "application/vnd.jam": ["jam"], "application/vnd.jcp.javame.midlet-rms": ["rms"], "application/vnd.jisp": ["jisp"], "application/vnd.joost.joda-archive": ["joda"], "application/vnd.kahootz": ["ktz", "ktr"], "application/vnd.kde.karbon": ["karbon"], "application/vnd.kde.kchart": ["chrt"], "application/vnd.kde.kformula": ["kfo"], "application/vnd.kde.kivio": ["flw"], "application/vnd.kde.kontour": ["kon"], "application/vnd.kde.kpresenter": ["kpr", "kpt"], "application/vnd.kde.kspread": ["ksp"], "application/vnd.kde.kword": ["kwd", "kwt"], "application/vnd.kenameaapp": ["htke"], "application/vnd.kidspiration": ["kia"], "application/vnd.kinar": ["kne", "knp"], "application/vnd.koan": ["skp", "skd", "skt", "skm"], "application/vnd.kodak-descriptor": ["sse"], "application/vnd.las.las+xml": ["lasxml"], "application/vnd.llamagraphics.life-balance.desktop": ["lbd"], "application/vnd.llamagraphics.life-balance.exchange+xml": ["lbe"], "application/vnd.lotus-1-2-3": ["123"], "application/vnd.lotus-approach": ["apr"], "application/vnd.lotus-freelance": ["pre"], "application/vnd.lotus-notes": ["nsf"], "application/vnd.lotus-organizer": ["org"], "application/vnd.lotus-screencam": ["scm"], "application/vnd.lotus-wordpro": ["lwp"], "application/vnd.macports.portpkg": ["portpkg"], "application/vnd.mapbox-vector-tile": ["mvt"], "application/vnd.mcd": ["mcd"], "application/vnd.medcalcdata": ["mc1"], "application/vnd.mediastation.cdkey": ["cdkey"], "application/vnd.mfer": ["mwf"], "application/vnd.mfmp": ["mfm"], "application/vnd.micrografx.flo": ["flo"], "application/vnd.micrografx.igx": ["igx"], "application/vnd.mif": ["mif"], "application/vnd.mobius.daf": ["daf"], "application/vnd.mobius.dis": ["dis"], "application/vnd.mobius.mbk": ["mbk"], "application/vnd.mobius.mqy": ["mqy"], "application/vnd.mobius.msl": ["msl"], "application/vnd.mobius.plc": ["plc"], "application/vnd.mobius.txf": ["txf"], "application/vnd.mophun.application": ["mpn"], "application/vnd.mophun.certificate": ["mpc"], "application/vnd.mozilla.xul+xml": ["xul"], "application/vnd.ms-artgalry": ["cil"], "application/vnd.ms-cab-compressed": ["cab"], "application/vnd.ms-excel": ["xls", "xlm", "xla", "xlc", "xlt", "xlw"], "application/vnd.ms-excel.addin.macroenabled.12": ["xlam"], "application/vnd.ms-excel.sheet.binary.macroenabled.12": ["xlsb"], "application/vnd.ms-excel.sheet.macroenabled.12": ["xlsm"], "application/vnd.ms-excel.template.macroenabled.12": ["xltm"], "application/vnd.ms-fontobject": ["eot"], "application/vnd.ms-htmlhelp": ["chm"], "application/vnd.ms-ims": ["ims"], "application/vnd.ms-lrm": ["lrm"], "application/vnd.ms-officetheme": ["thmx"], "application/vnd.ms-outlook": ["msg"], "application/vnd.ms-pki.seccat": ["cat"], "application/vnd.ms-pki.stl": ["*stl"], "application/vnd.ms-powerpoint": ["ppt", "pps", "pot"], "application/vnd.ms-powerpoint.addin.macroenabled.12": ["ppam"], "application/vnd.ms-powerpoint.presentation.macroenabled.12": ["pptm"], "application/vnd.ms-powerpoint.slide.macroenabled.12": ["sldm"], "application/vnd.ms-powerpoint.slideshow.macroenabled.12": ["ppsm"], "application/vnd.ms-powerpoint.template.macroenabled.12": ["potm"], "application/vnd.ms-project": ["*mpp", "mpt"], "application/vnd.ms-word.document.macroenabled.12": ["docm"], "application/vnd.ms-word.template.macroenabled.12": ["dotm"], "application/vnd.ms-works": ["wps", "wks", "wcm", "wdb"], "application/vnd.ms-wpl": ["wpl"], "application/vnd.ms-xpsdocument": ["xps"], "application/vnd.mseq": ["mseq"], "application/vnd.musician": ["mus"], "application/vnd.muvee.style": ["msty"], "application/vnd.mynfc": ["taglet"], "application/vnd.neurolanguage.nlu": ["nlu"], "application/vnd.nitf": ["ntf", "nitf"], "application/vnd.noblenet-directory": ["nnd"], "application/vnd.noblenet-sealer": ["nns"], "application/vnd.noblenet-web": ["nnw"], "application/vnd.nokia.n-gage.ac+xml": ["*ac"], "application/vnd.nokia.n-gage.data": ["ngdat"], "application/vnd.nokia.n-gage.symbian.install": ["n-gage"], "application/vnd.nokia.radio-preset": ["rpst"], "application/vnd.nokia.radio-presets": ["rpss"], "application/vnd.novadigm.edm": ["edm"], "application/vnd.novadigm.edx": ["edx"], "application/vnd.novadigm.ext": ["ext"], "application/vnd.oasis.opendocument.chart": ["odc"], "application/vnd.oasis.opendocument.chart-template": ["otc"], "application/vnd.oasis.opendocument.database": ["odb"], "application/vnd.oasis.opendocument.formula": ["odf"], "application/vnd.oasis.opendocument.formula-template": ["odft"], "application/vnd.oasis.opendocument.graphics": ["odg"], "application/vnd.oasis.opendocument.graphics-template": ["otg"], "application/vnd.oasis.opendocument.image": ["odi"], "application/vnd.oasis.opendocument.image-template": ["oti"], "application/vnd.oasis.opendocument.presentation": ["odp"], "application/vnd.oasis.opendocument.presentation-template": ["otp"], "application/vnd.oasis.opendocument.spreadsheet": ["ods"], "application/vnd.oasis.opendocument.spreadsheet-template": ["ots"], "application/vnd.oasis.opendocument.text": ["odt"], "application/vnd.oasis.opendocument.text-master": ["odm"], "application/vnd.oasis.opendocument.text-template": ["ott"], "application/vnd.oasis.opendocument.text-web": ["oth"], "application/vnd.olpc-sugar": ["xo"], "application/vnd.oma.dd2+xml": ["dd2"], "application/vnd.openblox.game+xml": ["obgx"], "application/vnd.openofficeorg.extension": ["oxt"], "application/vnd.openstreetmap.data+xml": ["osm"], "application/vnd.openxmlformats-officedocument.presentationml.presentation": ["pptx"], "application/vnd.openxmlformats-officedocument.presentationml.slide": ["sldx"], "application/vnd.openxmlformats-officedocument.presentationml.slideshow": ["ppsx"], "application/vnd.openxmlformats-officedocument.presentationml.template": ["potx"], "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ["xlsx"], "application/vnd.openxmlformats-officedocument.spreadsheetml.template": ["xltx"], "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ["docx"], "application/vnd.openxmlformats-officedocument.wordprocessingml.template": ["dotx"], "application/vnd.osgeo.mapguide.package": ["mgp"], "application/vnd.osgi.dp": ["dp"], "application/vnd.osgi.subsystem": ["esa"], "application/vnd.palm": ["pdb", "pqa", "oprc"], "application/vnd.pawaafile": ["paw"], "application/vnd.pg.format": ["str"], "application/vnd.pg.osasli": ["ei6"], "application/vnd.picsel": ["efif"], "application/vnd.pmi.widget": ["wg"], "application/vnd.pocketlearn": ["plf"], "application/vnd.powerbuilder6": ["pbd"], "application/vnd.previewsystems.box": ["box"], "application/vnd.proteus.magazine": ["mgz"], "application/vnd.publishare-delta-tree": ["qps"], "application/vnd.pvi.ptid1": ["ptid"], "application/vnd.pwg-xhtml-print+xml": ["xhtm"], "application/vnd.quark.quarkxpress": ["qxd", "qxt", "qwd", "qwt", "qxl", "qxb"], "application/vnd.rar": ["rar"], "application/vnd.realvnc.bed": ["bed"], "application/vnd.recordare.musicxml": ["mxl"], "application/vnd.recordare.musicxml+xml": ["musicxml"], "application/vnd.rig.cryptonote": ["cryptonote"], "application/vnd.rim.cod": ["cod"], "application/vnd.rn-realmedia": ["rm"], "application/vnd.rn-realmedia-vbr": ["rmvb"], "application/vnd.route66.link66+xml": ["link66"], "application/vnd.sailingtracker.track": ["st"], "application/vnd.seemail": ["see"], "application/vnd.sema": ["sema"], "application/vnd.semd": ["semd"], "application/vnd.semf": ["semf"], "application/vnd.shana.informed.formdata": ["ifm"], "application/vnd.shana.informed.formtemplate": ["itp"], "application/vnd.shana.informed.interchange": ["iif"], "application/vnd.shana.informed.package": ["ipk"], "application/vnd.simtech-mindmapper": ["twd", "twds"], "application/vnd.smaf": ["mmf"], "application/vnd.smart.teacher": ["teacher"], "application/vnd.software602.filler.form+xml": ["fo"], "application/vnd.solent.sdkm+xml": ["sdkm", "sdkd"], "application/vnd.spotfire.dxp": ["dxp"], "application/vnd.spotfire.sfs": ["sfs"], "application/vnd.stardivision.calc": ["sdc"], "application/vnd.stardivision.draw": ["sda"], "application/vnd.stardivision.impress": ["sdd"], "application/vnd.stardivision.math": ["smf"], "application/vnd.stardivision.writer": ["sdw", "vor"], "application/vnd.stardivision.writer-global": ["sgl"], "application/vnd.stepmania.package": ["smzip"], "application/vnd.stepmania.stepchart": ["sm"], "application/vnd.sun.wadl+xml": ["wadl"], "application/vnd.sun.xml.calc": ["sxc"], "application/vnd.sun.xml.calc.template": ["stc"], "application/vnd.sun.xml.draw": ["sxd"], "application/vnd.sun.xml.draw.template": ["std"], "application/vnd.sun.xml.impress": ["sxi"], "application/vnd.sun.xml.impress.template": ["sti"], "application/vnd.sun.xml.math": ["sxm"], "application/vnd.sun.xml.writer": ["sxw"], "application/vnd.sun.xml.writer.global": ["sxg"], "application/vnd.sun.xml.writer.template": ["stw"], "application/vnd.sus-calendar": ["sus", "susp"], "application/vnd.svd": ["svd"], "application/vnd.symbian.install": ["sis", "sisx"], "application/vnd.syncml+xml": ["xsm"], "application/vnd.syncml.dm+wbxml": ["bdm"], "application/vnd.syncml.dm+xml": ["xdm"], "application/vnd.syncml.dmddf+xml": ["ddf"], "application/vnd.tao.intent-module-archive": ["tao"], "application/vnd.tcpdump.pcap": ["pcap", "cap", "dmp"], "application/vnd.tmobile-livetv": ["tmo"], "application/vnd.trid.tpt": ["tpt"], "application/vnd.triscape.mxs": ["mxs"], "application/vnd.trueapp": ["tra"], "application/vnd.ufdl": ["ufd", "ufdl"], "application/vnd.uiq.theme": ["utz"], "application/vnd.umajin": ["umj"], "application/vnd.unity": ["unityweb"], "application/vnd.uoml+xml": ["uoml", "uo"], "application/vnd.vcx": ["vcx"], "application/vnd.visio": ["vsd", "vst", "vss", "vsw"], "application/vnd.visionary": ["vis"], "application/vnd.vsf": ["vsf"], "application/vnd.wap.wbxml": ["wbxml"], "application/vnd.wap.wmlc": ["wmlc"], "application/vnd.wap.wmlscriptc": ["wmlsc"], "application/vnd.webturbo": ["wtb"], "application/vnd.wolfram.player": ["nbp"], "application/vnd.wordperfect": ["wpd"], "application/vnd.wqd": ["wqd"], "application/vnd.wt.stf": ["stf"], "application/vnd.xara": ["xar"], "application/vnd.xfdl": ["xfdl"], "application/vnd.yamaha.hv-dic": ["hvd"], "application/vnd.yamaha.hv-script": ["hvs"], "application/vnd.yamaha.hv-voice": ["hvp"], "application/vnd.yamaha.openscoreformat": ["osf"], "application/vnd.yamaha.openscoreformat.osfpvg+xml": ["osfpvg"], "application/vnd.yamaha.smaf-audio": ["saf"], "application/vnd.yamaha.smaf-phrase": ["spf"], "application/vnd.yellowriver-custom-menu": ["cmp"], "application/vnd.zul": ["zir", "zirz"], "application/vnd.zzazz.deck+xml": ["zaz"], "application/x-7z-compressed": ["7z"], "application/x-abiword": ["abw"], "application/x-ace-compressed": ["ace"], "application/x-apple-diskimage": ["*dmg"], "application/x-arj": ["arj"], "application/x-authorware-bin": ["aab", "x32", "u32", "vox"], "application/x-authorware-map": ["aam"], "application/x-authorware-seg": ["aas"], "application/x-bcpio": ["bcpio"], "application/x-bdoc": ["*bdoc"], "application/x-bittorrent": ["torrent"], "application/x-blorb": ["blb", "blorb"], "application/x-bzip": ["bz"], "application/x-bzip2": ["bz2", "boz"], "application/x-cbr": ["cbr", "cba", "cbt", "cbz", "cb7"], "application/x-cdlink": ["vcd"], "application/x-cfs-compressed": ["cfs"], "application/x-chat": ["chat"], "application/x-chess-pgn": ["pgn"], "application/x-chrome-extension": ["crx"], "application/x-cocoa": ["cco"], "application/x-conference": ["nsc"], "application/x-cpio": ["cpio"], "application/x-csh": ["csh"], "application/x-debian-package": ["*deb", "udeb"], "application/x-dgc-compressed": ["dgc"], "application/x-director": ["dir", "dcr", "dxr", "cst", "cct", "cxt", "w3d", "fgd", "swa"], "application/x-doom": ["wad"], "application/x-dtbncx+xml": ["ncx"], "application/x-dtbook+xml": ["dtb"], "application/x-dtbresource+xml": ["res"], "application/x-dvi": ["dvi"], "application/x-envoy": ["evy"], "application/x-eva": ["eva"], "application/x-font-bdf": ["bdf"], "application/x-font-ghostscript": ["gsf"], "application/x-font-linux-psf": ["psf"], "application/x-font-pcf": ["pcf"], "application/x-font-snf": ["snf"], "application/x-font-type1": ["pfa", "pfb", "pfm", "afm"], "application/x-freearc": ["arc"], "application/x-futuresplash": ["spl"], "application/x-gca-compressed": ["gca"], "application/x-glulx": ["ulx"], "application/x-gnumeric": ["gnumeric"], "application/x-gramps-xml": ["gramps"], "application/x-gtar": ["gtar"], "application/x-hdf": ["hdf"], "application/x-httpd-php": ["php"], "application/x-install-instructions": ["install"], "application/x-iso9660-image": ["*iso"], "application/x-iwork-keynote-sffkey": ["*key"], "application/x-iwork-numbers-sffnumbers": ["*numbers"], "application/x-iwork-pages-sffpages": ["*pages"], "application/x-java-archive-diff": ["jardiff"], "application/x-java-jnlp-file": ["jnlp"], "application/x-keepass2": ["kdbx"], "application/x-latex": ["latex"], "application/x-lua-bytecode": ["luac"], "application/x-lzh-compressed": ["lzh", "lha"], "application/x-makeself": ["run"], "application/x-mie": ["mie"], "application/x-mobipocket-ebook": ["*prc", "mobi"], "application/x-ms-application": ["application"], "application/x-ms-shortcut": ["lnk"], "application/x-ms-wmd": ["wmd"], "application/x-ms-wmz": ["wmz"], "application/x-ms-xbap": ["xbap"], "application/x-msaccess": ["mdb"], "application/x-msbinder": ["obd"], "application/x-mscardfile": ["crd"], "application/x-msclip": ["clp"], "application/x-msdos-program": ["*exe"], "application/x-msdownload": ["*exe", "*dll", "com", "bat", "*msi"], "application/x-msmediaview": ["mvb", "m13", "m14"], "application/x-msmetafile": ["*wmf", "*wmz", "*emf", "emz"], "application/x-msmoney": ["mny"], "application/x-mspublisher": ["pub"], "application/x-msschedule": ["scd"], "application/x-msterminal": ["trm"], "application/x-mswrite": ["wri"], "application/x-netcdf": ["nc", "cdf"], "application/x-ns-proxy-autoconfig": ["pac"], "application/x-nzb": ["nzb"], "application/x-perl": ["pl", "pm"], "application/x-pilot": ["*prc", "*pdb"], "application/x-pkcs12": ["p12", "pfx"], "application/x-pkcs7-certificates": ["p7b", "spc"], "application/x-pkcs7-certreqresp": ["p7r"], "application/x-rar-compressed": ["*rar"], "application/x-redhat-package-manager": ["rpm"], "application/x-research-info-systems": ["ris"], "application/x-sea": ["sea"], "application/x-sh": ["sh"], "application/x-shar": ["shar"], "application/x-shockwave-flash": ["swf"], "application/x-silverlight-app": ["xap"], "application/x-sql": ["*sql"], "application/x-stuffit": ["sit"], "application/x-stuffitx": ["sitx"], "application/x-subrip": ["srt"], "application/x-sv4cpio": ["sv4cpio"], "application/x-sv4crc": ["sv4crc"], "application/x-t3vm-image": ["t3"], "application/x-tads": ["gam"], "application/x-tar": ["tar"], "application/x-tcl": ["tcl", "tk"], "application/x-tex": ["tex"], "application/x-tex-tfm": ["tfm"], "application/x-texinfo": ["texinfo", "texi"], "application/x-tgif": ["*obj"], "application/x-ustar": ["ustar"], "application/x-virtualbox-hdd": ["hdd"], "application/x-virtualbox-ova": ["ova"], "application/x-virtualbox-ovf": ["ovf"], "application/x-virtualbox-vbox": ["vbox"], "application/x-virtualbox-vbox-extpack": ["vbox-extpack"], "application/x-virtualbox-vdi": ["vdi"], "application/x-virtualbox-vhd": ["vhd"], "application/x-virtualbox-vmdk": ["vmdk"], "application/x-wais-source": ["src"], "application/x-web-app-manifest+json": ["webapp"], "application/x-x509-ca-cert": ["der", "crt", "pem"], "application/x-xfig": ["fig"], "application/x-xliff+xml": ["*xlf"], "application/x-xpinstall": ["xpi"], "application/x-xz": ["xz"], "application/x-zmachine": ["z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8"], "audio/vnd.dece.audio": ["uva", "uvva"], "audio/vnd.digital-winds": ["eol"], "audio/vnd.dra": ["dra"], "audio/vnd.dts": ["dts"], "audio/vnd.dts.hd": ["dtshd"], "audio/vnd.lucent.voice": ["lvp"], "audio/vnd.ms-playready.media.pya": ["pya"], "audio/vnd.nuera.ecelp4800": ["ecelp4800"], "audio/vnd.nuera.ecelp7470": ["ecelp7470"], "audio/vnd.nuera.ecelp9600": ["ecelp9600"], "audio/vnd.rip": ["rip"], "audio/x-aac": ["*aac"], "audio/x-aiff": ["aif", "aiff", "aifc"], "audio/x-caf": ["caf"], "audio/x-flac": ["flac"], "audio/x-m4a": ["*m4a"], "audio/x-matroska": ["mka"], "audio/x-mpegurl": ["m3u"], "audio/x-ms-wax": ["wax"], "audio/x-ms-wma": ["wma"], "audio/x-pn-realaudio": ["ram", "ra"], "audio/x-pn-realaudio-plugin": ["rmp"], "audio/x-realaudio": ["*ra"], "audio/x-wav": ["*wav"], "chemical/x-cdx": ["cdx"], "chemical/x-cif": ["cif"], "chemical/x-cmdf": ["cmdf"], "chemical/x-cml": ["cml"], "chemical/x-csml": ["csml"], "chemical/x-xyz": ["xyz"], "image/prs.btif": ["btif", "btf"], "image/prs.pti": ["pti"], "image/vnd.adobe.photoshop": ["psd"], "image/vnd.airzip.accelerator.azv": ["azv"], "image/vnd.dece.graphic": ["uvi", "uvvi", "uvg", "uvvg"], "image/vnd.djvu": ["djvu", "djv"], "image/vnd.dvb.subtitle": ["*sub"], "image/vnd.dwg": ["dwg"], "image/vnd.dxf": ["dxf"], "image/vnd.fastbidsheet": ["fbs"], "image/vnd.fpx": ["fpx"], "image/vnd.fst": ["fst"], "image/vnd.fujixerox.edmics-mmr": ["mmr"], "image/vnd.fujixerox.edmics-rlc": ["rlc"], "image/vnd.microsoft.icon": ["ico"], "image/vnd.ms-dds": ["dds"], "image/vnd.ms-modi": ["mdi"], "image/vnd.ms-photo": ["wdp"], "image/vnd.net-fpx": ["npx"], "image/vnd.pco.b16": ["b16"], "image/vnd.tencent.tap": ["tap"], "image/vnd.valve.source.texture": ["vtf"], "image/vnd.wap.wbmp": ["wbmp"], "image/vnd.xiff": ["xif"], "image/vnd.zbrush.pcx": ["pcx"], "image/x-3ds": ["3ds"], "image/x-cmu-raster": ["ras"], "image/x-cmx": ["cmx"], "image/x-freehand": ["fh", "fhc", "fh4", "fh5", "fh7"], "image/x-icon": ["*ico"], "image/x-jng": ["jng"], "image/x-mrsid-image": ["sid"], "image/x-ms-bmp": ["*bmp"], "image/x-pcx": ["*pcx"], "image/x-pict": ["pic", "pct"], "image/x-portable-anymap": ["pnm"], "image/x-portable-bitmap": ["pbm"], "image/x-portable-graymap": ["pgm"], "image/x-portable-pixmap": ["ppm"], "image/x-rgb": ["rgb"], "image/x-tga": ["tga"], "image/x-xbitmap": ["xbm"], "image/x-xpixmap": ["xpm"], "image/x-xwindowdump": ["xwd"], "message/vnd.wfa.wsc": ["wsc"], "model/vnd.cld": ["cld"], "model/vnd.collada+xml": ["dae"], "model/vnd.dwf": ["dwf"], "model/vnd.gdl": ["gdl"], "model/vnd.gtw": ["gtw"], "model/vnd.mts": ["mts"], "model/vnd.opengex": ["ogex"], "model/vnd.parasolid.transmit.binary": ["x_b"], "model/vnd.parasolid.transmit.text": ["x_t"], "model/vnd.pytha.pyox": ["pyo", "pyox"], "model/vnd.sap.vds": ["vds"], "model/vnd.usda": ["usda"], "model/vnd.usdz+zip": ["usdz"], "model/vnd.valve.source.compiled-map": ["bsp"], "model/vnd.vtu": ["vtu"], "text/prs.lines.tag": ["dsc"], "text/vnd.curl": ["curl"], "text/vnd.curl.dcurl": ["dcurl"], "text/vnd.curl.mcurl": ["mcurl"], "text/vnd.curl.scurl": ["scurl"], "text/vnd.dvb.subtitle": ["sub"], "text/vnd.familysearch.gedcom": ["ged"], "text/vnd.fly": ["fly"], "text/vnd.fmi.flexstor": ["flx"], "text/vnd.graphviz": ["gv"], "text/vnd.in3d.3dml": ["3dml"], "text/vnd.in3d.spot": ["spot"], "text/vnd.sun.j2me.app-descriptor": ["jad"], "text/vnd.wap.wml": ["wml"], "text/vnd.wap.wmlscript": ["wmls"], "text/x-asm": ["s", "asm"], "text/x-c": ["c", "cc", "cxx", "cpp", "h", "hh", "dic"], "text/x-component": ["htc"], "text/x-fortran": ["f", "for", "f77", "f90"], "text/x-handlebars-template": ["hbs"], "text/x-java-source": ["java"], "text/x-lua": ["lua"], "text/x-markdown": ["mkd"], "text/x-nfo": ["nfo"], "text/x-opml": ["opml"], "text/x-org": ["*org"], "text/x-pascal": ["p", "pas"], "text/x-processing": ["pde"], "text/x-sass": ["sass"], "text/x-scss": ["scss"], "text/x-setext": ["etx"], "text/x-sfv": ["sfv"], "text/x-suse-ymp": ["ymp"], "text/x-uuencode": ["uu"], "text/x-vcalendar": ["vcs"], "text/x-vcard": ["vcf"], "video/vnd.dece.hd": ["uvh", "uvvh"], "video/vnd.dece.mobile": ["uvm", "uvvm"], "video/vnd.dece.pd": ["uvp", "uvvp"], "video/vnd.dece.sd": ["uvs", "uvvs"], "video/vnd.dece.video": ["uvv", "uvvv"], "video/vnd.dvb.file": ["dvb"], "video/vnd.fvt": ["fvt"], "video/vnd.mpegurl": ["mxu", "m4u"], "video/vnd.ms-playready.media.pyv": ["pyv"], "video/vnd.uvvu.mp4": ["uvu", "uvvu"], "video/vnd.vivo": ["viv"], "video/x-f4v": ["f4v"], "video/x-fli": ["fli"], "video/x-flv": ["flv"], "video/x-m4v": ["m4v"], "video/x-matroska": ["mkv", "mk3d", "mks"], "video/x-mng": ["mng"], "video/x-ms-asf": ["asf", "asx"], "video/x-ms-vob": ["vob"], "video/x-ms-wm": ["wm"], "video/x-ms-wmv": ["wmv"], "video/x-ms-wmx": ["wmx"], "video/x-ms-wvx": ["wvx"], "video/x-msvideo": ["avi"], "video/x-sgi-movie": ["movie"], "video/x-smv": ["smv"], "x-conference/x-cooltalk": ["ice"] }; +Object.freeze(types); +export default types; +//# sourceMappingURL=other.js.map \ No newline at end of file diff --git a/node_modules/mime/dist/types/other.js.map b/node_modules/mime/dist/types/other.js.map new file mode 100644 index 0000000..84e5855 --- /dev/null +++ b/node_modules/mime/dist/types/other.js.map @@ -0,0 +1 @@ +{"version":3,"file":"other.js","sourceRoot":"","sources":["../../types/other.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/mime/dist/types/standard.d.ts b/node_modules/mime/dist/types/standard.d.ts new file mode 100644 index 0000000..12f015a --- /dev/null +++ b/node_modules/mime/dist/types/standard.d.ts @@ -0,0 +1,4 @@ +declare const types: { + [key: string]: string[]; +}; +export default types; diff --git a/node_modules/mime/dist/types/standard.js b/node_modules/mime/dist/types/standard.js new file mode 100644 index 0000000..0093630 --- /dev/null +++ b/node_modules/mime/dist/types/standard.js @@ -0,0 +1,4 @@ +const types = { "application/andrew-inset": ["ez"], "application/appinstaller": ["appinstaller"], "application/applixware": ["aw"], "application/appx": ["appx"], "application/appxbundle": ["appxbundle"], "application/atom+xml": ["atom"], "application/atomcat+xml": ["atomcat"], "application/atomdeleted+xml": ["atomdeleted"], "application/atomsvc+xml": ["atomsvc"], "application/atsc-dwd+xml": ["dwd"], "application/atsc-held+xml": ["held"], "application/atsc-rsat+xml": ["rsat"], "application/automationml-aml+xml": ["aml"], "application/automationml-amlx+zip": ["amlx"], "application/bdoc": ["bdoc"], "application/calendar+xml": ["xcs"], "application/ccxml+xml": ["ccxml"], "application/cdfx+xml": ["cdfx"], "application/cdmi-capability": ["cdmia"], "application/cdmi-container": ["cdmic"], "application/cdmi-domain": ["cdmid"], "application/cdmi-object": ["cdmio"], "application/cdmi-queue": ["cdmiq"], "application/cpl+xml": ["cpl"], "application/cu-seeme": ["cu"], "application/cwl": ["cwl"], "application/dash+xml": ["mpd"], "application/dash-patch+xml": ["mpp"], "application/davmount+xml": ["davmount"], "application/docbook+xml": ["dbk"], "application/dssc+der": ["dssc"], "application/dssc+xml": ["xdssc"], "application/ecmascript": ["ecma"], "application/emma+xml": ["emma"], "application/emotionml+xml": ["emotionml"], "application/epub+zip": ["epub"], "application/exi": ["exi"], "application/express": ["exp"], "application/fdf": ["fdf"], "application/fdt+xml": ["fdt"], "application/font-tdpfr": ["pfr"], "application/geo+json": ["geojson"], "application/gml+xml": ["gml"], "application/gpx+xml": ["gpx"], "application/gxf": ["gxf"], "application/gzip": ["gz"], "application/hjson": ["hjson"], "application/hyperstudio": ["stk"], "application/inkml+xml": ["ink", "inkml"], "application/ipfix": ["ipfix"], "application/its+xml": ["its"], "application/java-archive": ["jar", "war", "ear"], "application/java-serialized-object": ["ser"], "application/java-vm": ["class"], "application/javascript": ["*js"], "application/json": ["json", "map"], "application/json5": ["json5"], "application/jsonml+json": ["jsonml"], "application/ld+json": ["jsonld"], "application/lgr+xml": ["lgr"], "application/lost+xml": ["lostxml"], "application/mac-binhex40": ["hqx"], "application/mac-compactpro": ["cpt"], "application/mads+xml": ["mads"], "application/manifest+json": ["webmanifest"], "application/marc": ["mrc"], "application/marcxml+xml": ["mrcx"], "application/mathematica": ["ma", "nb", "mb"], "application/mathml+xml": ["mathml"], "application/mbox": ["mbox"], "application/media-policy-dataset+xml": ["mpf"], "application/mediaservercontrol+xml": ["mscml"], "application/metalink+xml": ["metalink"], "application/metalink4+xml": ["meta4"], "application/mets+xml": ["mets"], "application/mmt-aei+xml": ["maei"], "application/mmt-usd+xml": ["musd"], "application/mods+xml": ["mods"], "application/mp21": ["m21", "mp21"], "application/mp4": ["*mp4", "*mpg4", "mp4s", "m4p"], "application/msix": ["msix"], "application/msixbundle": ["msixbundle"], "application/msword": ["doc", "dot"], "application/mxf": ["mxf"], "application/n-quads": ["nq"], "application/n-triples": ["nt"], "application/node": ["cjs"], "application/octet-stream": ["bin", "dms", "lrf", "mar", "so", "dist", "distz", "pkg", "bpk", "dump", "elc", "deploy", "exe", "dll", "deb", "dmg", "iso", "img", "msi", "msp", "msm", "buffer"], "application/oda": ["oda"], "application/oebps-package+xml": ["opf"], "application/ogg": ["ogx"], "application/omdoc+xml": ["omdoc"], "application/onenote": ["onetoc", "onetoc2", "onetmp", "onepkg"], "application/oxps": ["oxps"], "application/p2p-overlay+xml": ["relo"], "application/patch-ops-error+xml": ["xer"], "application/pdf": ["pdf"], "application/pgp-encrypted": ["pgp"], "application/pgp-keys": ["asc"], "application/pgp-signature": ["sig", "*asc"], "application/pics-rules": ["prf"], "application/pkcs10": ["p10"], "application/pkcs7-mime": ["p7m", "p7c"], "application/pkcs7-signature": ["p7s"], "application/pkcs8": ["p8"], "application/pkix-attr-cert": ["ac"], "application/pkix-cert": ["cer"], "application/pkix-crl": ["crl"], "application/pkix-pkipath": ["pkipath"], "application/pkixcmp": ["pki"], "application/pls+xml": ["pls"], "application/postscript": ["ai", "eps", "ps"], "application/provenance+xml": ["provx"], "application/pskc+xml": ["pskcxml"], "application/raml+yaml": ["raml"], "application/rdf+xml": ["rdf", "owl"], "application/reginfo+xml": ["rif"], "application/relax-ng-compact-syntax": ["rnc"], "application/resource-lists+xml": ["rl"], "application/resource-lists-diff+xml": ["rld"], "application/rls-services+xml": ["rs"], "application/route-apd+xml": ["rapd"], "application/route-s-tsid+xml": ["sls"], "application/route-usd+xml": ["rusd"], "application/rpki-ghostbusters": ["gbr"], "application/rpki-manifest": ["mft"], "application/rpki-roa": ["roa"], "application/rsd+xml": ["rsd"], "application/rss+xml": ["rss"], "application/rtf": ["rtf"], "application/sbml+xml": ["sbml"], "application/scvp-cv-request": ["scq"], "application/scvp-cv-response": ["scs"], "application/scvp-vp-request": ["spq"], "application/scvp-vp-response": ["spp"], "application/sdp": ["sdp"], "application/senml+xml": ["senmlx"], "application/sensml+xml": ["sensmlx"], "application/set-payment-initiation": ["setpay"], "application/set-registration-initiation": ["setreg"], "application/shf+xml": ["shf"], "application/sieve": ["siv", "sieve"], "application/smil+xml": ["smi", "smil"], "application/sparql-query": ["rq"], "application/sparql-results+xml": ["srx"], "application/sql": ["sql"], "application/srgs": ["gram"], "application/srgs+xml": ["grxml"], "application/sru+xml": ["sru"], "application/ssdl+xml": ["ssdl"], "application/ssml+xml": ["ssml"], "application/swid+xml": ["swidtag"], "application/tei+xml": ["tei", "teicorpus"], "application/thraud+xml": ["tfi"], "application/timestamped-data": ["tsd"], "application/toml": ["toml"], "application/trig": ["trig"], "application/ttml+xml": ["ttml"], "application/ubjson": ["ubj"], "application/urc-ressheet+xml": ["rsheet"], "application/urc-targetdesc+xml": ["td"], "application/voicexml+xml": ["vxml"], "application/wasm": ["wasm"], "application/watcherinfo+xml": ["wif"], "application/widget": ["wgt"], "application/winhlp": ["hlp"], "application/wsdl+xml": ["wsdl"], "application/wspolicy+xml": ["wspolicy"], "application/xaml+xml": ["xaml"], "application/xcap-att+xml": ["xav"], "application/xcap-caps+xml": ["xca"], "application/xcap-diff+xml": ["xdf"], "application/xcap-el+xml": ["xel"], "application/xcap-ns+xml": ["xns"], "application/xenc+xml": ["xenc"], "application/xfdf": ["xfdf"], "application/xhtml+xml": ["xhtml", "xht"], "application/xliff+xml": ["xlf"], "application/xml": ["xml", "xsl", "xsd", "rng"], "application/xml-dtd": ["dtd"], "application/xop+xml": ["xop"], "application/xproc+xml": ["xpl"], "application/xslt+xml": ["*xsl", "xslt"], "application/xspf+xml": ["xspf"], "application/xv+xml": ["mxml", "xhvml", "xvml", "xvm"], "application/yang": ["yang"], "application/yin+xml": ["yin"], "application/zip": ["zip"], "audio/3gpp": ["*3gpp"], "audio/aac": ["adts", "aac"], "audio/adpcm": ["adp"], "audio/amr": ["amr"], "audio/basic": ["au", "snd"], "audio/midi": ["mid", "midi", "kar", "rmi"], "audio/mobile-xmf": ["mxmf"], "audio/mp3": ["*mp3"], "audio/mp4": ["m4a", "mp4a"], "audio/mpeg": ["mpga", "mp2", "mp2a", "mp3", "m2a", "m3a"], "audio/ogg": ["oga", "ogg", "spx", "opus"], "audio/s3m": ["s3m"], "audio/silk": ["sil"], "audio/wav": ["wav"], "audio/wave": ["*wav"], "audio/webm": ["weba"], "audio/xm": ["xm"], "font/collection": ["ttc"], "font/otf": ["otf"], "font/ttf": ["ttf"], "font/woff": ["woff"], "font/woff2": ["woff2"], "image/aces": ["exr"], "image/apng": ["apng"], "image/avci": ["avci"], "image/avcs": ["avcs"], "image/avif": ["avif"], "image/bmp": ["bmp", "dib"], "image/cgm": ["cgm"], "image/dicom-rle": ["drle"], "image/dpx": ["dpx"], "image/emf": ["emf"], "image/fits": ["fits"], "image/g3fax": ["g3"], "image/gif": ["gif"], "image/heic": ["heic"], "image/heic-sequence": ["heics"], "image/heif": ["heif"], "image/heif-sequence": ["heifs"], "image/hej2k": ["hej2"], "image/hsj2": ["hsj2"], "image/ief": ["ief"], "image/jls": ["jls"], "image/jp2": ["jp2", "jpg2"], "image/jpeg": ["jpeg", "jpg", "jpe"], "image/jph": ["jph"], "image/jphc": ["jhc"], "image/jpm": ["jpm", "jpgm"], "image/jpx": ["jpx", "jpf"], "image/jxr": ["jxr"], "image/jxra": ["jxra"], "image/jxrs": ["jxrs"], "image/jxs": ["jxs"], "image/jxsc": ["jxsc"], "image/jxsi": ["jxsi"], "image/jxss": ["jxss"], "image/ktx": ["ktx"], "image/ktx2": ["ktx2"], "image/png": ["png"], "image/sgi": ["sgi"], "image/svg+xml": ["svg", "svgz"], "image/t38": ["t38"], "image/tiff": ["tif", "tiff"], "image/tiff-fx": ["tfx"], "image/webp": ["webp"], "image/wmf": ["wmf"], "message/disposition-notification": ["disposition-notification"], "message/global": ["u8msg"], "message/global-delivery-status": ["u8dsn"], "message/global-disposition-notification": ["u8mdn"], "message/global-headers": ["u8hdr"], "message/rfc822": ["eml", "mime"], "model/3mf": ["3mf"], "model/gltf+json": ["gltf"], "model/gltf-binary": ["glb"], "model/iges": ["igs", "iges"], "model/jt": ["jt"], "model/mesh": ["msh", "mesh", "silo"], "model/mtl": ["mtl"], "model/obj": ["obj"], "model/prc": ["prc"], "model/step+xml": ["stpx"], "model/step+zip": ["stpz"], "model/step-xml+zip": ["stpxz"], "model/stl": ["stl"], "model/u3d": ["u3d"], "model/vrml": ["wrl", "vrml"], "model/x3d+binary": ["*x3db", "x3dbz"], "model/x3d+fastinfoset": ["x3db"], "model/x3d+vrml": ["*x3dv", "x3dvz"], "model/x3d+xml": ["x3d", "x3dz"], "model/x3d-vrml": ["x3dv"], "text/cache-manifest": ["appcache", "manifest"], "text/calendar": ["ics", "ifb"], "text/coffeescript": ["coffee", "litcoffee"], "text/css": ["css"], "text/csv": ["csv"], "text/html": ["html", "htm", "shtml"], "text/jade": ["jade"], "text/javascript": ["js", "mjs"], "text/jsx": ["jsx"], "text/less": ["less"], "text/markdown": ["md", "markdown"], "text/mathml": ["mml"], "text/mdx": ["mdx"], "text/n3": ["n3"], "text/plain": ["txt", "text", "conf", "def", "list", "log", "in", "ini"], "text/richtext": ["rtx"], "text/rtf": ["*rtf"], "text/sgml": ["sgml", "sgm"], "text/shex": ["shex"], "text/slim": ["slim", "slm"], "text/spdx": ["spdx"], "text/stylus": ["stylus", "styl"], "text/tab-separated-values": ["tsv"], "text/troff": ["t", "tr", "roff", "man", "me", "ms"], "text/turtle": ["ttl"], "text/uri-list": ["uri", "uris", "urls"], "text/vcard": ["vcard"], "text/vtt": ["vtt"], "text/wgsl": ["wgsl"], "text/xml": ["*xml"], "text/yaml": ["yaml", "yml"], "video/3gpp": ["3gp", "3gpp"], "video/3gpp2": ["3g2"], "video/h261": ["h261"], "video/h263": ["h263"], "video/h264": ["h264"], "video/iso.segment": ["m4s"], "video/jpeg": ["jpgv"], "video/jpm": ["*jpm", "*jpgm"], "video/mj2": ["mj2", "mjp2"], "video/mp2t": ["ts"], "video/mp4": ["mp4", "mp4v", "mpg4"], "video/mpeg": ["mpeg", "mpg", "mpe", "m1v", "m2v"], "video/ogg": ["ogv"], "video/quicktime": ["qt", "mov"], "video/webm": ["webm"] }; +Object.freeze(types); +export default types; +//# sourceMappingURL=standard.js.map \ No newline at end of file diff --git a/node_modules/mime/dist/types/standard.js.map b/node_modules/mime/dist/types/standard.js.map new file mode 100644 index 0000000..5cd0140 --- /dev/null +++ b/node_modules/mime/dist/types/standard.js.map @@ -0,0 +1 @@ +{"version":3,"file":"standard.js","sourceRoot":"","sources":["../../types/standard.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/mime/package.json b/node_modules/mime/package.json new file mode 100644 index 0000000..fd2125d --- /dev/null +++ b/node_modules/mime/package.json @@ -0,0 +1,73 @@ +{ + "author": { + "name": "Robert Kieffer", + "url": "http://github.com/broofa", + "email": "robert@broofa.com" + }, + "type": "module", + "engines": { + "node": ">=16" + }, + "main": "./dist/src/index.js", + "exports": { + ".": "./dist/src/index.js", + "./lite": "./dist/src/index_lite.js", + "./types/standard.js": "./dist/types/standard.js", + "./types/other.js": "./dist/types/other.js", + "./package.json": "./package.json" + }, + "files": [ + "dist/src/*", + "dist/types/*", + "bin/*" + ], + "bin": { + "mime": "bin/cli.js" + }, + "contributors": [], + "description": "A comprehensive library for mime-type mapping", + "license": "MIT", + "devDependencies": { + "@types/mime-db": "1.*", + "@types/mime-types": "2.1.1", + "@types/node": "20.5.9", + "@typescript-eslint/eslint-plugin": "6.6.0", + "@typescript-eslint/parser": "6.6.0", + "chalk": "5.3.0", + "mime-score": "2.0.4", + "mime-types": "2.1.35", + "prettier": "3.0.3", + "runmd": "1.3.9", + "standard-version": "9.5.0", + "typescript": "5.2.2" + }, + "scripts": { + "build": "npm run build:clean && tsc", + "build:clean": "rm -fr dist", + "build:types": "node dist/scripts/build.js", + "build:watch": "npm run build:clean && tsc --watch", + "lint": "prettier -c .", + "lint:fix": "prettier -w .", + "prepublishOnly": "npm run build && npm run build:types && npm test", + "release": "# `standard-version --dry-run --prerelease` is the command you're after", + "test": "node --test && ./test/exports_test.sh", + "test:watch": "clear && node --enable-source-maps --test --watch test" + }, + "keywords": [ + "extension", + "file", + "mime", + "mime-db", + "mimetypes", + "util" + ], + "name": "mime", + "repository": { + "url": "https://github.com/broofa/mime", + "type": "git" + }, + "version": "4.0.1", + "funding": [ + "https://github.com/sponsors/broofa" + ] +} diff --git a/node_modules/mrmime/index.d.ts b/node_modules/mrmime/index.d.ts new file mode 100644 index 0000000..1d9268f --- /dev/null +++ b/node_modules/mrmime/index.d.ts @@ -0,0 +1,2 @@ +export const mimes: Record; +export function lookup(extension: string): string | undefined; diff --git a/node_modules/mrmime/index.js b/node_modules/mrmime/index.js new file mode 100644 index 0000000..197a33b --- /dev/null +++ b/node_modules/mrmime/index.js @@ -0,0 +1,445 @@ +const mimes = { + "3g2": "video/3gpp2", + "3gp": "video/3gpp", + "3gpp": "video/3gpp", + "3mf": "model/3mf", + "aac": "audio/aac", + "ac": "application/pkix-attr-cert", + "adp": "audio/adpcm", + "adts": "audio/aac", + "ai": "application/postscript", + "aml": "application/automationml-aml+xml", + "amlx": "application/automationml-amlx+zip", + "amr": "audio/amr", + "apng": "image/apng", + "appcache": "text/cache-manifest", + "appinstaller": "application/appinstaller", + "appx": "application/appx", + "appxbundle": "application/appxbundle", + "asc": "application/pgp-keys", + "atom": "application/atom+xml", + "atomcat": "application/atomcat+xml", + "atomdeleted": "application/atomdeleted+xml", + "atomsvc": "application/atomsvc+xml", + "au": "audio/basic", + "avci": "image/avci", + "avcs": "image/avcs", + "avif": "image/avif", + "aw": "application/applixware", + "bdoc": "application/bdoc", + "bin": "application/octet-stream", + "bmp": "image/bmp", + "bpk": "application/octet-stream", + "btf": "image/prs.btif", + "btif": "image/prs.btif", + "buffer": "application/octet-stream", + "ccxml": "application/ccxml+xml", + "cdfx": "application/cdfx+xml", + "cdmia": "application/cdmi-capability", + "cdmic": "application/cdmi-container", + "cdmid": "application/cdmi-domain", + "cdmio": "application/cdmi-object", + "cdmiq": "application/cdmi-queue", + "cer": "application/pkix-cert", + "cgm": "image/cgm", + "cjs": "application/node", + "class": "application/java-vm", + "coffee": "text/coffeescript", + "conf": "text/plain", + "cpl": "application/cpl+xml", + "cpt": "application/mac-compactpro", + "crl": "application/pkix-crl", + "css": "text/css", + "csv": "text/csv", + "cu": "application/cu-seeme", + "cwl": "application/cwl", + "cww": "application/prs.cww", + "davmount": "application/davmount+xml", + "dbk": "application/docbook+xml", + "deb": "application/octet-stream", + "def": "text/plain", + "deploy": "application/octet-stream", + "dib": "image/bmp", + "disposition-notification": "message/disposition-notification", + "dist": "application/octet-stream", + "distz": "application/octet-stream", + "dll": "application/octet-stream", + "dmg": "application/octet-stream", + "dms": "application/octet-stream", + "doc": "application/msword", + "dot": "application/msword", + "dpx": "image/dpx", + "drle": "image/dicom-rle", + "dsc": "text/prs.lines.tag", + "dssc": "application/dssc+der", + "dtd": "application/xml-dtd", + "dump": "application/octet-stream", + "dwd": "application/atsc-dwd+xml", + "ear": "application/java-archive", + "ecma": "application/ecmascript", + "elc": "application/octet-stream", + "emf": "image/emf", + "eml": "message/rfc822", + "emma": "application/emma+xml", + "emotionml": "application/emotionml+xml", + "eps": "application/postscript", + "epub": "application/epub+zip", + "exe": "application/octet-stream", + "exi": "application/exi", + "exp": "application/express", + "exr": "image/aces", + "ez": "application/andrew-inset", + "fdf": "application/fdf", + "fdt": "application/fdt+xml", + "fits": "image/fits", + "g3": "image/g3fax", + "gbr": "application/rpki-ghostbusters", + "geojson": "application/geo+json", + "gif": "image/gif", + "glb": "model/gltf-binary", + "gltf": "model/gltf+json", + "gml": "application/gml+xml", + "gpx": "application/gpx+xml", + "gram": "application/srgs", + "grxml": "application/srgs+xml", + "gxf": "application/gxf", + "gz": "application/gzip", + "h261": "video/h261", + "h263": "video/h263", + "h264": "video/h264", + "heic": "image/heic", + "heics": "image/heic-sequence", + "heif": "image/heif", + "heifs": "image/heif-sequence", + "hej2": "image/hej2k", + "held": "application/atsc-held+xml", + "hjson": "application/hjson", + "hlp": "application/winhlp", + "hqx": "application/mac-binhex40", + "hsj2": "image/hsj2", + "htm": "text/html", + "html": "text/html", + "ics": "text/calendar", + "ief": "image/ief", + "ifb": "text/calendar", + "iges": "model/iges", + "igs": "model/iges", + "img": "application/octet-stream", + "in": "text/plain", + "ini": "text/plain", + "ink": "application/inkml+xml", + "inkml": "application/inkml+xml", + "ipfix": "application/ipfix", + "iso": "application/octet-stream", + "its": "application/its+xml", + "jade": "text/jade", + "jar": "application/java-archive", + "jhc": "image/jphc", + "jls": "image/jls", + "jp2": "image/jp2", + "jpe": "image/jpeg", + "jpeg": "image/jpeg", + "jpf": "image/jpx", + "jpg": "image/jpeg", + "jpg2": "image/jp2", + "jpgm": "image/jpm", + "jpgv": "video/jpeg", + "jph": "image/jph", + "jpm": "image/jpm", + "jpx": "image/jpx", + "js": "text/javascript", + "json": "application/json", + "json5": "application/json5", + "jsonld": "application/ld+json", + "jsonml": "application/jsonml+json", + "jsx": "text/jsx", + "jt": "model/jt", + "jxr": "image/jxr", + "jxra": "image/jxra", + "jxrs": "image/jxrs", + "jxs": "image/jxs", + "jxsc": "image/jxsc", + "jxsi": "image/jxsi", + "jxss": "image/jxss", + "kar": "audio/midi", + "ktx": "image/ktx", + "ktx2": "image/ktx2", + "less": "text/less", + "lgr": "application/lgr+xml", + "list": "text/plain", + "litcoffee": "text/coffeescript", + "log": "text/plain", + "lostxml": "application/lost+xml", + "lrf": "application/octet-stream", + "m1v": "video/mpeg", + "m21": "application/mp21", + "m2a": "audio/mpeg", + "m2v": "video/mpeg", + "m3a": "audio/mpeg", + "m4a": "audio/mp4", + "m4p": "application/mp4", + "m4s": "video/iso.segment", + "ma": "application/mathematica", + "mads": "application/mads+xml", + "maei": "application/mmt-aei+xml", + "man": "text/troff", + "manifest": "text/cache-manifest", + "map": "application/json", + "mar": "application/octet-stream", + "markdown": "text/markdown", + "mathml": "application/mathml+xml", + "mb": "application/mathematica", + "mbox": "application/mbox", + "md": "text/markdown", + "mdx": "text/mdx", + "me": "text/troff", + "mesh": "model/mesh", + "meta4": "application/metalink4+xml", + "metalink": "application/metalink+xml", + "mets": "application/mets+xml", + "mft": "application/rpki-manifest", + "mid": "audio/midi", + "midi": "audio/midi", + "mime": "message/rfc822", + "mj2": "video/mj2", + "mjp2": "video/mj2", + "mjs": "text/javascript", + "mml": "text/mathml", + "mods": "application/mods+xml", + "mov": "video/quicktime", + "mp2": "audio/mpeg", + "mp21": "application/mp21", + "mp2a": "audio/mpeg", + "mp3": "audio/mpeg", + "mp4": "video/mp4", + "mp4a": "audio/mp4", + "mp4s": "application/mp4", + "mp4v": "video/mp4", + "mpd": "application/dash+xml", + "mpe": "video/mpeg", + "mpeg": "video/mpeg", + "mpf": "application/media-policy-dataset+xml", + "mpg": "video/mpeg", + "mpg4": "video/mp4", + "mpga": "audio/mpeg", + "mpp": "application/dash-patch+xml", + "mrc": "application/marc", + "mrcx": "application/marcxml+xml", + "ms": "text/troff", + "mscml": "application/mediaservercontrol+xml", + "msh": "model/mesh", + "msi": "application/octet-stream", + "msix": "application/msix", + "msixbundle": "application/msixbundle", + "msm": "application/octet-stream", + "msp": "application/octet-stream", + "mtl": "model/mtl", + "musd": "application/mmt-usd+xml", + "mxf": "application/mxf", + "mxmf": "audio/mobile-xmf", + "mxml": "application/xv+xml", + "n3": "text/n3", + "nb": "application/mathematica", + "nq": "application/n-quads", + "nt": "application/n-triples", + "obj": "model/obj", + "oda": "application/oda", + "oga": "audio/ogg", + "ogg": "audio/ogg", + "ogv": "video/ogg", + "ogx": "application/ogg", + "omdoc": "application/omdoc+xml", + "onepkg": "application/onenote", + "onetmp": "application/onenote", + "onetoc": "application/onenote", + "onetoc2": "application/onenote", + "opf": "application/oebps-package+xml", + "opus": "audio/ogg", + "otf": "font/otf", + "owl": "application/rdf+xml", + "oxps": "application/oxps", + "p10": "application/pkcs10", + "p7c": "application/pkcs7-mime", + "p7m": "application/pkcs7-mime", + "p7s": "application/pkcs7-signature", + "p8": "application/pkcs8", + "pdf": "application/pdf", + "pfr": "application/font-tdpfr", + "pgp": "application/pgp-encrypted", + "pkg": "application/octet-stream", + "pki": "application/pkixcmp", + "pkipath": "application/pkix-pkipath", + "pls": "application/pls+xml", + "png": "image/png", + "prc": "model/prc", + "prf": "application/pics-rules", + "provx": "application/provenance+xml", + "ps": "application/postscript", + "pskcxml": "application/pskc+xml", + "pti": "image/prs.pti", + "qt": "video/quicktime", + "raml": "application/raml+yaml", + "rapd": "application/route-apd+xml", + "rdf": "application/rdf+xml", + "relo": "application/p2p-overlay+xml", + "rif": "application/reginfo+xml", + "rl": "application/resource-lists+xml", + "rld": "application/resource-lists-diff+xml", + "rmi": "audio/midi", + "rnc": "application/relax-ng-compact-syntax", + "rng": "application/xml", + "roa": "application/rpki-roa", + "roff": "text/troff", + "rq": "application/sparql-query", + "rs": "application/rls-services+xml", + "rsat": "application/atsc-rsat+xml", + "rsd": "application/rsd+xml", + "rsheet": "application/urc-ressheet+xml", + "rss": "application/rss+xml", + "rtf": "text/rtf", + "rtx": "text/richtext", + "rusd": "application/route-usd+xml", + "s3m": "audio/s3m", + "sbml": "application/sbml+xml", + "scq": "application/scvp-cv-request", + "scs": "application/scvp-cv-response", + "sdp": "application/sdp", + "senmlx": "application/senml+xml", + "sensmlx": "application/sensml+xml", + "ser": "application/java-serialized-object", + "setpay": "application/set-payment-initiation", + "setreg": "application/set-registration-initiation", + "sgi": "image/sgi", + "sgm": "text/sgml", + "sgml": "text/sgml", + "shex": "text/shex", + "shf": "application/shf+xml", + "shtml": "text/html", + "sieve": "application/sieve", + "sig": "application/pgp-signature", + "sil": "audio/silk", + "silo": "model/mesh", + "siv": "application/sieve", + "slim": "text/slim", + "slm": "text/slim", + "sls": "application/route-s-tsid+xml", + "smi": "application/smil+xml", + "smil": "application/smil+xml", + "snd": "audio/basic", + "so": "application/octet-stream", + "spdx": "text/spdx", + "spp": "application/scvp-vp-response", + "spq": "application/scvp-vp-request", + "spx": "audio/ogg", + "sql": "application/sql", + "sru": "application/sru+xml", + "srx": "application/sparql-results+xml", + "ssdl": "application/ssdl+xml", + "ssml": "application/ssml+xml", + "stk": "application/hyperstudio", + "stl": "model/stl", + "stpx": "model/step+xml", + "stpxz": "model/step-xml+zip", + "stpz": "model/step+zip", + "styl": "text/stylus", + "stylus": "text/stylus", + "svg": "image/svg+xml", + "svgz": "image/svg+xml", + "swidtag": "application/swid+xml", + "t": "text/troff", + "t38": "image/t38", + "td": "application/urc-targetdesc+xml", + "tei": "application/tei+xml", + "teicorpus": "application/tei+xml", + "text": "text/plain", + "tfi": "application/thraud+xml", + "tfx": "image/tiff-fx", + "tif": "image/tiff", + "tiff": "image/tiff", + "toml": "application/toml", + "tr": "text/troff", + "trig": "application/trig", + "ts": "video/mp2t", + "tsd": "application/timestamped-data", + "tsv": "text/tab-separated-values", + "ttc": "font/collection", + "ttf": "font/ttf", + "ttl": "text/turtle", + "ttml": "application/ttml+xml", + "txt": "text/plain", + "u3d": "model/u3d", + "u8dsn": "message/global-delivery-status", + "u8hdr": "message/global-headers", + "u8mdn": "message/global-disposition-notification", + "u8msg": "message/global", + "ubj": "application/ubjson", + "uri": "text/uri-list", + "uris": "text/uri-list", + "urls": "text/uri-list", + "vcard": "text/vcard", + "vrml": "model/vrml", + "vtt": "text/vtt", + "vxml": "application/voicexml+xml", + "war": "application/java-archive", + "wasm": "application/wasm", + "wav": "audio/wav", + "weba": "audio/webm", + "webm": "video/webm", + "webmanifest": "application/manifest+json", + "webp": "image/webp", + "wgsl": "text/wgsl", + "wgt": "application/widget", + "wif": "application/watcherinfo+xml", + "wmf": "image/wmf", + "woff": "font/woff", + "woff2": "font/woff2", + "wrl": "model/vrml", + "wsdl": "application/wsdl+xml", + "wspolicy": "application/wspolicy+xml", + "x3d": "model/x3d+xml", + "x3db": "model/x3d+fastinfoset", + "x3dbz": "model/x3d+binary", + "x3dv": "model/x3d-vrml", + "x3dvz": "model/x3d+vrml", + "x3dz": "model/x3d+xml", + "xaml": "application/xaml+xml", + "xav": "application/xcap-att+xml", + "xca": "application/xcap-caps+xml", + "xcs": "application/calendar+xml", + "xdf": "application/xcap-diff+xml", + "xdssc": "application/dssc+xml", + "xel": "application/xcap-el+xml", + "xenc": "application/xenc+xml", + "xer": "application/patch-ops-error+xml", + "xfdf": "application/xfdf", + "xht": "application/xhtml+xml", + "xhtml": "application/xhtml+xml", + "xhvml": "application/xv+xml", + "xlf": "application/xliff+xml", + "xm": "audio/xm", + "xml": "text/xml", + "xns": "application/xcap-ns+xml", + "xop": "application/xop+xml", + "xpl": "application/xproc+xml", + "xsd": "application/xml", + "xsf": "application/prs.xsf+xml", + "xsl": "application/xml", + "xslt": "application/xml", + "xspf": "application/xspf+xml", + "xvm": "application/xv+xml", + "xvml": "application/xv+xml", + "yaml": "text/yaml", + "yang": "application/yang", + "yin": "application/yin+xml", + "yml": "text/yaml", + "zip": "application/zip" +}; + +function lookup(extn) { + let tmp = ('' + extn).trim().toLowerCase(); + let idx = tmp.lastIndexOf('.'); + return mimes[!~idx ? tmp : tmp.substring(++idx)]; +} + +exports.mimes = mimes; +exports.lookup = lookup; diff --git a/node_modules/mrmime/index.mjs b/node_modules/mrmime/index.mjs new file mode 100644 index 0000000..5c42c4f --- /dev/null +++ b/node_modules/mrmime/index.mjs @@ -0,0 +1,444 @@ +const mimes = { + "3g2": "video/3gpp2", + "3gp": "video/3gpp", + "3gpp": "video/3gpp", + "3mf": "model/3mf", + "aac": "audio/aac", + "ac": "application/pkix-attr-cert", + "adp": "audio/adpcm", + "adts": "audio/aac", + "ai": "application/postscript", + "aml": "application/automationml-aml+xml", + "amlx": "application/automationml-amlx+zip", + "amr": "audio/amr", + "apng": "image/apng", + "appcache": "text/cache-manifest", + "appinstaller": "application/appinstaller", + "appx": "application/appx", + "appxbundle": "application/appxbundle", + "asc": "application/pgp-keys", + "atom": "application/atom+xml", + "atomcat": "application/atomcat+xml", + "atomdeleted": "application/atomdeleted+xml", + "atomsvc": "application/atomsvc+xml", + "au": "audio/basic", + "avci": "image/avci", + "avcs": "image/avcs", + "avif": "image/avif", + "aw": "application/applixware", + "bdoc": "application/bdoc", + "bin": "application/octet-stream", + "bmp": "image/bmp", + "bpk": "application/octet-stream", + "btf": "image/prs.btif", + "btif": "image/prs.btif", + "buffer": "application/octet-stream", + "ccxml": "application/ccxml+xml", + "cdfx": "application/cdfx+xml", + "cdmia": "application/cdmi-capability", + "cdmic": "application/cdmi-container", + "cdmid": "application/cdmi-domain", + "cdmio": "application/cdmi-object", + "cdmiq": "application/cdmi-queue", + "cer": "application/pkix-cert", + "cgm": "image/cgm", + "cjs": "application/node", + "class": "application/java-vm", + "coffee": "text/coffeescript", + "conf": "text/plain", + "cpl": "application/cpl+xml", + "cpt": "application/mac-compactpro", + "crl": "application/pkix-crl", + "css": "text/css", + "csv": "text/csv", + "cu": "application/cu-seeme", + "cwl": "application/cwl", + "cww": "application/prs.cww", + "davmount": "application/davmount+xml", + "dbk": "application/docbook+xml", + "deb": "application/octet-stream", + "def": "text/plain", + "deploy": "application/octet-stream", + "dib": "image/bmp", + "disposition-notification": "message/disposition-notification", + "dist": "application/octet-stream", + "distz": "application/octet-stream", + "dll": "application/octet-stream", + "dmg": "application/octet-stream", + "dms": "application/octet-stream", + "doc": "application/msword", + "dot": "application/msword", + "dpx": "image/dpx", + "drle": "image/dicom-rle", + "dsc": "text/prs.lines.tag", + "dssc": "application/dssc+der", + "dtd": "application/xml-dtd", + "dump": "application/octet-stream", + "dwd": "application/atsc-dwd+xml", + "ear": "application/java-archive", + "ecma": "application/ecmascript", + "elc": "application/octet-stream", + "emf": "image/emf", + "eml": "message/rfc822", + "emma": "application/emma+xml", + "emotionml": "application/emotionml+xml", + "eps": "application/postscript", + "epub": "application/epub+zip", + "exe": "application/octet-stream", + "exi": "application/exi", + "exp": "application/express", + "exr": "image/aces", + "ez": "application/andrew-inset", + "fdf": "application/fdf", + "fdt": "application/fdt+xml", + "fits": "image/fits", + "g3": "image/g3fax", + "gbr": "application/rpki-ghostbusters", + "geojson": "application/geo+json", + "gif": "image/gif", + "glb": "model/gltf-binary", + "gltf": "model/gltf+json", + "gml": "application/gml+xml", + "gpx": "application/gpx+xml", + "gram": "application/srgs", + "grxml": "application/srgs+xml", + "gxf": "application/gxf", + "gz": "application/gzip", + "h261": "video/h261", + "h263": "video/h263", + "h264": "video/h264", + "heic": "image/heic", + "heics": "image/heic-sequence", + "heif": "image/heif", + "heifs": "image/heif-sequence", + "hej2": "image/hej2k", + "held": "application/atsc-held+xml", + "hjson": "application/hjson", + "hlp": "application/winhlp", + "hqx": "application/mac-binhex40", + "hsj2": "image/hsj2", + "htm": "text/html", + "html": "text/html", + "ics": "text/calendar", + "ief": "image/ief", + "ifb": "text/calendar", + "iges": "model/iges", + "igs": "model/iges", + "img": "application/octet-stream", + "in": "text/plain", + "ini": "text/plain", + "ink": "application/inkml+xml", + "inkml": "application/inkml+xml", + "ipfix": "application/ipfix", + "iso": "application/octet-stream", + "its": "application/its+xml", + "jade": "text/jade", + "jar": "application/java-archive", + "jhc": "image/jphc", + "jls": "image/jls", + "jp2": "image/jp2", + "jpe": "image/jpeg", + "jpeg": "image/jpeg", + "jpf": "image/jpx", + "jpg": "image/jpeg", + "jpg2": "image/jp2", + "jpgm": "image/jpm", + "jpgv": "video/jpeg", + "jph": "image/jph", + "jpm": "image/jpm", + "jpx": "image/jpx", + "js": "text/javascript", + "json": "application/json", + "json5": "application/json5", + "jsonld": "application/ld+json", + "jsonml": "application/jsonml+json", + "jsx": "text/jsx", + "jt": "model/jt", + "jxr": "image/jxr", + "jxra": "image/jxra", + "jxrs": "image/jxrs", + "jxs": "image/jxs", + "jxsc": "image/jxsc", + "jxsi": "image/jxsi", + "jxss": "image/jxss", + "kar": "audio/midi", + "ktx": "image/ktx", + "ktx2": "image/ktx2", + "less": "text/less", + "lgr": "application/lgr+xml", + "list": "text/plain", + "litcoffee": "text/coffeescript", + "log": "text/plain", + "lostxml": "application/lost+xml", + "lrf": "application/octet-stream", + "m1v": "video/mpeg", + "m21": "application/mp21", + "m2a": "audio/mpeg", + "m2v": "video/mpeg", + "m3a": "audio/mpeg", + "m4a": "audio/mp4", + "m4p": "application/mp4", + "m4s": "video/iso.segment", + "ma": "application/mathematica", + "mads": "application/mads+xml", + "maei": "application/mmt-aei+xml", + "man": "text/troff", + "manifest": "text/cache-manifest", + "map": "application/json", + "mar": "application/octet-stream", + "markdown": "text/markdown", + "mathml": "application/mathml+xml", + "mb": "application/mathematica", + "mbox": "application/mbox", + "md": "text/markdown", + "mdx": "text/mdx", + "me": "text/troff", + "mesh": "model/mesh", + "meta4": "application/metalink4+xml", + "metalink": "application/metalink+xml", + "mets": "application/mets+xml", + "mft": "application/rpki-manifest", + "mid": "audio/midi", + "midi": "audio/midi", + "mime": "message/rfc822", + "mj2": "video/mj2", + "mjp2": "video/mj2", + "mjs": "text/javascript", + "mml": "text/mathml", + "mods": "application/mods+xml", + "mov": "video/quicktime", + "mp2": "audio/mpeg", + "mp21": "application/mp21", + "mp2a": "audio/mpeg", + "mp3": "audio/mpeg", + "mp4": "video/mp4", + "mp4a": "audio/mp4", + "mp4s": "application/mp4", + "mp4v": "video/mp4", + "mpd": "application/dash+xml", + "mpe": "video/mpeg", + "mpeg": "video/mpeg", + "mpf": "application/media-policy-dataset+xml", + "mpg": "video/mpeg", + "mpg4": "video/mp4", + "mpga": "audio/mpeg", + "mpp": "application/dash-patch+xml", + "mrc": "application/marc", + "mrcx": "application/marcxml+xml", + "ms": "text/troff", + "mscml": "application/mediaservercontrol+xml", + "msh": "model/mesh", + "msi": "application/octet-stream", + "msix": "application/msix", + "msixbundle": "application/msixbundle", + "msm": "application/octet-stream", + "msp": "application/octet-stream", + "mtl": "model/mtl", + "musd": "application/mmt-usd+xml", + "mxf": "application/mxf", + "mxmf": "audio/mobile-xmf", + "mxml": "application/xv+xml", + "n3": "text/n3", + "nb": "application/mathematica", + "nq": "application/n-quads", + "nt": "application/n-triples", + "obj": "model/obj", + "oda": "application/oda", + "oga": "audio/ogg", + "ogg": "audio/ogg", + "ogv": "video/ogg", + "ogx": "application/ogg", + "omdoc": "application/omdoc+xml", + "onepkg": "application/onenote", + "onetmp": "application/onenote", + "onetoc": "application/onenote", + "onetoc2": "application/onenote", + "opf": "application/oebps-package+xml", + "opus": "audio/ogg", + "otf": "font/otf", + "owl": "application/rdf+xml", + "oxps": "application/oxps", + "p10": "application/pkcs10", + "p7c": "application/pkcs7-mime", + "p7m": "application/pkcs7-mime", + "p7s": "application/pkcs7-signature", + "p8": "application/pkcs8", + "pdf": "application/pdf", + "pfr": "application/font-tdpfr", + "pgp": "application/pgp-encrypted", + "pkg": "application/octet-stream", + "pki": "application/pkixcmp", + "pkipath": "application/pkix-pkipath", + "pls": "application/pls+xml", + "png": "image/png", + "prc": "model/prc", + "prf": "application/pics-rules", + "provx": "application/provenance+xml", + "ps": "application/postscript", + "pskcxml": "application/pskc+xml", + "pti": "image/prs.pti", + "qt": "video/quicktime", + "raml": "application/raml+yaml", + "rapd": "application/route-apd+xml", + "rdf": "application/rdf+xml", + "relo": "application/p2p-overlay+xml", + "rif": "application/reginfo+xml", + "rl": "application/resource-lists+xml", + "rld": "application/resource-lists-diff+xml", + "rmi": "audio/midi", + "rnc": "application/relax-ng-compact-syntax", + "rng": "application/xml", + "roa": "application/rpki-roa", + "roff": "text/troff", + "rq": "application/sparql-query", + "rs": "application/rls-services+xml", + "rsat": "application/atsc-rsat+xml", + "rsd": "application/rsd+xml", + "rsheet": "application/urc-ressheet+xml", + "rss": "application/rss+xml", + "rtf": "text/rtf", + "rtx": "text/richtext", + "rusd": "application/route-usd+xml", + "s3m": "audio/s3m", + "sbml": "application/sbml+xml", + "scq": "application/scvp-cv-request", + "scs": "application/scvp-cv-response", + "sdp": "application/sdp", + "senmlx": "application/senml+xml", + "sensmlx": "application/sensml+xml", + "ser": "application/java-serialized-object", + "setpay": "application/set-payment-initiation", + "setreg": "application/set-registration-initiation", + "sgi": "image/sgi", + "sgm": "text/sgml", + "sgml": "text/sgml", + "shex": "text/shex", + "shf": "application/shf+xml", + "shtml": "text/html", + "sieve": "application/sieve", + "sig": "application/pgp-signature", + "sil": "audio/silk", + "silo": "model/mesh", + "siv": "application/sieve", + "slim": "text/slim", + "slm": "text/slim", + "sls": "application/route-s-tsid+xml", + "smi": "application/smil+xml", + "smil": "application/smil+xml", + "snd": "audio/basic", + "so": "application/octet-stream", + "spdx": "text/spdx", + "spp": "application/scvp-vp-response", + "spq": "application/scvp-vp-request", + "spx": "audio/ogg", + "sql": "application/sql", + "sru": "application/sru+xml", + "srx": "application/sparql-results+xml", + "ssdl": "application/ssdl+xml", + "ssml": "application/ssml+xml", + "stk": "application/hyperstudio", + "stl": "model/stl", + "stpx": "model/step+xml", + "stpxz": "model/step-xml+zip", + "stpz": "model/step+zip", + "styl": "text/stylus", + "stylus": "text/stylus", + "svg": "image/svg+xml", + "svgz": "image/svg+xml", + "swidtag": "application/swid+xml", + "t": "text/troff", + "t38": "image/t38", + "td": "application/urc-targetdesc+xml", + "tei": "application/tei+xml", + "teicorpus": "application/tei+xml", + "text": "text/plain", + "tfi": "application/thraud+xml", + "tfx": "image/tiff-fx", + "tif": "image/tiff", + "tiff": "image/tiff", + "toml": "application/toml", + "tr": "text/troff", + "trig": "application/trig", + "ts": "video/mp2t", + "tsd": "application/timestamped-data", + "tsv": "text/tab-separated-values", + "ttc": "font/collection", + "ttf": "font/ttf", + "ttl": "text/turtle", + "ttml": "application/ttml+xml", + "txt": "text/plain", + "u3d": "model/u3d", + "u8dsn": "message/global-delivery-status", + "u8hdr": "message/global-headers", + "u8mdn": "message/global-disposition-notification", + "u8msg": "message/global", + "ubj": "application/ubjson", + "uri": "text/uri-list", + "uris": "text/uri-list", + "urls": "text/uri-list", + "vcard": "text/vcard", + "vrml": "model/vrml", + "vtt": "text/vtt", + "vxml": "application/voicexml+xml", + "war": "application/java-archive", + "wasm": "application/wasm", + "wav": "audio/wav", + "weba": "audio/webm", + "webm": "video/webm", + "webmanifest": "application/manifest+json", + "webp": "image/webp", + "wgsl": "text/wgsl", + "wgt": "application/widget", + "wif": "application/watcherinfo+xml", + "wmf": "image/wmf", + "woff": "font/woff", + "woff2": "font/woff2", + "wrl": "model/vrml", + "wsdl": "application/wsdl+xml", + "wspolicy": "application/wspolicy+xml", + "x3d": "model/x3d+xml", + "x3db": "model/x3d+fastinfoset", + "x3dbz": "model/x3d+binary", + "x3dv": "model/x3d-vrml", + "x3dvz": "model/x3d+vrml", + "x3dz": "model/x3d+xml", + "xaml": "application/xaml+xml", + "xav": "application/xcap-att+xml", + "xca": "application/xcap-caps+xml", + "xcs": "application/calendar+xml", + "xdf": "application/xcap-diff+xml", + "xdssc": "application/dssc+xml", + "xel": "application/xcap-el+xml", + "xenc": "application/xenc+xml", + "xer": "application/patch-ops-error+xml", + "xfdf": "application/xfdf", + "xht": "application/xhtml+xml", + "xhtml": "application/xhtml+xml", + "xhvml": "application/xv+xml", + "xlf": "application/xliff+xml", + "xm": "audio/xm", + "xml": "text/xml", + "xns": "application/xcap-ns+xml", + "xop": "application/xop+xml", + "xpl": "application/xproc+xml", + "xsd": "application/xml", + "xsf": "application/prs.xsf+xml", + "xsl": "application/xml", + "xslt": "application/xml", + "xspf": "application/xspf+xml", + "xvm": "application/xv+xml", + "xvml": "application/xv+xml", + "yaml": "text/yaml", + "yang": "application/yang", + "yin": "application/yin+xml", + "yml": "text/yaml", + "zip": "application/zip" +}; + +function lookup(extn) { + let tmp = ('' + extn).trim().toLowerCase(); + let idx = tmp.lastIndexOf('.'); + return mimes[!~idx ? tmp : tmp.substring(++idx)]; +} + +export { mimes, lookup }; diff --git a/node_modules/mrmime/license b/node_modules/mrmime/license new file mode 100644 index 0000000..d46889a --- /dev/null +++ b/node_modules/mrmime/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Luke Edwards (https://lukeed.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/mrmime/package.json b/node_modules/mrmime/package.json new file mode 100644 index 0000000..6ec2d23 --- /dev/null +++ b/node_modules/mrmime/package.json @@ -0,0 +1,44 @@ +{ + "name": "mrmime", + "version": "2.0.0", + "repository": "lukeed/mrmime", + "description": "A tiny (2.8kB) and fast utility for getting a MIME type from an extension or filename", + "module": "index.mjs", + "types": "index.d.ts", + "main": "index.js", + "license": "MIT", + "author": { + "name": "Luke Edwards", + "email": "luke.edwards05@gmail.com", + "url": "https://lukeed.com" + }, + "exports": { + ".": { + "types": "./index.d.ts", + "import": "./index.mjs", + "require": "./index.js" + }, + "./package.json": "./package.json" + }, + "files": [ + "index.d.ts", + "index.mjs", + "index.js" + ], + "engines": { + "node": ">=10" + }, + "scripts": { + "build": "tsm bin/index.ts", + "test": "uvu -r tsm test" + }, + "keywords": [ + "mime", + "extension", + "mimetype" + ], + "devDependencies": { + "tsm": "2.3.0", + "uvu": "0.5.2" + } +} diff --git a/node_modules/mrmime/readme.md b/node_modules/mrmime/readme.md new file mode 100644 index 0000000..3c3ab1b --- /dev/null +++ b/node_modules/mrmime/readme.md @@ -0,0 +1,127 @@ +
+ mrmime +
+ + + +
+ A tiny (2.8kB) and fast utility for getting a MIME type from an extension or filename +
+ + +## Features + +* Lightweight – 2.8kB gzip
+ _Only includes standard mime types; all experimental and vendor-specific mimetypes removed._ + +* [Performant](#benchmarks)
+ _All lookups are O(1) with minimal processing._ + +* Comprehensive Dictionary
+ _Generated from [`mime-db`](https://github.com/jshttp/mime-db), which aggregates the IANA, NGINX, and Apache datasets._ + +* Customizable
+ _Exposes the `mimes` dictionary for easy additions or overrides._ + +* Supports Native ESM and [Deno](https://deno.land/x/mrmime)
+ _Ships with CommonJS and ESM support!_ + + +## Install + +``` +$ npm install --save mrmime +``` + + +## Usage + +```js +import { lookup, mimes } from 'mrmime'; + +// Get a MIME type +// --- +lookup('txt'); //=> "text/plain" +lookup('.txt'); //=> "text/plain" +lookup('a.txt'); //=> "text/plain" + +// Unknown extension +// --- +lookup('.xyz'); //=> undefined + +// Add extension to dictionary +// --- +mimes['xyz'] = 'hello/world'; +lookup('xyz'); //=> "hello/world" +``` + + +## API + +### lookup(input) +Returns: `string` or `undefined` + +#### input +Type: `string` + +The extension or filename to lookup. + +> **Important:** +> * Any `input` value is cast to string, lowercased, and trimmed. +> * If a filename or filepath is provided, only the extension will be used. + + +## Benchmarks + +> Running on Node v16.8.0 + +``` +Load times: + mrmime 0.963ms + mime/lite 3.281ms + mime 6.751ms + +Benchmark :: plain ("ext") + mime x 598,849 ops/sec ±0.28% (94 runs sampled) + mime/lite x 536,643 ops/sec ±0.11% (97 runs sampled) + mrmime x 835,885 ops/sec ±0.20% (97 runs sampled) + +Benchmark :: leading (".ext") + mime x 368,656 ops/sec ±0.19% (99 runs sampled) + mime/lite x 368,318 ops/sec ±0.13% (97 runs sampled) + mrmime x 533,643 ops/sec ±0.10% (96 runs sampled) + +Benchmark :: filename ("file.ext") + mime x 326,907 ops/sec ±0.17% (95 runs sampled) + mime/lite x 327,479 ops/sec ±0.12% (98 runs sampled) + mrmime x 512,823 ops/sec ±0.12% (99 runs sampled) +``` + + +## Credits + +Of course, a thank-you to [`mime`](https://github.com/broofa/mime) serving the community all these years & for being a all-encompassing MIME type library. I've only ever needed lookup/`getType` functionality – and now ESM support – so `mrmime` can only ever support 1/3 of what `mime` offers, at best. + +This would not be possible without the team behind [`mime-db`](https://github.com/jshttp/mime-db), who have painstakingly maintained an amazing database for 7+ years. + +Artwork created by [mintinol](https://www.deviantart.com/mintinol), which I found [here](https://www.deviantart.com/mintinol/art/Mr-Mime-373927920). + +Finally, thanks to [Tim Branyen](https://github.com/tbranyen) for donating the package name :) + + +## License + +MIT © [Luke Edwards](https://lukeed.com) diff --git a/node_modules/negotiator/HISTORY.md b/node_modules/negotiator/HISTORY.md new file mode 100644 index 0000000..a9a5449 --- /dev/null +++ b/node_modules/negotiator/HISTORY.md @@ -0,0 +1,108 @@ +0.6.3 / 2022-01-22 +================== + + * Revert "Lazy-load modules from main entry point" + +0.6.2 / 2019-04-29 +================== + + * Fix sorting charset, encoding, and language with extra parameters + +0.6.1 / 2016-05-02 +================== + + * perf: improve `Accept` parsing speed + * perf: improve `Accept-Charset` parsing speed + * perf: improve `Accept-Encoding` parsing speed + * perf: improve `Accept-Language` parsing speed + +0.6.0 / 2015-09-29 +================== + + * Fix including type extensions in parameters in `Accept` parsing + * Fix parsing `Accept` parameters with quoted equals + * Fix parsing `Accept` parameters with quoted semicolons + * Lazy-load modules from main entry point + * perf: delay type concatenation until needed + * perf: enable strict mode + * perf: hoist regular expressions + * perf: remove closures getting spec properties + * perf: remove a closure from media type parsing + * perf: remove property delete from media type parsing + +0.5.3 / 2015-05-10 +================== + + * Fix media type parameter matching to be case-insensitive + +0.5.2 / 2015-05-06 +================== + + * Fix comparing media types with quoted values + * Fix splitting media types with quoted commas + +0.5.1 / 2015-02-14 +================== + + * Fix preference sorting to be stable for long acceptable lists + +0.5.0 / 2014-12-18 +================== + + * Fix list return order when large accepted list + * Fix missing identity encoding when q=0 exists + * Remove dynamic building of Negotiator class + +0.4.9 / 2014-10-14 +================== + + * Fix error when media type has invalid parameter + +0.4.8 / 2014-09-28 +================== + + * Fix all negotiations to be case-insensitive + * Stable sort preferences of same quality according to client order + * Support Node.js 0.6 + +0.4.7 / 2014-06-24 +================== + + * Handle invalid provided languages + * Handle invalid provided media types + +0.4.6 / 2014-06-11 +================== + + * Order by specificity when quality is the same + +0.4.5 / 2014-05-29 +================== + + * Fix regression in empty header handling + +0.4.4 / 2014-05-29 +================== + + * Fix behaviors when headers are not present + +0.4.3 / 2014-04-16 +================== + + * Handle slashes on media params correctly + +0.4.2 / 2014-02-28 +================== + + * Fix media type sorting + * Handle media types params strictly + +0.4.1 / 2014-01-16 +================== + + * Use most specific matches + +0.4.0 / 2014-01-09 +================== + + * Remove preferred prefix from methods diff --git a/node_modules/negotiator/LICENSE b/node_modules/negotiator/LICENSE new file mode 100644 index 0000000..ea6b9e2 --- /dev/null +++ b/node_modules/negotiator/LICENSE @@ -0,0 +1,24 @@ +(The MIT License) + +Copyright (c) 2012-2014 Federico Romero +Copyright (c) 2012-2014 Isaac Z. Schlueter +Copyright (c) 2014-2015 Douglas Christopher Wilson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/negotiator/README.md b/node_modules/negotiator/README.md new file mode 100644 index 0000000..82915e5 --- /dev/null +++ b/node_modules/negotiator/README.md @@ -0,0 +1,203 @@ +# negotiator + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Node.js Version][node-version-image]][node-version-url] +[![Build Status][github-actions-ci-image]][github-actions-ci-url] +[![Test Coverage][coveralls-image]][coveralls-url] + +An HTTP content negotiator for Node.js + +## Installation + +```sh +$ npm install negotiator +``` + +## API + +```js +var Negotiator = require('negotiator') +``` + +### Accept Negotiation + +```js +availableMediaTypes = ['text/html', 'text/plain', 'application/json'] + +// The negotiator constructor receives a request object +negotiator = new Negotiator(request) + +// Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8' + +negotiator.mediaTypes() +// -> ['text/html', 'image/jpeg', 'application/*'] + +negotiator.mediaTypes(availableMediaTypes) +// -> ['text/html', 'application/json'] + +negotiator.mediaType(availableMediaTypes) +// -> 'text/html' +``` + +You can check a working example at `examples/accept.js`. + +#### Methods + +##### mediaType() + +Returns the most preferred media type from the client. + +##### mediaType(availableMediaType) + +Returns the most preferred media type from a list of available media types. + +##### mediaTypes() + +Returns an array of preferred media types ordered by the client preference. + +##### mediaTypes(availableMediaTypes) + +Returns an array of preferred media types ordered by priority from a list of +available media types. + +### Accept-Language Negotiation + +```js +negotiator = new Negotiator(request) + +availableLanguages = ['en', 'es', 'fr'] + +// Let's say Accept-Language header is 'en;q=0.8, es, pt' + +negotiator.languages() +// -> ['es', 'pt', 'en'] + +negotiator.languages(availableLanguages) +// -> ['es', 'en'] + +language = negotiator.language(availableLanguages) +// -> 'es' +``` + +You can check a working example at `examples/language.js`. + +#### Methods + +##### language() + +Returns the most preferred language from the client. + +##### language(availableLanguages) + +Returns the most preferred language from a list of available languages. + +##### languages() + +Returns an array of preferred languages ordered by the client preference. + +##### languages(availableLanguages) + +Returns an array of preferred languages ordered by priority from a list of +available languages. + +### Accept-Charset Negotiation + +```js +availableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5'] + +negotiator = new Negotiator(request) + +// Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2' + +negotiator.charsets() +// -> ['utf-8', 'iso-8859-1', 'utf-7'] + +negotiator.charsets(availableCharsets) +// -> ['utf-8', 'iso-8859-1'] + +negotiator.charset(availableCharsets) +// -> 'utf-8' +``` + +You can check a working example at `examples/charset.js`. + +#### Methods + +##### charset() + +Returns the most preferred charset from the client. + +##### charset(availableCharsets) + +Returns the most preferred charset from a list of available charsets. + +##### charsets() + +Returns an array of preferred charsets ordered by the client preference. + +##### charsets(availableCharsets) + +Returns an array of preferred charsets ordered by priority from a list of +available charsets. + +### Accept-Encoding Negotiation + +```js +availableEncodings = ['identity', 'gzip'] + +negotiator = new Negotiator(request) + +// Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5' + +negotiator.encodings() +// -> ['gzip', 'identity', 'compress'] + +negotiator.encodings(availableEncodings) +// -> ['gzip', 'identity'] + +negotiator.encoding(availableEncodings) +// -> 'gzip' +``` + +You can check a working example at `examples/encoding.js`. + +#### Methods + +##### encoding() + +Returns the most preferred encoding from the client. + +##### encoding(availableEncodings) + +Returns the most preferred encoding from a list of available encodings. + +##### encodings() + +Returns an array of preferred encodings ordered by the client preference. + +##### encodings(availableEncodings) + +Returns an array of preferred encodings ordered by priority from a list of +available encodings. + +## See Also + +The [accepts](https://npmjs.org/package/accepts#readme) module builds on +this module and provides an alternative interface, mime type validation, +and more. + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/negotiator.svg +[npm-url]: https://npmjs.org/package/negotiator +[node-version-image]: https://img.shields.io/node/v/negotiator.svg +[node-version-url]: https://nodejs.org/en/download/ +[coveralls-image]: https://img.shields.io/coveralls/jshttp/negotiator/master.svg +[coveralls-url]: https://coveralls.io/r/jshttp/negotiator?branch=master +[downloads-image]: https://img.shields.io/npm/dm/negotiator.svg +[downloads-url]: https://npmjs.org/package/negotiator +[github-actions-ci-image]: https://img.shields.io/github/workflow/status/jshttp/negotiator/ci/master?label=ci +[github-actions-ci-url]: https://github.com/jshttp/negotiator/actions/workflows/ci.yml diff --git a/node_modules/negotiator/index.js b/node_modules/negotiator/index.js new file mode 100644 index 0000000..4788264 --- /dev/null +++ b/node_modules/negotiator/index.js @@ -0,0 +1,82 @@ +/*! + * negotiator + * Copyright(c) 2012 Federico Romero + * Copyright(c) 2012-2014 Isaac Z. Schlueter + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict'; + +var preferredCharsets = require('./lib/charset') +var preferredEncodings = require('./lib/encoding') +var preferredLanguages = require('./lib/language') +var preferredMediaTypes = require('./lib/mediaType') + +/** + * Module exports. + * @public + */ + +module.exports = Negotiator; +module.exports.Negotiator = Negotiator; + +/** + * Create a Negotiator instance from a request. + * @param {object} request + * @public + */ + +function Negotiator(request) { + if (!(this instanceof Negotiator)) { + return new Negotiator(request); + } + + this.request = request; +} + +Negotiator.prototype.charset = function charset(available) { + var set = this.charsets(available); + return set && set[0]; +}; + +Negotiator.prototype.charsets = function charsets(available) { + return preferredCharsets(this.request.headers['accept-charset'], available); +}; + +Negotiator.prototype.encoding = function encoding(available) { + var set = this.encodings(available); + return set && set[0]; +}; + +Negotiator.prototype.encodings = function encodings(available) { + return preferredEncodings(this.request.headers['accept-encoding'], available); +}; + +Negotiator.prototype.language = function language(available) { + var set = this.languages(available); + return set && set[0]; +}; + +Negotiator.prototype.languages = function languages(available) { + return preferredLanguages(this.request.headers['accept-language'], available); +}; + +Negotiator.prototype.mediaType = function mediaType(available) { + var set = this.mediaTypes(available); + return set && set[0]; +}; + +Negotiator.prototype.mediaTypes = function mediaTypes(available) { + return preferredMediaTypes(this.request.headers.accept, available); +}; + +// Backwards compatibility +Negotiator.prototype.preferredCharset = Negotiator.prototype.charset; +Negotiator.prototype.preferredCharsets = Negotiator.prototype.charsets; +Negotiator.prototype.preferredEncoding = Negotiator.prototype.encoding; +Negotiator.prototype.preferredEncodings = Negotiator.prototype.encodings; +Negotiator.prototype.preferredLanguage = Negotiator.prototype.language; +Negotiator.prototype.preferredLanguages = Negotiator.prototype.languages; +Negotiator.prototype.preferredMediaType = Negotiator.prototype.mediaType; +Negotiator.prototype.preferredMediaTypes = Negotiator.prototype.mediaTypes; diff --git a/node_modules/negotiator/lib/charset.js b/node_modules/negotiator/lib/charset.js new file mode 100644 index 0000000..cdd0148 --- /dev/null +++ b/node_modules/negotiator/lib/charset.js @@ -0,0 +1,169 @@ +/** + * negotiator + * Copyright(c) 2012 Isaac Z. Schlueter + * Copyright(c) 2014 Federico Romero + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict'; + +/** + * Module exports. + * @public + */ + +module.exports = preferredCharsets; +module.exports.preferredCharsets = preferredCharsets; + +/** + * Module variables. + * @private + */ + +var simpleCharsetRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/; + +/** + * Parse the Accept-Charset header. + * @private + */ + +function parseAcceptCharset(accept) { + var accepts = accept.split(','); + + for (var i = 0, j = 0; i < accepts.length; i++) { + var charset = parseCharset(accepts[i].trim(), i); + + if (charset) { + accepts[j++] = charset; + } + } + + // trim accepts + accepts.length = j; + + return accepts; +} + +/** + * Parse a charset from the Accept-Charset header. + * @private + */ + +function parseCharset(str, i) { + var match = simpleCharsetRegExp.exec(str); + if (!match) return null; + + var charset = match[1]; + var q = 1; + if (match[2]) { + var params = match[2].split(';') + for (var j = 0; j < params.length; j++) { + var p = params[j].trim().split('='); + if (p[0] === 'q') { + q = parseFloat(p[1]); + break; + } + } + } + + return { + charset: charset, + q: q, + i: i + }; +} + +/** + * Get the priority of a charset. + * @private + */ + +function getCharsetPriority(charset, accepted, index) { + var priority = {o: -1, q: 0, s: 0}; + + for (var i = 0; i < accepted.length; i++) { + var spec = specify(charset, accepted[i], index); + + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + + return priority; +} + +/** + * Get the specificity of the charset. + * @private + */ + +function specify(charset, spec, index) { + var s = 0; + if(spec.charset.toLowerCase() === charset.toLowerCase()){ + s |= 1; + } else if (spec.charset !== '*' ) { + return null + } + + return { + i: index, + o: spec.i, + q: spec.q, + s: s + } +} + +/** + * Get the preferred charsets from an Accept-Charset header. + * @public + */ + +function preferredCharsets(accept, provided) { + // RFC 2616 sec 14.2: no header = * + var accepts = parseAcceptCharset(accept === undefined ? '*' : accept || ''); + + if (!provided) { + // sorted list of all charsets + return accepts + .filter(isQuality) + .sort(compareSpecs) + .map(getFullCharset); + } + + var priorities = provided.map(function getPriority(type, index) { + return getCharsetPriority(type, accepts, index); + }); + + // sorted list of accepted charsets + return priorities.filter(isQuality).sort(compareSpecs).map(function getCharset(priority) { + return provided[priorities.indexOf(priority)]; + }); +} + +/** + * Compare two specs. + * @private + */ + +function compareSpecs(a, b) { + return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0; +} + +/** + * Get full charset string. + * @private + */ + +function getFullCharset(spec) { + return spec.charset; +} + +/** + * Check if a spec has any quality. + * @private + */ + +function isQuality(spec) { + return spec.q > 0; +} diff --git a/node_modules/negotiator/lib/encoding.js b/node_modules/negotiator/lib/encoding.js new file mode 100644 index 0000000..8432cd7 --- /dev/null +++ b/node_modules/negotiator/lib/encoding.js @@ -0,0 +1,184 @@ +/** + * negotiator + * Copyright(c) 2012 Isaac Z. Schlueter + * Copyright(c) 2014 Federico Romero + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict'; + +/** + * Module exports. + * @public + */ + +module.exports = preferredEncodings; +module.exports.preferredEncodings = preferredEncodings; + +/** + * Module variables. + * @private + */ + +var simpleEncodingRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/; + +/** + * Parse the Accept-Encoding header. + * @private + */ + +function parseAcceptEncoding(accept) { + var accepts = accept.split(','); + var hasIdentity = false; + var minQuality = 1; + + for (var i = 0, j = 0; i < accepts.length; i++) { + var encoding = parseEncoding(accepts[i].trim(), i); + + if (encoding) { + accepts[j++] = encoding; + hasIdentity = hasIdentity || specify('identity', encoding); + minQuality = Math.min(minQuality, encoding.q || 1); + } + } + + if (!hasIdentity) { + /* + * If identity doesn't explicitly appear in the accept-encoding header, + * it's added to the list of acceptable encoding with the lowest q + */ + accepts[j++] = { + encoding: 'identity', + q: minQuality, + i: i + }; + } + + // trim accepts + accepts.length = j; + + return accepts; +} + +/** + * Parse an encoding from the Accept-Encoding header. + * @private + */ + +function parseEncoding(str, i) { + var match = simpleEncodingRegExp.exec(str); + if (!match) return null; + + var encoding = match[1]; + var q = 1; + if (match[2]) { + var params = match[2].split(';'); + for (var j = 0; j < params.length; j++) { + var p = params[j].trim().split('='); + if (p[0] === 'q') { + q = parseFloat(p[1]); + break; + } + } + } + + return { + encoding: encoding, + q: q, + i: i + }; +} + +/** + * Get the priority of an encoding. + * @private + */ + +function getEncodingPriority(encoding, accepted, index) { + var priority = {o: -1, q: 0, s: 0}; + + for (var i = 0; i < accepted.length; i++) { + var spec = specify(encoding, accepted[i], index); + + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + + return priority; +} + +/** + * Get the specificity of the encoding. + * @private + */ + +function specify(encoding, spec, index) { + var s = 0; + if(spec.encoding.toLowerCase() === encoding.toLowerCase()){ + s |= 1; + } else if (spec.encoding !== '*' ) { + return null + } + + return { + i: index, + o: spec.i, + q: spec.q, + s: s + } +}; + +/** + * Get the preferred encodings from an Accept-Encoding header. + * @public + */ + +function preferredEncodings(accept, provided) { + var accepts = parseAcceptEncoding(accept || ''); + + if (!provided) { + // sorted list of all encodings + return accepts + .filter(isQuality) + .sort(compareSpecs) + .map(getFullEncoding); + } + + var priorities = provided.map(function getPriority(type, index) { + return getEncodingPriority(type, accepts, index); + }); + + // sorted list of accepted encodings + return priorities.filter(isQuality).sort(compareSpecs).map(function getEncoding(priority) { + return provided[priorities.indexOf(priority)]; + }); +} + +/** + * Compare two specs. + * @private + */ + +function compareSpecs(a, b) { + return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0; +} + +/** + * Get full encoding string. + * @private + */ + +function getFullEncoding(spec) { + return spec.encoding; +} + +/** + * Check if a spec has any quality. + * @private + */ + +function isQuality(spec) { + return spec.q > 0; +} diff --git a/node_modules/negotiator/lib/language.js b/node_modules/negotiator/lib/language.js new file mode 100644 index 0000000..a231672 --- /dev/null +++ b/node_modules/negotiator/lib/language.js @@ -0,0 +1,179 @@ +/** + * negotiator + * Copyright(c) 2012 Isaac Z. Schlueter + * Copyright(c) 2014 Federico Romero + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict'; + +/** + * Module exports. + * @public + */ + +module.exports = preferredLanguages; +module.exports.preferredLanguages = preferredLanguages; + +/** + * Module variables. + * @private + */ + +var simpleLanguageRegExp = /^\s*([^\s\-;]+)(?:-([^\s;]+))?\s*(?:;(.*))?$/; + +/** + * Parse the Accept-Language header. + * @private + */ + +function parseAcceptLanguage(accept) { + var accepts = accept.split(','); + + for (var i = 0, j = 0; i < accepts.length; i++) { + var language = parseLanguage(accepts[i].trim(), i); + + if (language) { + accepts[j++] = language; + } + } + + // trim accepts + accepts.length = j; + + return accepts; +} + +/** + * Parse a language from the Accept-Language header. + * @private + */ + +function parseLanguage(str, i) { + var match = simpleLanguageRegExp.exec(str); + if (!match) return null; + + var prefix = match[1] + var suffix = match[2] + var full = prefix + + if (suffix) full += "-" + suffix; + + var q = 1; + if (match[3]) { + var params = match[3].split(';') + for (var j = 0; j < params.length; j++) { + var p = params[j].split('='); + if (p[0] === 'q') q = parseFloat(p[1]); + } + } + + return { + prefix: prefix, + suffix: suffix, + q: q, + i: i, + full: full + }; +} + +/** + * Get the priority of a language. + * @private + */ + +function getLanguagePriority(language, accepted, index) { + var priority = {o: -1, q: 0, s: 0}; + + for (var i = 0; i < accepted.length; i++) { + var spec = specify(language, accepted[i], index); + + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + + return priority; +} + +/** + * Get the specificity of the language. + * @private + */ + +function specify(language, spec, index) { + var p = parseLanguage(language) + if (!p) return null; + var s = 0; + if(spec.full.toLowerCase() === p.full.toLowerCase()){ + s |= 4; + } else if (spec.prefix.toLowerCase() === p.full.toLowerCase()) { + s |= 2; + } else if (spec.full.toLowerCase() === p.prefix.toLowerCase()) { + s |= 1; + } else if (spec.full !== '*' ) { + return null + } + + return { + i: index, + o: spec.i, + q: spec.q, + s: s + } +}; + +/** + * Get the preferred languages from an Accept-Language header. + * @public + */ + +function preferredLanguages(accept, provided) { + // RFC 2616 sec 14.4: no header = * + var accepts = parseAcceptLanguage(accept === undefined ? '*' : accept || ''); + + if (!provided) { + // sorted list of all languages + return accepts + .filter(isQuality) + .sort(compareSpecs) + .map(getFullLanguage); + } + + var priorities = provided.map(function getPriority(type, index) { + return getLanguagePriority(type, accepts, index); + }); + + // sorted list of accepted languages + return priorities.filter(isQuality).sort(compareSpecs).map(function getLanguage(priority) { + return provided[priorities.indexOf(priority)]; + }); +} + +/** + * Compare two specs. + * @private + */ + +function compareSpecs(a, b) { + return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0; +} + +/** + * Get full language string. + * @private + */ + +function getFullLanguage(spec) { + return spec.full; +} + +/** + * Check if a spec has any quality. + * @private + */ + +function isQuality(spec) { + return spec.q > 0; +} diff --git a/node_modules/negotiator/lib/mediaType.js b/node_modules/negotiator/lib/mediaType.js new file mode 100644 index 0000000..67309dd --- /dev/null +++ b/node_modules/negotiator/lib/mediaType.js @@ -0,0 +1,294 @@ +/** + * negotiator + * Copyright(c) 2012 Isaac Z. Schlueter + * Copyright(c) 2014 Federico Romero + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict'; + +/** + * Module exports. + * @public + */ + +module.exports = preferredMediaTypes; +module.exports.preferredMediaTypes = preferredMediaTypes; + +/** + * Module variables. + * @private + */ + +var simpleMediaTypeRegExp = /^\s*([^\s\/;]+)\/([^;\s]+)\s*(?:;(.*))?$/; + +/** + * Parse the Accept header. + * @private + */ + +function parseAccept(accept) { + var accepts = splitMediaTypes(accept); + + for (var i = 0, j = 0; i < accepts.length; i++) { + var mediaType = parseMediaType(accepts[i].trim(), i); + + if (mediaType) { + accepts[j++] = mediaType; + } + } + + // trim accepts + accepts.length = j; + + return accepts; +} + +/** + * Parse a media type from the Accept header. + * @private + */ + +function parseMediaType(str, i) { + var match = simpleMediaTypeRegExp.exec(str); + if (!match) return null; + + var params = Object.create(null); + var q = 1; + var subtype = match[2]; + var type = match[1]; + + if (match[3]) { + var kvps = splitParameters(match[3]).map(splitKeyValuePair); + + for (var j = 0; j < kvps.length; j++) { + var pair = kvps[j]; + var key = pair[0].toLowerCase(); + var val = pair[1]; + + // get the value, unwrapping quotes + var value = val && val[0] === '"' && val[val.length - 1] === '"' + ? val.substr(1, val.length - 2) + : val; + + if (key === 'q') { + q = parseFloat(value); + break; + } + + // store parameter + params[key] = value; + } + } + + return { + type: type, + subtype: subtype, + params: params, + q: q, + i: i + }; +} + +/** + * Get the priority of a media type. + * @private + */ + +function getMediaTypePriority(type, accepted, index) { + var priority = {o: -1, q: 0, s: 0}; + + for (var i = 0; i < accepted.length; i++) { + var spec = specify(type, accepted[i], index); + + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + + return priority; +} + +/** + * Get the specificity of the media type. + * @private + */ + +function specify(type, spec, index) { + var p = parseMediaType(type); + var s = 0; + + if (!p) { + return null; + } + + if(spec.type.toLowerCase() == p.type.toLowerCase()) { + s |= 4 + } else if(spec.type != '*') { + return null; + } + + if(spec.subtype.toLowerCase() == p.subtype.toLowerCase()) { + s |= 2 + } else if(spec.subtype != '*') { + return null; + } + + var keys = Object.keys(spec.params); + if (keys.length > 0) { + if (keys.every(function (k) { + return spec.params[k] == '*' || (spec.params[k] || '').toLowerCase() == (p.params[k] || '').toLowerCase(); + })) { + s |= 1 + } else { + return null + } + } + + return { + i: index, + o: spec.i, + q: spec.q, + s: s, + } +} + +/** + * Get the preferred media types from an Accept header. + * @public + */ + +function preferredMediaTypes(accept, provided) { + // RFC 2616 sec 14.2: no header = */* + var accepts = parseAccept(accept === undefined ? '*/*' : accept || ''); + + if (!provided) { + // sorted list of all types + return accepts + .filter(isQuality) + .sort(compareSpecs) + .map(getFullType); + } + + var priorities = provided.map(function getPriority(type, index) { + return getMediaTypePriority(type, accepts, index); + }); + + // sorted list of accepted types + return priorities.filter(isQuality).sort(compareSpecs).map(function getType(priority) { + return provided[priorities.indexOf(priority)]; + }); +} + +/** + * Compare two specs. + * @private + */ + +function compareSpecs(a, b) { + return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0; +} + +/** + * Get full type string. + * @private + */ + +function getFullType(spec) { + return spec.type + '/' + spec.subtype; +} + +/** + * Check if a spec has any quality. + * @private + */ + +function isQuality(spec) { + return spec.q > 0; +} + +/** + * Count the number of quotes in a string. + * @private + */ + +function quoteCount(string) { + var count = 0; + var index = 0; + + while ((index = string.indexOf('"', index)) !== -1) { + count++; + index++; + } + + return count; +} + +/** + * Split a key value pair. + * @private + */ + +function splitKeyValuePair(str) { + var index = str.indexOf('='); + var key; + var val; + + if (index === -1) { + key = str; + } else { + key = str.substr(0, index); + val = str.substr(index + 1); + } + + return [key, val]; +} + +/** + * Split an Accept header into media types. + * @private + */ + +function splitMediaTypes(accept) { + var accepts = accept.split(','); + + for (var i = 1, j = 0; i < accepts.length; i++) { + if (quoteCount(accepts[j]) % 2 == 0) { + accepts[++j] = accepts[i]; + } else { + accepts[j] += ',' + accepts[i]; + } + } + + // trim accepts + accepts.length = j + 1; + + return accepts; +} + +/** + * Split a string of parameters. + * @private + */ + +function splitParameters(str) { + var parameters = str.split(';'); + + for (var i = 1, j = 0; i < parameters.length; i++) { + if (quoteCount(parameters[j]) % 2 == 0) { + parameters[++j] = parameters[i]; + } else { + parameters[j] += ';' + parameters[i]; + } + } + + // trim parameters + parameters.length = j + 1; + + for (var i = 0; i < parameters.length; i++) { + parameters[i] = parameters[i].trim(); + } + + return parameters; +} diff --git a/node_modules/negotiator/package.json b/node_modules/negotiator/package.json new file mode 100644 index 0000000..297635f --- /dev/null +++ b/node_modules/negotiator/package.json @@ -0,0 +1,42 @@ +{ + "name": "negotiator", + "description": "HTTP content negotiation", + "version": "0.6.3", + "contributors": [ + "Douglas Christopher Wilson ", + "Federico Romero ", + "Isaac Z. Schlueter (http://blog.izs.me/)" + ], + "license": "MIT", + "keywords": [ + "http", + "content negotiation", + "accept", + "accept-language", + "accept-encoding", + "accept-charset" + ], + "repository": "jshttp/negotiator", + "devDependencies": { + "eslint": "7.32.0", + "eslint-plugin-markdown": "2.2.1", + "mocha": "9.1.3", + "nyc": "15.1.0" + }, + "files": [ + "lib/", + "HISTORY.md", + "LICENSE", + "index.js", + "README.md" + ], + "engines": { + "node": ">= 0.6" + }, + "scripts": { + "lint": "eslint .", + "test": "mocha --reporter spec --check-leaks --bail test/", + "test-ci": "nyc --reporter=lcov --reporter=text npm test", + "test-cov": "nyc --reporter=html --reporter=text npm test" + } +} diff --git a/node_modules/normalize-path/LICENSE b/node_modules/normalize-path/LICENSE new file mode 100644 index 0000000..d32ab44 --- /dev/null +++ b/node_modules/normalize-path/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2018, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/normalize-path/README.md b/node_modules/normalize-path/README.md new file mode 100644 index 0000000..726d4d6 --- /dev/null +++ b/node_modules/normalize-path/README.md @@ -0,0 +1,127 @@ +# normalize-path [![NPM version](https://img.shields.io/npm/v/normalize-path.svg?style=flat)](https://www.npmjs.com/package/normalize-path) [![NPM monthly downloads](https://img.shields.io/npm/dm/normalize-path.svg?style=flat)](https://npmjs.org/package/normalize-path) [![NPM total downloads](https://img.shields.io/npm/dt/normalize-path.svg?style=flat)](https://npmjs.org/package/normalize-path) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/normalize-path.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/normalize-path) + +> Normalize slashes in a file path to be posix/unix-like forward slashes. Also condenses repeat slashes to a single slash and removes and trailing slashes, unless disabled. + +Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save normalize-path +``` + +## Usage + +```js +const normalize = require('normalize-path'); + +console.log(normalize('\\foo\\bar\\baz\\')); +//=> '/foo/bar/baz' +``` + +**win32 namespaces** + +```js +console.log(normalize('\\\\?\\UNC\\Server01\\user\\docs\\Letter.txt')); +//=> '//?/UNC/Server01/user/docs/Letter.txt' + +console.log(normalize('\\\\.\\CdRomX')); +//=> '//./CdRomX' +``` + +**Consecutive slashes** + +Condenses multiple consecutive forward slashes (except for leading slashes in win32 namespaces) to a single slash. + +```js +console.log(normalize('.//foo//bar///////baz/')); +//=> './foo/bar/baz' +``` + +### Trailing slashes + +By default trailing slashes are removed. Pass `false` as the last argument to disable this behavior and _**keep** trailing slashes_: + +```js +console.log(normalize('foo\\bar\\baz\\', false)); //=> 'foo/bar/baz/' +console.log(normalize('./foo/bar/baz/', false)); //=> './foo/bar/baz/' +``` + +## Release history + +### v3.0 + +No breaking changes in this release. + +* a check was added to ensure that [win32 namespaces](https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces) are handled properly by win32 `path.parse()` after a path has been normalized by this library. +* a minor optimization was made to simplify how the trailing separator was handled + +## About + +
+Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +
+ +
+Running Tests + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +$ npm install && npm test +``` + +
+ +
+Building docs + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +$ npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +
+ +### Related projects + +Other useful path-related libraries: + +* [contains-path](https://www.npmjs.com/package/contains-path): Return true if a file path contains the given path. | [homepage](https://github.com/jonschlinkert/contains-path "Return true if a file path contains the given path.") +* [is-absolute](https://www.npmjs.com/package/is-absolute): Returns true if a file path is absolute. Does not rely on the path module… [more](https://github.com/jonschlinkert/is-absolute) | [homepage](https://github.com/jonschlinkert/is-absolute "Returns true if a file path is absolute. Does not rely on the path module and can be used as a polyfill for node.js native `path.isAbolute`.") +* [is-relative](https://www.npmjs.com/package/is-relative): Returns `true` if the path appears to be relative. | [homepage](https://github.com/jonschlinkert/is-relative "Returns `true` if the path appears to be relative.") +* [parse-filepath](https://www.npmjs.com/package/parse-filepath): Pollyfill for node.js `path.parse`, parses a filepath into an object. | [homepage](https://github.com/jonschlinkert/parse-filepath "Pollyfill for node.js `path.parse`, parses a filepath into an object.") +* [path-ends-with](https://www.npmjs.com/package/path-ends-with): Return `true` if a file path ends with the given string/suffix. | [homepage](https://github.com/jonschlinkert/path-ends-with "Return `true` if a file path ends with the given string/suffix.") +* [unixify](https://www.npmjs.com/package/unixify): Convert Windows file paths to unix paths. | [homepage](https://github.com/jonschlinkert/unixify "Convert Windows file paths to unix paths.") + +### Contributors + +| **Commits** | **Contributor** | +| --- | --- | +| 35 | [jonschlinkert](https://github.com/jonschlinkert) | +| 1 | [phated](https://github.com/phated) | + +### Author + +**Jon Schlinkert** + +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) + +### License + +Copyright © 2018, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on April 19, 2018._ \ No newline at end of file diff --git a/node_modules/normalize-path/index.js b/node_modules/normalize-path/index.js new file mode 100644 index 0000000..6fac553 --- /dev/null +++ b/node_modules/normalize-path/index.js @@ -0,0 +1,35 @@ +/*! + * normalize-path + * + * Copyright (c) 2014-2018, Jon Schlinkert. + * Released under the MIT License. + */ + +module.exports = function(path, stripTrailing) { + if (typeof path !== 'string') { + throw new TypeError('expected path to be a string'); + } + + if (path === '\\' || path === '/') return '/'; + + var len = path.length; + if (len <= 1) return path; + + // ensure that win32 namespaces has two leading slashes, so that the path is + // handled properly by the win32 version of path.parse() after being normalized + // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces + var prefix = ''; + if (len > 4 && path[3] === '\\') { + var ch = path[2]; + if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') { + path = path.slice(2); + prefix = '//'; + } + } + + var segs = path.split(/[/\\]+/); + if (stripTrailing !== false && segs[segs.length - 1] === '') { + segs.pop(); + } + return prefix + segs.join('/'); +}; diff --git a/node_modules/normalize-path/package.json b/node_modules/normalize-path/package.json new file mode 100644 index 0000000..ad61098 --- /dev/null +++ b/node_modules/normalize-path/package.json @@ -0,0 +1,77 @@ +{ + "name": "normalize-path", + "description": "Normalize slashes in a file path to be posix/unix-like forward slashes. Also condenses repeat slashes to a single slash and removes and trailing slashes, unless disabled.", + "version": "3.0.0", + "homepage": "https://github.com/jonschlinkert/normalize-path", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "contributors": [ + "Blaine Bublitz (https://twitter.com/BlaineBublitz)", + "Jon Schlinkert (http://twitter.com/jonschlinkert)" + ], + "repository": "jonschlinkert/normalize-path", + "bugs": { + "url": "https://github.com/jonschlinkert/normalize-path/issues" + }, + "license": "MIT", + "files": [ + "index.js" + ], + "main": "index.js", + "engines": { + "node": ">=0.10.0" + }, + "scripts": { + "test": "mocha" + }, + "devDependencies": { + "gulp-format-md": "^1.0.0", + "minimist": "^1.2.0", + "mocha": "^3.5.3" + }, + "keywords": [ + "absolute", + "backslash", + "delimiter", + "file", + "file-path", + "filepath", + "fix", + "forward", + "fp", + "fs", + "normalize", + "path", + "relative", + "separator", + "slash", + "slashes", + "trailing", + "unix", + "urix" + ], + "verb": { + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "related": { + "description": "Other useful path-related libraries:", + "list": [ + "contains-path", + "is-absolute", + "is-relative", + "parse-filepath", + "path-ends-with", + "path-ends-with", + "unixify" + ] + }, + "lint": { + "reflinks": true + } + } +} diff --git a/node_modules/picomatch/CHANGELOG.md b/node_modules/picomatch/CHANGELOG.md new file mode 100644 index 0000000..8ccc6c1 --- /dev/null +++ b/node_modules/picomatch/CHANGELOG.md @@ -0,0 +1,136 @@ +# Release history + +**All notable changes to this project will be documented in this file.** + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +
+ Guiding Principles + +- Changelogs are for humans, not machines. +- There should be an entry for every single version. +- The same types of changes should be grouped. +- Versions and sections should be linkable. +- The latest version comes first. +- The release date of each versions is displayed. +- Mention whether you follow Semantic Versioning. + +
+ +
+ Types of changes + +Changelog entries are classified using the following labels _(from [keep-a-changelog](http://keepachangelog.com/)_): + +- `Added` for new features. +- `Changed` for changes in existing functionality. +- `Deprecated` for soon-to-be removed features. +- `Removed` for now removed features. +- `Fixed` for any bug fixes. +- `Security` in case of vulnerabilities. + +
+ +## 2.3.1 (2022-01-02) + +### Fixed + +* Fixes bug when a pattern containing an expression after the closing parenthesis (`/!(*.d).{ts,tsx}`) was incorrectly converted to regexp ([9f241ef](https://github.com/micromatch/picomatch/commit/9f241ef)). + +### Changed + +* Some documentation improvements ([f81d236](https://github.com/micromatch/picomatch/commit/f81d236), [421e0e7](https://github.com/micromatch/picomatch/commit/421e0e7)). + +## 2.3.0 (2021-05-21) + +### Fixed + +* Fixes bug where file names with two dots were not being matched consistently with negation extglobs containing a star ([56083ef](https://github.com/micromatch/picomatch/commit/56083ef)) + +## 2.2.3 (2021-04-10) + +### Fixed + +* Do not skip pattern seperator for square brackets ([fb08a30](https://github.com/micromatch/picomatch/commit/fb08a30)). +* Set negatedExtGlob also if it does not span the whole pattern ([032e3f5](https://github.com/micromatch/picomatch/commit/032e3f5)). + +## 2.2.2 (2020-03-21) + +### Fixed + +* Correctly handle parts of the pattern after parentheses in the `scan` method ([e15b920](https://github.com/micromatch/picomatch/commit/e15b920)). + +## 2.2.1 (2020-01-04) + +* Fixes [#49](https://github.com/micromatch/picomatch/issues/49), so that braces with no sets or ranges are now propertly treated as literals. + +## 2.2.0 (2020-01-04) + +* Disable fastpaths mode for the parse method ([5b8d33f](https://github.com/micromatch/picomatch/commit/5b8d33f)) +* Add `tokens`, `slashes`, and `parts` to the object returned by `picomatch.scan()`. + +## 2.1.0 (2019-10-31) + +* add benchmarks for scan ([4793b92](https://github.com/micromatch/picomatch/commit/4793b92)) +* Add eslint object-curly-spacing rule ([707c650](https://github.com/micromatch/picomatch/commit/707c650)) +* Add prefer-const eslint rule ([5c7501c](https://github.com/micromatch/picomatch/commit/5c7501c)) +* Add support for nonegate in scan API ([275c9b9](https://github.com/micromatch/picomatch/commit/275c9b9)) +* Change lets to consts. Move root import up. ([4840625](https://github.com/micromatch/picomatch/commit/4840625)) +* closes https://github.com/micromatch/picomatch/issues/21 ([766bcb0](https://github.com/micromatch/picomatch/commit/766bcb0)) +* Fix "Extglobs" table in readme ([eb19da8](https://github.com/micromatch/picomatch/commit/eb19da8)) +* fixes https://github.com/micromatch/picomatch/issues/20 ([9caca07](https://github.com/micromatch/picomatch/commit/9caca07)) +* fixes https://github.com/micromatch/picomatch/issues/26 ([fa58f45](https://github.com/micromatch/picomatch/commit/fa58f45)) +* Lint test ([d433a34](https://github.com/micromatch/picomatch/commit/d433a34)) +* lint unit tests ([0159b55](https://github.com/micromatch/picomatch/commit/0159b55)) +* Make scan work with noext ([6c02e03](https://github.com/micromatch/picomatch/commit/6c02e03)) +* minor linting ([c2a2b87](https://github.com/micromatch/picomatch/commit/c2a2b87)) +* minor parser improvements ([197671d](https://github.com/micromatch/picomatch/commit/197671d)) +* remove eslint since it... ([07876fa](https://github.com/micromatch/picomatch/commit/07876fa)) +* remove funding file ([8ebe96d](https://github.com/micromatch/picomatch/commit/8ebe96d)) +* Remove unused funks ([cbc6d54](https://github.com/micromatch/picomatch/commit/cbc6d54)) +* Run eslint during pretest, fix existing eslint findings ([0682367](https://github.com/micromatch/picomatch/commit/0682367)) +* support `noparen` in scan ([3d37569](https://github.com/micromatch/picomatch/commit/3d37569)) +* update changelog ([7b34e77](https://github.com/micromatch/picomatch/commit/7b34e77)) +* update travis ([777f038](https://github.com/micromatch/picomatch/commit/777f038)) +* Use eslint-disable-next-line instead of eslint-disable ([4e7c1fd](https://github.com/micromatch/picomatch/commit/4e7c1fd)) + +## 2.0.7 (2019-05-14) + +* 2.0.7 ([9eb9a71](https://github.com/micromatch/picomatch/commit/9eb9a71)) +* supports lookbehinds ([1f63f7e](https://github.com/micromatch/picomatch/commit/1f63f7e)) +* update .verb.md file with typo change ([2741279](https://github.com/micromatch/picomatch/commit/2741279)) +* fix: typo in README ([0753e44](https://github.com/micromatch/picomatch/commit/0753e44)) + +## 2.0.4 (2019-04-10) + +### Fixed + +- Readme link [fixed](https://github.com/micromatch/picomatch/pull/13/commits/a96ab3aa2b11b6861c23289964613d85563b05df) by @danez. +- `options.capture` now works as expected when fastpaths are enabled. See https://github.com/micromatch/picomatch/pull/12/commits/26aefd71f1cfaf95c37f1c1fcab68a693b037304. Thanks to @DrPizza. + +## 2.0.0 (2019-04-10) + +### Added + +- Adds support for `options.onIgnore`. See the readme for details +- Adds support for `options.onResult`. See the readme for details + +### Breaking changes + +- The unixify option was renamed to `windows` +- caching and all related options and methods have been removed + +## 1.0.0 (2018-11-05) + +- adds `.onMatch` option +- improvements to `.scan` method +- numerous improvements and optimizations for matching and parsing +- better windows path handling + +## 0.1.0 - 2017-04-13 + +First release. + + +[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog diff --git a/node_modules/picomatch/LICENSE b/node_modules/picomatch/LICENSE new file mode 100644 index 0000000..3608dca --- /dev/null +++ b/node_modules/picomatch/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/picomatch/README.md b/node_modules/picomatch/README.md new file mode 100644 index 0000000..b0526e2 --- /dev/null +++ b/node_modules/picomatch/README.md @@ -0,0 +1,708 @@ +

Picomatch

+ +

+ +version + + +test status + + +coverage status + + +downloads + +

+ +
+
+ +

+Blazing fast and accurate glob matcher written in JavaScript.
+No dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions. +

+ +
+
+ +## Why picomatch? + +* **Lightweight** - No dependencies +* **Minimal** - Tiny API surface. Main export is a function that takes a glob pattern and returns a matcher function. +* **Fast** - Loads in about 2ms (that's several times faster than a [single frame of a HD movie](http://www.endmemo.com/sconvert/framespersecondframespermillisecond.php) at 60fps) +* **Performant** - Use the returned matcher function to speed up repeat matching (like when watching files) +* **Accurate matching** - Using wildcards (`*` and `?`), globstars (`**`) for nested directories, [advanced globbing](#advanced-globbing) with extglobs, braces, and POSIX brackets, and support for escaping special characters with `\` or quotes. +* **Well tested** - Thousands of unit tests + +See the [library comparison](#library-comparisons) to other libraries. + +
+
+ +## Table of Contents + +
Click to expand + +- [Install](#install) +- [Usage](#usage) +- [API](#api) + * [picomatch](#picomatch) + * [.test](#test) + * [.matchBase](#matchbase) + * [.isMatch](#ismatch) + * [.parse](#parse) + * [.scan](#scan) + * [.compileRe](#compilere) + * [.makeRe](#makere) + * [.toRegex](#toregex) +- [Options](#options) + * [Picomatch options](#picomatch-options) + * [Scan Options](#scan-options) + * [Options Examples](#options-examples) +- [Globbing features](#globbing-features) + * [Basic globbing](#basic-globbing) + * [Advanced globbing](#advanced-globbing) + * [Braces](#braces) + * [Matching special characters as literals](#matching-special-characters-as-literals) +- [Library Comparisons](#library-comparisons) +- [Benchmarks](#benchmarks) +- [Philosophies](#philosophies) +- [About](#about) + * [Author](#author) + * [License](#license) + +_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_ + +
+ +
+
+ +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +npm install --save picomatch +``` + +
+ +## Usage + +The main export is a function that takes a glob pattern and an options object and returns a function for matching strings. + +```js +const pm = require('picomatch'); +const isMatch = pm('*.js'); + +console.log(isMatch('abcd')); //=> false +console.log(isMatch('a.js')); //=> true +console.log(isMatch('a.md')); //=> false +console.log(isMatch('a/b.js')); //=> false +``` + +
+ +## API + +### [picomatch](lib/picomatch.js#L32) + +Creates a matcher function from one or more glob patterns. The returned function takes a string to match as its first argument, and returns true if the string is a match. The returned matcher function also takes a boolean as the second argument that, when true, returns an object with additional information. + +**Params** + +* `globs` **{String|Array}**: One or more glob patterns. +* `options` **{Object=}** +* `returns` **{Function=}**: Returns a matcher function. + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch(glob[, options]); + +const isMatch = picomatch('*.!(*a)'); +console.log(isMatch('a.a')); //=> false +console.log(isMatch('a.b')); //=> true +``` + +### [.test](lib/picomatch.js#L117) + +Test `input` with the given `regex`. This is used by the main `picomatch()` function to test the input string. + +**Params** + +* `input` **{String}**: String to test. +* `regex` **{RegExp}** +* `returns` **{Object}**: Returns an object with matching info. + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.test(input, regex[, options]); + +console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); +// { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } +``` + +### [.matchBase](lib/picomatch.js#L161) + +Match the basename of a filepath. + +**Params** + +* `input` **{String}**: String to test. +* `glob` **{RegExp|String}**: Glob pattern or regex created by [.makeRe](#makeRe). +* `returns` **{Boolean}** + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.matchBase(input, glob[, options]); +console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true +``` + +### [.isMatch](lib/picomatch.js#L183) + +Returns true if **any** of the given glob `patterns` match the specified `string`. + +**Params** + +* **{String|Array}**: str The string to test. +* **{String|Array}**: patterns One or more glob patterns to use for matching. +* **{Object}**: See available [options](#options). +* `returns` **{Boolean}**: Returns true if any patterns match `str` + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.isMatch(string, patterns[, options]); + +console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true +console.log(picomatch.isMatch('a.a', 'b.*')); //=> false +``` + +### [.parse](lib/picomatch.js#L199) + +Parse a glob pattern to create the source string for a regular expression. + +**Params** + +* `pattern` **{String}** +* `options` **{Object}** +* `returns` **{Object}**: Returns an object with useful properties and output to be used as a regex source string. + +**Example** + +```js +const picomatch = require('picomatch'); +const result = picomatch.parse(pattern[, options]); +``` + +### [.scan](lib/picomatch.js#L231) + +Scan a glob pattern to separate the pattern into segments. + +**Params** + +* `input` **{String}**: Glob pattern to scan. +* `options` **{Object}** +* `returns` **{Object}**: Returns an object with + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.scan(input[, options]); + +const result = picomatch.scan('!./foo/*.js'); +console.log(result); +{ prefix: '!./', + input: '!./foo/*.js', + start: 3, + base: 'foo', + glob: '*.js', + isBrace: false, + isBracket: false, + isGlob: true, + isExtglob: false, + isGlobstar: false, + negated: true } +``` + +### [.compileRe](lib/picomatch.js#L245) + +Compile a regular expression from the `state` object returned by the +[parse()](#parse) method. + +**Params** + +* `state` **{Object}** +* `options` **{Object}** +* `returnOutput` **{Boolean}**: Intended for implementors, this argument allows you to return the raw output from the parser. +* `returnState` **{Boolean}**: Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. +* `returns` **{RegExp}** + +### [.makeRe](lib/picomatch.js#L286) + +Create a regular expression from a parsed glob pattern. + +**Params** + +* `state` **{String}**: The object returned from the `.parse` method. +* `options` **{Object}** +* `returnOutput` **{Boolean}**: Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. +* `returnState` **{Boolean}**: Implementors may use this argument to return the state from the parsed glob with the returned regular expression. +* `returns` **{RegExp}**: Returns a regex created from the given pattern. + +**Example** + +```js +const picomatch = require('picomatch'); +const state = picomatch.parse('*.js'); +// picomatch.compileRe(state[, options]); + +console.log(picomatch.compileRe(state)); +//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ +``` + +### [.toRegex](lib/picomatch.js#L321) + +Create a regular expression from the given regex source string. + +**Params** + +* `source` **{String}**: Regular expression source string. +* `options` **{Object}** +* `returns` **{RegExp}** + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.toRegex(source[, options]); + +const { output } = picomatch.parse('*.js'); +console.log(picomatch.toRegex(output)); +//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ +``` + +
+ +## Options + +### Picomatch options + +The following options may be used with the main `picomatch()` function or any of the methods on the picomatch API. + +| **Option** | **Type** | **Default value** | **Description** | +| --- | --- | --- | --- | +| `basename` | `boolean` | `false` | If set, then patterns without slashes will be matched against the basename of the path if it contains slashes. For example, `a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. | +| `bash` | `boolean` | `false` | Follow bash matching rules more strictly - disallows backslashes as escape characters, and treats single stars as globstars (`**`). | +| `capture` | `boolean` | `undefined` | Return regex matches in supporting methods. | +| `contains` | `boolean` | `undefined` | Allows glob to match any part of the given string(s). | +| `cwd` | `string` | `process.cwd()` | Current working directory. Used by `picomatch.split()` | +| `debug` | `boolean` | `undefined` | Debug regular expressions when an error is thrown. | +| `dot` | `boolean` | `false` | Enable dotfile matching. By default, dotfiles are ignored unless a `.` is explicitly defined in the pattern, or `options.dot` is true | +| `expandRange` | `function` | `undefined` | Custom function for expanding ranges in brace patterns, such as `{a..z}`. The function receives the range values as two arguments, and it must return a string to be used in the generated regex. It's recommended that returned strings be wrapped in parentheses. | +| `failglob` | `boolean` | `false` | Throws an error if no matches are found. Based on the bash option of the same name. | +| `fastpaths` | `boolean` | `true` | To speed up processing, full parsing is skipped for a handful common glob patterns. Disable this behavior by setting this option to `false`. | +| `flags` | `string` | `undefined` | Regex flags to use in the generated regex. If defined, the `nocase` option will be overridden. | +| [format](#optionsformat) | `function` | `undefined` | Custom function for formatting the returned string. This is useful for removing leading slashes, converting Windows paths to Posix paths, etc. | +| `ignore` | `array\|string` | `undefined` | One or more glob patterns for excluding strings that should not be matched from the result. | +| `keepQuotes` | `boolean` | `false` | Retain quotes in the generated regex, since quotes may also be used as an alternative to backslashes. | +| `literalBrackets` | `boolean` | `undefined` | When `true`, brackets in the glob pattern will be escaped so that only literal brackets will be matched. | +| `matchBase` | `boolean` | `false` | Alias for `basename` | +| `maxLength` | `boolean` | `65536` | Limit the max length of the input string. An error is thrown if the input string is longer than this value. | +| `nobrace` | `boolean` | `false` | Disable brace matching, so that `{a,b}` and `{1..3}` would be treated as literal characters. | +| `nobracket` | `boolean` | `undefined` | Disable matching with regex brackets. | +| `nocase` | `boolean` | `false` | Make matching case-insensitive. Equivalent to the regex `i` flag. Note that this option is overridden by the `flags` option. | +| `nodupes` | `boolean` | `true` | Deprecated, use `nounique` instead. This option will be removed in a future major release. By default duplicates are removed. Disable uniquification by setting this option to false. | +| `noext` | `boolean` | `false` | Alias for `noextglob` | +| `noextglob` | `boolean` | `false` | Disable support for matching with extglobs (like `+(a\|b)`) | +| `noglobstar` | `boolean` | `false` | Disable support for matching nested directories with globstars (`**`) | +| `nonegate` | `boolean` | `false` | Disable support for negating with leading `!` | +| `noquantifiers` | `boolean` | `false` | Disable support for regex quantifiers (like `a{1,2}`) and treat them as brace patterns to be expanded. | +| [onIgnore](#optionsonIgnore) | `function` | `undefined` | Function to be called on ignored items. | +| [onMatch](#optionsonMatch) | `function` | `undefined` | Function to be called on matched items. | +| [onResult](#optionsonResult) | `function` | `undefined` | Function to be called on all items, regardless of whether or not they are matched or ignored. | +| `posix` | `boolean` | `false` | Support POSIX character classes ("posix brackets"). | +| `posixSlashes` | `boolean` | `undefined` | Convert all slashes in file paths to forward slashes. This does not convert slashes in the glob pattern itself | +| `prepend` | `boolean` | `undefined` | String to prepend to the generated regex used for matching. | +| `regex` | `boolean` | `false` | Use regular expression rules for `+` (instead of matching literal `+`), and for stars that follow closing parentheses or brackets (as in `)*` and `]*`). | +| `strictBrackets` | `boolean` | `undefined` | Throw an error if brackets, braces, or parens are imbalanced. | +| `strictSlashes` | `boolean` | `undefined` | When true, picomatch won't match trailing slashes with single stars. | +| `unescape` | `boolean` | `undefined` | Remove backslashes preceding escaped characters in the glob pattern. By default, backslashes are retained. | +| `unixify` | `boolean` | `undefined` | Alias for `posixSlashes`, for backwards compatibility. | + +picomatch has automatic detection for regex positive and negative lookbehinds. If the pattern contains a negative lookbehind, you must be using Node.js >= 8.10 or else picomatch will throw an error. + +### Scan Options + +In addition to the main [picomatch options](#picomatch-options), the following options may also be used with the [.scan](#scan) method. + +| **Option** | **Type** | **Default value** | **Description** | +| --- | --- | --- | --- | +| `tokens` | `boolean` | `false` | When `true`, the returned object will include an array of tokens (objects), representing each path "segment" in the scanned glob pattern | +| `parts` | `boolean` | `false` | When `true`, the returned object will include an array of strings representing each path "segment" in the scanned glob pattern. This is automatically enabled when `options.tokens` is true | + +**Example** + +```js +const picomatch = require('picomatch'); +const result = picomatch.scan('!./foo/*.js', { tokens: true }); +console.log(result); +// { +// prefix: '!./', +// input: '!./foo/*.js', +// start: 3, +// base: 'foo', +// glob: '*.js', +// isBrace: false, +// isBracket: false, +// isGlob: true, +// isExtglob: false, +// isGlobstar: false, +// negated: true, +// maxDepth: 2, +// tokens: [ +// { value: '!./', depth: 0, isGlob: false, negated: true, isPrefix: true }, +// { value: 'foo', depth: 1, isGlob: false }, +// { value: '*.js', depth: 1, isGlob: true } +// ], +// slashes: [ 2, 6 ], +// parts: [ 'foo', '*.js' ] +// } +``` + +
+ +### Options Examples + +#### options.expandRange + +**Type**: `function` + +**Default**: `undefined` + +Custom function for expanding ranges in brace patterns. The [fill-range](https://github.com/jonschlinkert/fill-range) library is ideal for this purpose, or you can use custom code to do whatever you need. + +**Example** + +The following example shows how to create a glob that matches a folder + +```js +const fill = require('fill-range'); +const regex = pm.makeRe('foo/{01..25}/bar', { + expandRange(a, b) { + return `(${fill(a, b, { toRegex: true })})`; + } +}); + +console.log(regex); +//=> /^(?:foo\/((?:0[1-9]|1[0-9]|2[0-5]))\/bar)$/ + +console.log(regex.test('foo/00/bar')) // false +console.log(regex.test('foo/01/bar')) // true +console.log(regex.test('foo/10/bar')) // true +console.log(regex.test('foo/22/bar')) // true +console.log(regex.test('foo/25/bar')) // true +console.log(regex.test('foo/26/bar')) // false +``` + +#### options.format + +**Type**: `function` + +**Default**: `undefined` + +Custom function for formatting strings before they're matched. + +**Example** + +```js +// strip leading './' from strings +const format = str => str.replace(/^\.\//, ''); +const isMatch = picomatch('foo/*.js', { format }); +console.log(isMatch('./foo/bar.js')); //=> true +``` + +#### options.onMatch + +```js +const onMatch = ({ glob, regex, input, output }) => { + console.log({ glob, regex, input, output }); +}; + +const isMatch = picomatch('*', { onMatch }); +isMatch('foo'); +isMatch('bar'); +isMatch('baz'); +``` + +#### options.onIgnore + +```js +const onIgnore = ({ glob, regex, input, output }) => { + console.log({ glob, regex, input, output }); +}; + +const isMatch = picomatch('*', { onIgnore, ignore: 'f*' }); +isMatch('foo'); +isMatch('bar'); +isMatch('baz'); +``` + +#### options.onResult + +```js +const onResult = ({ glob, regex, input, output }) => { + console.log({ glob, regex, input, output }); +}; + +const isMatch = picomatch('*', { onResult, ignore: 'f*' }); +isMatch('foo'); +isMatch('bar'); +isMatch('baz'); +``` + +
+
+ +## Globbing features + +* [Basic globbing](#basic-globbing) (Wildcard matching) +* [Advanced globbing](#advanced-globbing) (extglobs, posix brackets, brace matching) + +### Basic globbing + +| **Character** | **Description** | +| --- | --- | +| `*` | Matches any character zero or more times, excluding path separators. Does _not match_ path separators or hidden files or directories ("dotfiles"), unless explicitly enabled by setting the `dot` option to `true`. | +| `**` | Matches any character zero or more times, including path separators. Note that `**` will only match path separators (`/`, and `\\` on Windows) when they are the only characters in a path segment. Thus, `foo**/bar` is equivalent to `foo*/bar`, and `foo/a**b/bar` is equivalent to `foo/a*b/bar`, and _more than two_ consecutive stars in a glob path segment are regarded as _a single star_. Thus, `foo/***/bar` is equivalent to `foo/*/bar`. | +| `?` | Matches any character excluding path separators one time. Does _not match_ path separators or leading dots. | +| `[abc]` | Matches any characters inside the brackets. For example, `[abc]` would match the characters `a`, `b` or `c`, and nothing else. | + +#### Matching behavior vs. Bash + +Picomatch's matching features and expected results in unit tests are based on Bash's unit tests and the Bash 4.3 specification, with the following exceptions: + +* Bash will match `foo/bar/baz` with `*`. Picomatch only matches nested directories with `**`. +* Bash greedily matches with negated extglobs. For example, Bash 4.3 says that `!(foo)*` should match `foo` and `foobar`, since the trailing `*` bracktracks to match the preceding pattern. This is very memory-inefficient, and IMHO, also incorrect. Picomatch would return `false` for both `foo` and `foobar`. + +
+ +### Advanced globbing + +* [extglobs](#extglobs) +* [POSIX brackets](#posix-brackets) +* [Braces](#brace-expansion) + +#### Extglobs + +| **Pattern** | **Description** | +| --- | --- | +| `@(pattern)` | Match _only one_ consecutive occurrence of `pattern` | +| `*(pattern)` | Match _zero or more_ consecutive occurrences of `pattern` | +| `+(pattern)` | Match _one or more_ consecutive occurrences of `pattern` | +| `?(pattern)` | Match _zero or **one**_ consecutive occurrences of `pattern` | +| `!(pattern)` | Match _anything but_ `pattern` | + +**Examples** + +```js +const pm = require('picomatch'); + +// *(pattern) matches ZERO or more of "pattern" +console.log(pm.isMatch('a', 'a*(z)')); // true +console.log(pm.isMatch('az', 'a*(z)')); // true +console.log(pm.isMatch('azzz', 'a*(z)')); // true + +// +(pattern) matches ONE or more of "pattern" +console.log(pm.isMatch('a', 'a*(z)')); // true +console.log(pm.isMatch('az', 'a*(z)')); // true +console.log(pm.isMatch('azzz', 'a*(z)')); // true + +// supports multiple extglobs +console.log(pm.isMatch('foo.bar', '!(foo).!(bar)')); // false + +// supports nested extglobs +console.log(pm.isMatch('foo.bar', '!(!(foo)).!(!(bar))')); // true +``` + +#### POSIX brackets + +POSIX classes are disabled by default. Enable this feature by setting the `posix` option to true. + +**Enable POSIX bracket support** + +```js +console.log(pm.makeRe('[[:word:]]+', { posix: true })); +//=> /^(?:(?=.)[A-Za-z0-9_]+\/?)$/ +``` + +**Supported POSIX classes** + +The following named POSIX bracket expressions are supported: + +* `[:alnum:]` - Alphanumeric characters, equ `[a-zA-Z0-9]` +* `[:alpha:]` - Alphabetical characters, equivalent to `[a-zA-Z]`. +* `[:ascii:]` - ASCII characters, equivalent to `[\\x00-\\x7F]`. +* `[:blank:]` - Space and tab characters, equivalent to `[ \\t]`. +* `[:cntrl:]` - Control characters, equivalent to `[\\x00-\\x1F\\x7F]`. +* `[:digit:]` - Numerical digits, equivalent to `[0-9]`. +* `[:graph:]` - Graph characters, equivalent to `[\\x21-\\x7E]`. +* `[:lower:]` - Lowercase letters, equivalent to `[a-z]`. +* `[:print:]` - Print characters, equivalent to `[\\x20-\\x7E ]`. +* `[:punct:]` - Punctuation and symbols, equivalent to `[\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~]`. +* `[:space:]` - Extended space characters, equivalent to `[ \\t\\r\\n\\v\\f]`. +* `[:upper:]` - Uppercase letters, equivalent to `[A-Z]`. +* `[:word:]` - Word characters (letters, numbers and underscores), equivalent to `[A-Za-z0-9_]`. +* `[:xdigit:]` - Hexadecimal digits, equivalent to `[A-Fa-f0-9]`. + +See the [Bash Reference Manual](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html) for more information. + +### Braces + +Picomatch does not do brace expansion. For [brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html) and advanced matching with braces, use [micromatch](https://github.com/micromatch/micromatch) instead. Picomatch has very basic support for braces. + +### Matching special characters as literals + +If you wish to match the following special characters in a filepath, and you want to use these characters in your glob pattern, they must be escaped with backslashes or quotes: + +**Special Characters** + +Some characters that are used for matching in regular expressions are also regarded as valid file path characters on some platforms. + +To match any of the following characters as literals: `$^*+?()[] + +Examples: + +```js +console.log(pm.makeRe('foo/bar \\(1\\)')); +console.log(pm.makeRe('foo/bar \\(1\\)')); +``` + +
+
+ +## Library Comparisons + +The following table shows which features are supported by [minimatch](https://github.com/isaacs/minimatch), [micromatch](https://github.com/micromatch/micromatch), [picomatch](https://github.com/micromatch/picomatch), [nanomatch](https://github.com/micromatch/nanomatch), [extglob](https://github.com/micromatch/extglob), [braces](https://github.com/micromatch/braces), and [expand-brackets](https://github.com/micromatch/expand-brackets). + +| **Feature** | `minimatch` | `micromatch` | `picomatch` | `nanomatch` | `extglob` | `braces` | `expand-brackets` | +| --- | --- | --- | --- | --- | --- | --- | --- | +| Wildcard matching (`*?+`) | ✔ | ✔ | ✔ | ✔ | - | - | - | +| Advancing globbing | ✔ | ✔ | ✔ | - | - | - | - | +| Brace _matching_ | ✔ | ✔ | ✔ | - | - | ✔ | - | +| Brace _expansion_ | ✔ | ✔ | - | - | - | ✔ | - | +| Extglobs | partial | ✔ | ✔ | - | ✔ | - | - | +| Posix brackets | - | ✔ | ✔ | - | - | - | ✔ | +| Regular expression syntax | - | ✔ | ✔ | ✔ | ✔ | - | ✔ | +| File system operations | - | - | - | - | - | - | - | + +
+
+ +## Benchmarks + +Performance comparison of picomatch and minimatch. + +``` +# .makeRe star + picomatch x 1,993,050 ops/sec ±0.51% (91 runs sampled) + minimatch x 627,206 ops/sec ±1.96% (87 runs sampled)) + +# .makeRe star; dot=true + picomatch x 1,436,640 ops/sec ±0.62% (91 runs sampled) + minimatch x 525,876 ops/sec ±0.60% (88 runs sampled) + +# .makeRe globstar + picomatch x 1,592,742 ops/sec ±0.42% (90 runs sampled) + minimatch x 962,043 ops/sec ±1.76% (91 runs sampled)d) + +# .makeRe globstars + picomatch x 1,615,199 ops/sec ±0.35% (94 runs sampled) + minimatch x 477,179 ops/sec ±1.33% (91 runs sampled) + +# .makeRe with leading star + picomatch x 1,220,856 ops/sec ±0.40% (92 runs sampled) + minimatch x 453,564 ops/sec ±1.43% (94 runs sampled) + +# .makeRe - basic braces + picomatch x 392,067 ops/sec ±0.70% (90 runs sampled) + minimatch x 99,532 ops/sec ±2.03% (87 runs sampled)) +``` + +
+
+ +## Philosophies + +The goal of this library is to be blazing fast, without compromising on accuracy. + +**Accuracy** + +The number one of goal of this library is accuracy. However, it's not unusual for different glob implementations to have different rules for matching behavior, even with simple wildcard matching. It gets increasingly more complicated when combinations of different features are combined, like when extglobs are combined with globstars, braces, slashes, and so on: `!(**/{a,b,*/c})`. + +Thus, given that there is no canonical glob specification to use as a single source of truth when differences of opinion arise regarding behavior, sometimes we have to implement our best judgement and rely on feedback from users to make improvements. + +**Performance** + +Although this library performs well in benchmarks, and in most cases it's faster than other popular libraries we benchmarked against, we will always choose accuracy over performance. It's not helpful to anyone if our library is faster at returning the wrong answer. + +
+
+ +## About + +
+Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +Please read the [contributing guide](.github/contributing.md) for advice on opening issues, pull requests, and coding standards. + +
+ +
+Running Tests + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +npm install && npm test +``` + +
+ +
+Building docs + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +
+ +### Author + +**Jon Schlinkert** + +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) + +### License + +Copyright © 2017-present, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). diff --git a/node_modules/picomatch/index.js b/node_modules/picomatch/index.js new file mode 100644 index 0000000..d2f2bc5 --- /dev/null +++ b/node_modules/picomatch/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./lib/picomatch'); diff --git a/node_modules/picomatch/lib/constants.js b/node_modules/picomatch/lib/constants.js new file mode 100644 index 0000000..a62ef38 --- /dev/null +++ b/node_modules/picomatch/lib/constants.js @@ -0,0 +1,179 @@ +'use strict'; + +const path = require('path'); +const WIN_SLASH = '\\\\/'; +const WIN_NO_SLASH = `[^${WIN_SLASH}]`; + +/** + * Posix glob regex + */ + +const DOT_LITERAL = '\\.'; +const PLUS_LITERAL = '\\+'; +const QMARK_LITERAL = '\\?'; +const SLASH_LITERAL = '\\/'; +const ONE_CHAR = '(?=.)'; +const QMARK = '[^/]'; +const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; +const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; +const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; +const NO_DOT = `(?!${DOT_LITERAL})`; +const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; +const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; +const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; +const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; +const STAR = `${QMARK}*?`; + +const POSIX_CHARS = { + DOT_LITERAL, + PLUS_LITERAL, + QMARK_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + QMARK, + END_ANCHOR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK_NO_DOT, + STAR, + START_ANCHOR +}; + +/** + * Windows glob regex + */ + +const WINDOWS_CHARS = { + ...POSIX_CHARS, + + SLASH_LITERAL: `[${WIN_SLASH}]`, + QMARK: WIN_NO_SLASH, + STAR: `${WIN_NO_SLASH}*?`, + DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, + NO_DOT: `(?!${DOT_LITERAL})`, + NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, + NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + QMARK_NO_DOT: `[^.${WIN_SLASH}]`, + START_ANCHOR: `(?:^|[${WIN_SLASH}])`, + END_ANCHOR: `(?:[${WIN_SLASH}]|$)` +}; + +/** + * POSIX Bracket Regex + */ + +const POSIX_REGEX_SOURCE = { + alnum: 'a-zA-Z0-9', + alpha: 'a-zA-Z', + ascii: '\\x00-\\x7F', + blank: ' \\t', + cntrl: '\\x00-\\x1F\\x7F', + digit: '0-9', + graph: '\\x21-\\x7E', + lower: 'a-z', + print: '\\x20-\\x7E ', + punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', + space: ' \\t\\r\\n\\v\\f', + upper: 'A-Z', + word: 'A-Za-z0-9_', + xdigit: 'A-Fa-f0-9' +}; + +module.exports = { + MAX_LENGTH: 1024 * 64, + POSIX_REGEX_SOURCE, + + // regular expressions + REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, + REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, + REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, + REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, + REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, + REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, + + // Replace globs with equivalent patterns to reduce parsing time. + REPLACEMENTS: { + '***': '*', + '**/**': '**', + '**/**/**': '**' + }, + + // Digits + CHAR_0: 48, /* 0 */ + CHAR_9: 57, /* 9 */ + + // Alphabet chars. + CHAR_UPPERCASE_A: 65, /* A */ + CHAR_LOWERCASE_A: 97, /* a */ + CHAR_UPPERCASE_Z: 90, /* Z */ + CHAR_LOWERCASE_Z: 122, /* z */ + + CHAR_LEFT_PARENTHESES: 40, /* ( */ + CHAR_RIGHT_PARENTHESES: 41, /* ) */ + + CHAR_ASTERISK: 42, /* * */ + + // Non-alphabetic chars. + CHAR_AMPERSAND: 38, /* & */ + CHAR_AT: 64, /* @ */ + CHAR_BACKWARD_SLASH: 92, /* \ */ + CHAR_CARRIAGE_RETURN: 13, /* \r */ + CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ + CHAR_COLON: 58, /* : */ + CHAR_COMMA: 44, /* , */ + CHAR_DOT: 46, /* . */ + CHAR_DOUBLE_QUOTE: 34, /* " */ + CHAR_EQUAL: 61, /* = */ + CHAR_EXCLAMATION_MARK: 33, /* ! */ + CHAR_FORM_FEED: 12, /* \f */ + CHAR_FORWARD_SLASH: 47, /* / */ + CHAR_GRAVE_ACCENT: 96, /* ` */ + CHAR_HASH: 35, /* # */ + CHAR_HYPHEN_MINUS: 45, /* - */ + CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ + CHAR_LEFT_CURLY_BRACE: 123, /* { */ + CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ + CHAR_LINE_FEED: 10, /* \n */ + CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ + CHAR_PERCENT: 37, /* % */ + CHAR_PLUS: 43, /* + */ + CHAR_QUESTION_MARK: 63, /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ + CHAR_RIGHT_CURLY_BRACE: 125, /* } */ + CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ + CHAR_SEMICOLON: 59, /* ; */ + CHAR_SINGLE_QUOTE: 39, /* ' */ + CHAR_SPACE: 32, /* */ + CHAR_TAB: 9, /* \t */ + CHAR_UNDERSCORE: 95, /* _ */ + CHAR_VERTICAL_LINE: 124, /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ + + SEP: path.sep, + + /** + * Create EXTGLOB_CHARS + */ + + extglobChars(chars) { + return { + '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, + '?': { type: 'qmark', open: '(?:', close: ')?' }, + '+': { type: 'plus', open: '(?:', close: ')+' }, + '*': { type: 'star', open: '(?:', close: ')*' }, + '@': { type: 'at', open: '(?:', close: ')' } + }; + }, + + /** + * Create GLOB_CHARS + */ + + globChars(win32) { + return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; + } +}; diff --git a/node_modules/picomatch/lib/parse.js b/node_modules/picomatch/lib/parse.js new file mode 100644 index 0000000..58269d0 --- /dev/null +++ b/node_modules/picomatch/lib/parse.js @@ -0,0 +1,1091 @@ +'use strict'; + +const constants = require('./constants'); +const utils = require('./utils'); + +/** + * Constants + */ + +const { + MAX_LENGTH, + POSIX_REGEX_SOURCE, + REGEX_NON_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_BACKREF, + REPLACEMENTS +} = constants; + +/** + * Helpers + */ + +const expandRange = (args, options) => { + if (typeof options.expandRange === 'function') { + return options.expandRange(...args, options); + } + + args.sort(); + const value = `[${args.join('-')}]`; + + try { + /* eslint-disable-next-line no-new */ + new RegExp(value); + } catch (ex) { + return args.map(v => utils.escapeRegex(v)).join('..'); + } + + return value; +}; + +/** + * Create the message for a syntax error + */ + +const syntaxError = (type, char) => { + return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; +}; + +/** + * Parse the given input string. + * @param {String} input + * @param {Object} options + * @return {Object} + */ + +const parse = (input, options) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); + } + + input = REPLACEMENTS[input] || input; + + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + + let len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } + + const bos = { type: 'bos', value: '', output: opts.prepend || '' }; + const tokens = [bos]; + + const capture = opts.capture ? '' : '?:'; + const win32 = utils.isWindows(options); + + // create constants based on platform, for windows or posix + const PLATFORM_CHARS = constants.globChars(win32); + const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); + + const { + DOT_LITERAL, + PLUS_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK, + QMARK_NO_DOT, + STAR, + START_ANCHOR + } = PLATFORM_CHARS; + + const globstar = opts => { + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; + + const nodot = opts.dot ? '' : NO_DOT; + const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; + let star = opts.bash === true ? globstar(opts) : STAR; + + if (opts.capture) { + star = `(${star})`; + } + + // minimatch options support + if (typeof opts.noext === 'boolean') { + opts.noextglob = opts.noext; + } + + const state = { + input, + index: -1, + start: 0, + dot: opts.dot === true, + consumed: '', + output: '', + prefix: '', + backtrack: false, + negated: false, + brackets: 0, + braces: 0, + parens: 0, + quotes: 0, + globstar: false, + tokens + }; + + input = utils.removePrefix(input, state); + len = input.length; + + const extglobs = []; + const braces = []; + const stack = []; + let prev = bos; + let value; + + /** + * Tokenizing helpers + */ + + const eos = () => state.index === len - 1; + const peek = state.peek = (n = 1) => input[state.index + n]; + const advance = state.advance = () => input[++state.index] || ''; + const remaining = () => input.slice(state.index + 1); + const consume = (value = '', num = 0) => { + state.consumed += value; + state.index += num; + }; + + const append = token => { + state.output += token.output != null ? token.output : token.value; + consume(token.value); + }; + + const negate = () => { + let count = 1; + + while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { + advance(); + state.start++; + count++; + } + + if (count % 2 === 0) { + return false; + } + + state.negated = true; + state.start++; + return true; + }; + + const increment = type => { + state[type]++; + stack.push(type); + }; + + const decrement = type => { + state[type]--; + stack.pop(); + }; + + /** + * Push tokens onto the tokens array. This helper speeds up + * tokenizing by 1) helping us avoid backtracking as much as possible, + * and 2) helping us avoid creating extra tokens when consecutive + * characters are plain text. This improves performance and simplifies + * lookbehinds. + */ + + const push = tok => { + if (prev.type === 'globstar') { + const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); + const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); + + if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { + state.output = state.output.slice(0, -prev.output.length); + prev.type = 'star'; + prev.value = '*'; + prev.output = star; + state.output += prev.output; + } + } + + if (extglobs.length && tok.type !== 'paren') { + extglobs[extglobs.length - 1].inner += tok.value; + } + + if (tok.value || tok.output) append(tok); + if (prev && prev.type === 'text' && tok.type === 'text') { + prev.value += tok.value; + prev.output = (prev.output || '') + tok.value; + return; + } + + tok.prev = prev; + tokens.push(tok); + prev = tok; + }; + + const extglobOpen = (type, value) => { + const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; + + token.prev = prev; + token.parens = state.parens; + token.output = state.output; + const output = (opts.capture ? '(' : '') + token.open; + + increment('parens'); + push({ type, value, output: state.output ? '' : ONE_CHAR }); + push({ type: 'paren', extglob: true, value: advance(), output }); + extglobs.push(token); + }; + + const extglobClose = token => { + let output = token.close + (opts.capture ? ')' : ''); + let rest; + + if (token.type === 'negate') { + let extglobStar = star; + + if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { + extglobStar = globstar(opts); + } + + if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { + output = token.close = `)$))${extglobStar}`; + } + + if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { + // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. + // In this case, we need to parse the string and use it in the output of the original pattern. + // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. + // + // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. + const expression = parse(rest, { ...options, fastpaths: false }).output; + + output = token.close = `)${expression})${extglobStar})`; + } + + if (token.prev.type === 'bos') { + state.negatedExtglob = true; + } + } + + push({ type: 'paren', extglob: true, value, output }); + decrement('parens'); + }; + + /** + * Fast paths + */ + + if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { + let backslashes = false; + + let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { + if (first === '\\') { + backslashes = true; + return m; + } + + if (first === '?') { + if (esc) { + return esc + first + (rest ? QMARK.repeat(rest.length) : ''); + } + if (index === 0) { + return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); + } + return QMARK.repeat(chars.length); + } + + if (first === '.') { + return DOT_LITERAL.repeat(chars.length); + } + + if (first === '*') { + if (esc) { + return esc + first + (rest ? star : ''); + } + return star; + } + return esc ? m : `\\${m}`; + }); + + if (backslashes === true) { + if (opts.unescape === true) { + output = output.replace(/\\/g, ''); + } else { + output = output.replace(/\\+/g, m => { + return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); + }); + } + } + + if (output === input && opts.contains === true) { + state.output = input; + return state; + } + + state.output = utils.wrapOutput(output, state, options); + return state; + } + + /** + * Tokenize input until we reach end-of-string + */ + + while (!eos()) { + value = advance(); + + if (value === '\u0000') { + continue; + } + + /** + * Escaped characters + */ + + if (value === '\\') { + const next = peek(); + + if (next === '/' && opts.bash !== true) { + continue; + } + + if (next === '.' || next === ';') { + continue; + } + + if (!next) { + value += '\\'; + push({ type: 'text', value }); + continue; + } + + // collapse slashes to reduce potential for exploits + const match = /^\\+/.exec(remaining()); + let slashes = 0; + + if (match && match[0].length > 2) { + slashes = match[0].length; + state.index += slashes; + if (slashes % 2 !== 0) { + value += '\\'; + } + } + + if (opts.unescape === true) { + value = advance(); + } else { + value += advance(); + } + + if (state.brackets === 0) { + push({ type: 'text', value }); + continue; + } + } + + /** + * If we're inside a regex character class, continue + * until we reach the closing bracket. + */ + + if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { + if (opts.posix !== false && value === ':') { + const inner = prev.value.slice(1); + if (inner.includes('[')) { + prev.posix = true; + + if (inner.includes(':')) { + const idx = prev.value.lastIndexOf('['); + const pre = prev.value.slice(0, idx); + const rest = prev.value.slice(idx + 2); + const posix = POSIX_REGEX_SOURCE[rest]; + if (posix) { + prev.value = pre + posix; + state.backtrack = true; + advance(); + + if (!bos.output && tokens.indexOf(prev) === 1) { + bos.output = ONE_CHAR; + } + continue; + } + } + } + } + + if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { + value = `\\${value}`; + } + + if (value === ']' && (prev.value === '[' || prev.value === '[^')) { + value = `\\${value}`; + } + + if (opts.posix === true && value === '!' && prev.value === '[') { + value = '^'; + } + + prev.value += value; + append({ value }); + continue; + } + + /** + * If we're inside a quoted string, continue + * until we reach the closing double quote. + */ + + if (state.quotes === 1 && value !== '"') { + value = utils.escapeRegex(value); + prev.value += value; + append({ value }); + continue; + } + + /** + * Double quotes + */ + + if (value === '"') { + state.quotes = state.quotes === 1 ? 0 : 1; + if (opts.keepQuotes === true) { + push({ type: 'text', value }); + } + continue; + } + + /** + * Parentheses + */ + + if (value === '(') { + increment('parens'); + push({ type: 'paren', value }); + continue; + } + + if (value === ')') { + if (state.parens === 0 && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '(')); + } + + const extglob = extglobs[extglobs.length - 1]; + if (extglob && state.parens === extglob.parens + 1) { + extglobClose(extglobs.pop()); + continue; + } + + push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); + decrement('parens'); + continue; + } + + /** + * Square brackets + */ + + if (value === '[') { + if (opts.nobracket === true || !remaining().includes(']')) { + if (opts.nobracket !== true && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('closing', ']')); + } + + value = `\\${value}`; + } else { + increment('brackets'); + } + + push({ type: 'bracket', value }); + continue; + } + + if (value === ']') { + if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { + push({ type: 'text', value, output: `\\${value}` }); + continue; + } + + if (state.brackets === 0) { + if (opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '[')); + } + + push({ type: 'text', value, output: `\\${value}` }); + continue; + } + + decrement('brackets'); + + const prevValue = prev.value.slice(1); + if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { + value = `/${value}`; + } + + prev.value += value; + append({ value }); + + // when literal brackets are explicitly disabled + // assume we should match with a regex character class + if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { + continue; + } + + const escaped = utils.escapeRegex(prev.value); + state.output = state.output.slice(0, -prev.value.length); + + // when literal brackets are explicitly enabled + // assume we should escape the brackets to match literal characters + if (opts.literalBrackets === true) { + state.output += escaped; + prev.value = escaped; + continue; + } + + // when the user specifies nothing, try to match both + prev.value = `(${capture}${escaped}|${prev.value})`; + state.output += prev.value; + continue; + } + + /** + * Braces + */ + + if (value === '{' && opts.nobrace !== true) { + increment('braces'); + + const open = { + type: 'brace', + value, + output: '(', + outputIndex: state.output.length, + tokensIndex: state.tokens.length + }; + + braces.push(open); + push(open); + continue; + } + + if (value === '}') { + const brace = braces[braces.length - 1]; + + if (opts.nobrace === true || !brace) { + push({ type: 'text', value, output: value }); + continue; + } + + let output = ')'; + + if (brace.dots === true) { + const arr = tokens.slice(); + const range = []; + + for (let i = arr.length - 1; i >= 0; i--) { + tokens.pop(); + if (arr[i].type === 'brace') { + break; + } + if (arr[i].type !== 'dots') { + range.unshift(arr[i].value); + } + } + + output = expandRange(range, opts); + state.backtrack = true; + } + + if (brace.comma !== true && brace.dots !== true) { + const out = state.output.slice(0, brace.outputIndex); + const toks = state.tokens.slice(brace.tokensIndex); + brace.value = brace.output = '\\{'; + value = output = '\\}'; + state.output = out; + for (const t of toks) { + state.output += (t.output || t.value); + } + } + + push({ type: 'brace', value, output }); + decrement('braces'); + braces.pop(); + continue; + } + + /** + * Pipes + */ + + if (value === '|') { + if (extglobs.length > 0) { + extglobs[extglobs.length - 1].conditions++; + } + push({ type: 'text', value }); + continue; + } + + /** + * Commas + */ + + if (value === ',') { + let output = value; + + const brace = braces[braces.length - 1]; + if (brace && stack[stack.length - 1] === 'braces') { + brace.comma = true; + output = '|'; + } + + push({ type: 'comma', value, output }); + continue; + } + + /** + * Slashes + */ + + if (value === '/') { + // if the beginning of the glob is "./", advance the start + // to the current index, and don't add the "./" characters + // to the state. This greatly simplifies lookbehinds when + // checking for BOS characters like "!" and "." (not "./") + if (prev.type === 'dot' && state.index === state.start + 1) { + state.start = state.index + 1; + state.consumed = ''; + state.output = ''; + tokens.pop(); + prev = bos; // reset "prev" to the first token + continue; + } + + push({ type: 'slash', value, output: SLASH_LITERAL }); + continue; + } + + /** + * Dots + */ + + if (value === '.') { + if (state.braces > 0 && prev.type === 'dot') { + if (prev.value === '.') prev.output = DOT_LITERAL; + const brace = braces[braces.length - 1]; + prev.type = 'dots'; + prev.output += value; + prev.value += value; + brace.dots = true; + continue; + } + + if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { + push({ type: 'text', value, output: DOT_LITERAL }); + continue; + } + + push({ type: 'dot', value, output: DOT_LITERAL }); + continue; + } + + /** + * Question marks + */ + + if (value === '?') { + const isGroup = prev && prev.value === '('; + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); + continue; + } + + if (prev && prev.type === 'paren') { + const next = peek(); + let output = value; + + if (next === '<' && !utils.supportsLookbehinds()) { + throw new Error('Node.js v10 or higher is required for regex lookbehinds'); + } + + if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { + output = `\\${value}`; + } + + push({ type: 'text', value, output }); + continue; + } + + if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { + push({ type: 'qmark', value, output: QMARK_NO_DOT }); + continue; + } + + push({ type: 'qmark', value, output: QMARK }); + continue; + } + + /** + * Exclamation + */ + + if (value === '!') { + if (opts.noextglob !== true && peek() === '(') { + if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { + extglobOpen('negate', value); + continue; + } + } + + if (opts.nonegate !== true && state.index === 0) { + negate(); + continue; + } + } + + /** + * Plus + */ + + if (value === '+') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('plus', value); + continue; + } + + if ((prev && prev.value === '(') || opts.regex === false) { + push({ type: 'plus', value, output: PLUS_LITERAL }); + continue; + } + + if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { + push({ type: 'plus', value }); + continue; + } + + push({ type: 'plus', value: PLUS_LITERAL }); + continue; + } + + /** + * Plain text + */ + + if (value === '@') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + push({ type: 'at', extglob: true, value, output: '' }); + continue; + } + + push({ type: 'text', value }); + continue; + } + + /** + * Plain text + */ + + if (value !== '*') { + if (value === '$' || value === '^') { + value = `\\${value}`; + } + + const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); + if (match) { + value += match[0]; + state.index += match[0].length; + } + + push({ type: 'text', value }); + continue; + } + + /** + * Stars + */ + + if (prev && (prev.type === 'globstar' || prev.star === true)) { + prev.type = 'star'; + prev.star = true; + prev.value += value; + prev.output = star; + state.backtrack = true; + state.globstar = true; + consume(value); + continue; + } + + let rest = remaining(); + if (opts.noextglob !== true && /^\([^?]/.test(rest)) { + extglobOpen('star', value); + continue; + } + + if (prev.type === 'star') { + if (opts.noglobstar === true) { + consume(value); + continue; + } + + const prior = prev.prev; + const before = prior.prev; + const isStart = prior.type === 'slash' || prior.type === 'bos'; + const afterStar = before && (before.type === 'star' || before.type === 'globstar'); + + if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { + push({ type: 'star', value, output: '' }); + continue; + } + + const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); + const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); + if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { + push({ type: 'star', value, output: '' }); + continue; + } + + // strip consecutive `/**/` + while (rest.slice(0, 3) === '/**') { + const after = input[state.index + 4]; + if (after && after !== '/') { + break; + } + rest = rest.slice(3); + consume('/**', 3); + } + + if (prior.type === 'bos' && eos()) { + prev.type = 'globstar'; + prev.value += value; + prev.output = globstar(opts); + state.output = prev.output; + state.globstar = true; + consume(value); + continue; + } + + if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; + + prev.type = 'globstar'; + prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); + prev.value += value; + state.globstar = true; + state.output += prior.output + prev.output; + consume(value); + continue; + } + + if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { + const end = rest[1] !== void 0 ? '|$' : ''; + + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; + + prev.type = 'globstar'; + prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; + prev.value += value; + + state.output += prior.output + prev.output; + state.globstar = true; + + consume(value + advance()); + + push({ type: 'slash', value: '/', output: '' }); + continue; + } + + if (prior.type === 'bos' && rest[0] === '/') { + prev.type = 'globstar'; + prev.value += value; + prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; + state.output = prev.output; + state.globstar = true; + consume(value + advance()); + push({ type: 'slash', value: '/', output: '' }); + continue; + } + + // remove single star from output + state.output = state.output.slice(0, -prev.output.length); + + // reset previous token to globstar + prev.type = 'globstar'; + prev.output = globstar(opts); + prev.value += value; + + // reset output with globstar + state.output += prev.output; + state.globstar = true; + consume(value); + continue; + } + + const token = { type: 'star', value, output: star }; + + if (opts.bash === true) { + token.output = '.*?'; + if (prev.type === 'bos' || prev.type === 'slash') { + token.output = nodot + token.output; + } + push(token); + continue; + } + + if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { + token.output = value; + push(token); + continue; + } + + if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { + if (prev.type === 'dot') { + state.output += NO_DOT_SLASH; + prev.output += NO_DOT_SLASH; + + } else if (opts.dot === true) { + state.output += NO_DOTS_SLASH; + prev.output += NO_DOTS_SLASH; + + } else { + state.output += nodot; + prev.output += nodot; + } + + if (peek() !== '*') { + state.output += ONE_CHAR; + prev.output += ONE_CHAR; + } + } + + push(token); + } + + while (state.brackets > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); + state.output = utils.escapeLast(state.output, '['); + decrement('brackets'); + } + + while (state.parens > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); + state.output = utils.escapeLast(state.output, '('); + decrement('parens'); + } + + while (state.braces > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); + state.output = utils.escapeLast(state.output, '{'); + decrement('braces'); + } + + if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { + push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); + } + + // rebuild the output if we had to backtrack at any point + if (state.backtrack === true) { + state.output = ''; + + for (const token of state.tokens) { + state.output += token.output != null ? token.output : token.value; + + if (token.suffix) { + state.output += token.suffix; + } + } + } + + return state; +}; + +/** + * Fast paths for creating regular expressions for common glob patterns. + * This can significantly speed up processing and has very little downside + * impact when none of the fast paths match. + */ + +parse.fastpaths = (input, options) => { + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + const len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } + + input = REPLACEMENTS[input] || input; + const win32 = utils.isWindows(options); + + // create constants based on platform, for windows or posix + const { + DOT_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOTS_SLASH, + STAR, + START_ANCHOR + } = constants.globChars(win32); + + const nodot = opts.dot ? NO_DOTS : NO_DOT; + const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; + const capture = opts.capture ? '' : '?:'; + const state = { negated: false, prefix: '' }; + let star = opts.bash === true ? '.*?' : STAR; + + if (opts.capture) { + star = `(${star})`; + } + + const globstar = opts => { + if (opts.noglobstar === true) return star; + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; + + const create = str => { + switch (str) { + case '*': + return `${nodot}${ONE_CHAR}${star}`; + + case '.*': + return `${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '*.*': + return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '*/*': + return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; + + case '**': + return nodot + globstar(opts); + + case '**/*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; + + case '**/*.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '**/.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; + + default: { + const match = /^(.*?)\.(\w+)$/.exec(str); + if (!match) return; + + const source = create(match[1]); + if (!source) return; + + return source + DOT_LITERAL + match[2]; + } + } + }; + + const output = utils.removePrefix(input, state); + let source = create(output); + + if (source && opts.strictSlashes !== true) { + source += `${SLASH_LITERAL}?`; + } + + return source; +}; + +module.exports = parse; diff --git a/node_modules/picomatch/lib/picomatch.js b/node_modules/picomatch/lib/picomatch.js new file mode 100644 index 0000000..782d809 --- /dev/null +++ b/node_modules/picomatch/lib/picomatch.js @@ -0,0 +1,342 @@ +'use strict'; + +const path = require('path'); +const scan = require('./scan'); +const parse = require('./parse'); +const utils = require('./utils'); +const constants = require('./constants'); +const isObject = val => val && typeof val === 'object' && !Array.isArray(val); + +/** + * Creates a matcher function from one or more glob patterns. The + * returned function takes a string to match as its first argument, + * and returns true if the string is a match. The returned matcher + * function also takes a boolean as the second argument that, when true, + * returns an object with additional information. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch(glob[, options]); + * + * const isMatch = picomatch('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @name picomatch + * @param {String|Array} `globs` One or more glob patterns. + * @param {Object=} `options` + * @return {Function=} Returns a matcher function. + * @api public + */ + +const picomatch = (glob, options, returnState = false) => { + if (Array.isArray(glob)) { + const fns = glob.map(input => picomatch(input, options, returnState)); + const arrayMatcher = str => { + for (const isMatch of fns) { + const state = isMatch(str); + if (state) return state; + } + return false; + }; + return arrayMatcher; + } + + const isState = isObject(glob) && glob.tokens && glob.input; + + if (glob === '' || (typeof glob !== 'string' && !isState)) { + throw new TypeError('Expected pattern to be a non-empty string'); + } + + const opts = options || {}; + const posix = utils.isWindows(options); + const regex = isState + ? picomatch.compileRe(glob, options) + : picomatch.makeRe(glob, options, false, true); + + const state = regex.state; + delete regex.state; + + let isIgnored = () => false; + if (opts.ignore) { + const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; + isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); + } + + const matcher = (input, returnObject = false) => { + const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); + const result = { glob, state, regex, posix, input, output, match, isMatch }; + + if (typeof opts.onResult === 'function') { + opts.onResult(result); + } + + if (isMatch === false) { + result.isMatch = false; + return returnObject ? result : false; + } + + if (isIgnored(input)) { + if (typeof opts.onIgnore === 'function') { + opts.onIgnore(result); + } + result.isMatch = false; + return returnObject ? result : false; + } + + if (typeof opts.onMatch === 'function') { + opts.onMatch(result); + } + return returnObject ? result : true; + }; + + if (returnState) { + matcher.state = state; + } + + return matcher; +}; + +/** + * Test `input` with the given `regex`. This is used by the main + * `picomatch()` function to test the input string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.test(input, regex[, options]); + * + * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); + * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } + * ``` + * @param {String} `input` String to test. + * @param {RegExp} `regex` + * @return {Object} Returns an object with matching info. + * @api public + */ + +picomatch.test = (input, regex, options, { glob, posix } = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected input to be a string'); + } + + if (input === '') { + return { isMatch: false, output: '' }; + } + + const opts = options || {}; + const format = opts.format || (posix ? utils.toPosixSlashes : null); + let match = input === glob; + let output = (match && format) ? format(input) : input; + + if (match === false) { + output = format ? format(input) : input; + match = output === glob; + } + + if (match === false || opts.capture === true) { + if (opts.matchBase === true || opts.basename === true) { + match = picomatch.matchBase(input, regex, options, posix); + } else { + match = regex.exec(output); + } + } + + return { isMatch: Boolean(match), match, output }; +}; + +/** + * Match the basename of a filepath. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.matchBase(input, glob[, options]); + * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true + * ``` + * @param {String} `input` String to test. + * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). + * @return {Boolean} + * @api public + */ + +picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { + const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); + return regex.test(path.basename(input)); +}; + +/** + * Returns true if **any** of the given glob `patterns` match the specified `string`. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.isMatch(string, patterns[, options]); + * + * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false + * ``` + * @param {String|Array} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ + +picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); + +/** + * Parse a glob pattern to create the source string for a regular + * expression. + * + * ```js + * const picomatch = require('picomatch'); + * const result = picomatch.parse(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as a regex source string. + * @api public + */ + +picomatch.parse = (pattern, options) => { + if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); + return parse(pattern, { ...options, fastpaths: false }); +}; + +/** + * Scan a glob pattern to separate the pattern into segments. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.scan(input[, options]); + * + * const result = picomatch.scan('!./foo/*.js'); + * console.log(result); + * { prefix: '!./', + * input: '!./foo/*.js', + * start: 3, + * base: 'foo', + * glob: '*.js', + * isBrace: false, + * isBracket: false, + * isGlob: true, + * isExtglob: false, + * isGlobstar: false, + * negated: true } + * ``` + * @param {String} `input` Glob pattern to scan. + * @param {Object} `options` + * @return {Object} Returns an object with + * @api public + */ + +picomatch.scan = (input, options) => scan(input, options); + +/** + * Compile a regular expression from the `state` object returned by the + * [parse()](#parse) method. + * + * @param {Object} `state` + * @param {Object} `options` + * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. + * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. + * @return {RegExp} + * @api public + */ + +picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { + if (returnOutput === true) { + return state.output; + } + + const opts = options || {}; + const prepend = opts.contains ? '' : '^'; + const append = opts.contains ? '' : '$'; + + let source = `${prepend}(?:${state.output})${append}`; + if (state && state.negated === true) { + source = `^(?!${source}).*$`; + } + + const regex = picomatch.toRegex(source, options); + if (returnState === true) { + regex.state = state; + } + + return regex; +}; + +/** + * Create a regular expression from a parsed glob pattern. + * + * ```js + * const picomatch = require('picomatch'); + * const state = picomatch.parse('*.js'); + * // picomatch.compileRe(state[, options]); + * + * console.log(picomatch.compileRe(state)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `state` The object returned from the `.parse` method. + * @param {Object} `options` + * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. + * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. + * @return {RegExp} Returns a regex created from the given pattern. + * @api public + */ + +picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { + if (!input || typeof input !== 'string') { + throw new TypeError('Expected a non-empty string'); + } + + let parsed = { negated: false, fastpaths: true }; + + if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { + parsed.output = parse.fastpaths(input, options); + } + + if (!parsed.output) { + parsed = parse(input, options); + } + + return picomatch.compileRe(parsed, options, returnOutput, returnState); +}; + +/** + * Create a regular expression from the given regex source string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.toRegex(source[, options]); + * + * const { output } = picomatch.parse('*.js'); + * console.log(picomatch.toRegex(output)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `source` Regular expression source string. + * @param {Object} `options` + * @return {RegExp} + * @api public + */ + +picomatch.toRegex = (source, options) => { + try { + const opts = options || {}; + return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); + } catch (err) { + if (options && options.debug === true) throw err; + return /$^/; + } +}; + +/** + * Picomatch constants. + * @return {Object} + */ + +picomatch.constants = constants; + +/** + * Expose "picomatch" + */ + +module.exports = picomatch; diff --git a/node_modules/picomatch/lib/scan.js b/node_modules/picomatch/lib/scan.js new file mode 100644 index 0000000..e59cd7a --- /dev/null +++ b/node_modules/picomatch/lib/scan.js @@ -0,0 +1,391 @@ +'use strict'; + +const utils = require('./utils'); +const { + CHAR_ASTERISK, /* * */ + CHAR_AT, /* @ */ + CHAR_BACKWARD_SLASH, /* \ */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_EXCLAMATION_MARK, /* ! */ + CHAR_FORWARD_SLASH, /* / */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_PLUS, /* + */ + CHAR_QUESTION_MARK, /* ? */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_RIGHT_SQUARE_BRACKET /* ] */ +} = require('./constants'); + +const isPathSeparator = code => { + return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; +}; + +const depth = token => { + if (token.isPrefix !== true) { + token.depth = token.isGlobstar ? Infinity : 1; + } +}; + +/** + * Quickly scans a glob pattern and returns an object with a handful of + * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), + * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not + * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). + * + * ```js + * const pm = require('picomatch'); + * console.log(pm.scan('foo/bar/*.js')); + * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {Object} Returns an object with tokens and regex source string. + * @api public + */ + +const scan = (input, options) => { + const opts = options || {}; + + const length = input.length - 1; + const scanToEnd = opts.parts === true || opts.scanToEnd === true; + const slashes = []; + const tokens = []; + const parts = []; + + let str = input; + let index = -1; + let start = 0; + let lastIndex = 0; + let isBrace = false; + let isBracket = false; + let isGlob = false; + let isExtglob = false; + let isGlobstar = false; + let braceEscaped = false; + let backslashes = false; + let negated = false; + let negatedExtglob = false; + let finished = false; + let braces = 0; + let prev; + let code; + let token = { value: '', depth: 0, isGlob: false }; + + const eos = () => index >= length; + const peek = () => str.charCodeAt(index + 1); + const advance = () => { + prev = code; + return str.charCodeAt(++index); + }; + + while (index < length) { + code = advance(); + let next; + + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + + if (code === CHAR_LEFT_CURLY_BRACE) { + braceEscaped = true; + } + continue; + } + + if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { + braces++; + + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } + + if (code === CHAR_LEFT_CURLY_BRACE) { + braces++; + continue; + } + + if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (braceEscaped !== true && code === CHAR_COMMA) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (code === CHAR_RIGHT_CURLY_BRACE) { + braces--; + + if (braces === 0) { + braceEscaped = false; + isBrace = token.isBrace = true; + finished = true; + break; + } + } + } + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (code === CHAR_FORWARD_SLASH) { + slashes.push(index); + tokens.push(token); + token = { value: '', depth: 0, isGlob: false }; + + if (finished === true) continue; + if (prev === CHAR_DOT && index === (start + 1)) { + start += 2; + continue; + } + + lastIndex = index + 1; + continue; + } + + if (opts.noext !== true) { + const isExtglobChar = code === CHAR_PLUS + || code === CHAR_AT + || code === CHAR_ASTERISK + || code === CHAR_QUESTION_MARK + || code === CHAR_EXCLAMATION_MARK; + + if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; + isExtglob = token.isExtglob = true; + finished = true; + if (code === CHAR_EXCLAMATION_MARK && index === start) { + negatedExtglob = true; + } + + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } + + if (code === CHAR_RIGHT_PARENTHESES) { + isGlob = token.isGlob = true; + finished = true; + break; + } + } + continue; + } + break; + } + } + + if (code === CHAR_ASTERISK) { + if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + break; + } + + if (code === CHAR_QUESTION_MARK) { + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + break; + } + + if (code === CHAR_LEFT_SQUARE_BRACKET) { + while (eos() !== true && (next = advance())) { + if (next === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } + + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + isBracket = token.isBracket = true; + isGlob = token.isGlob = true; + finished = true; + break; + } + } + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { + negated = token.negated = true; + start++; + continue; + } + + if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; + + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_LEFT_PARENTHESES) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } + + if (code === CHAR_RIGHT_PARENTHESES) { + finished = true; + break; + } + } + continue; + } + break; + } + + if (isGlob === true) { + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + } + + if (opts.noext === true) { + isExtglob = false; + isGlob = false; + } + + let base = str; + let prefix = ''; + let glob = ''; + + if (start > 0) { + prefix = str.slice(0, start); + str = str.slice(start); + lastIndex -= start; + } + + if (base && isGlob === true && lastIndex > 0) { + base = str.slice(0, lastIndex); + glob = str.slice(lastIndex); + } else if (isGlob === true) { + base = ''; + glob = str; + } else { + base = str; + } + + if (base && base !== '' && base !== '/' && base !== str) { + if (isPathSeparator(base.charCodeAt(base.length - 1))) { + base = base.slice(0, -1); + } + } + + if (opts.unescape === true) { + if (glob) glob = utils.removeBackslashes(glob); + + if (base && backslashes === true) { + base = utils.removeBackslashes(base); + } + } + + const state = { + prefix, + input, + start, + base, + glob, + isBrace, + isBracket, + isGlob, + isExtglob, + isGlobstar, + negated, + negatedExtglob + }; + + if (opts.tokens === true) { + state.maxDepth = 0; + if (!isPathSeparator(code)) { + tokens.push(token); + } + state.tokens = tokens; + } + + if (opts.parts === true || opts.tokens === true) { + let prevIndex; + + for (let idx = 0; idx < slashes.length; idx++) { + const n = prevIndex ? prevIndex + 1 : start; + const i = slashes[idx]; + const value = input.slice(n, i); + if (opts.tokens) { + if (idx === 0 && start !== 0) { + tokens[idx].isPrefix = true; + tokens[idx].value = prefix; + } else { + tokens[idx].value = value; + } + depth(tokens[idx]); + state.maxDepth += tokens[idx].depth; + } + if (idx !== 0 || value !== '') { + parts.push(value); + } + prevIndex = i; + } + + if (prevIndex && prevIndex + 1 < input.length) { + const value = input.slice(prevIndex + 1); + parts.push(value); + + if (opts.tokens) { + tokens[tokens.length - 1].value = value; + depth(tokens[tokens.length - 1]); + state.maxDepth += tokens[tokens.length - 1].depth; + } + } + + state.slashes = slashes; + state.parts = parts; + } + + return state; +}; + +module.exports = scan; diff --git a/node_modules/picomatch/lib/utils.js b/node_modules/picomatch/lib/utils.js new file mode 100644 index 0000000..c3ca766 --- /dev/null +++ b/node_modules/picomatch/lib/utils.js @@ -0,0 +1,64 @@ +'use strict'; + +const path = require('path'); +const win32 = process.platform === 'win32'; +const { + REGEX_BACKSLASH, + REGEX_REMOVE_BACKSLASH, + REGEX_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_GLOBAL +} = require('./constants'); + +exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); +exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); +exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); +exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); +exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); + +exports.removeBackslashes = str => { + return str.replace(REGEX_REMOVE_BACKSLASH, match => { + return match === '\\' ? '' : match; + }); +}; + +exports.supportsLookbehinds = () => { + const segs = process.version.slice(1).split('.').map(Number); + if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { + return true; + } + return false; +}; + +exports.isWindows = options => { + if (options && typeof options.windows === 'boolean') { + return options.windows; + } + return win32 === true || path.sep === '\\'; +}; + +exports.escapeLast = (input, char, lastIdx) => { + const idx = input.lastIndexOf(char, lastIdx); + if (idx === -1) return input; + if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); + return `${input.slice(0, idx)}\\${input.slice(idx)}`; +}; + +exports.removePrefix = (input, state = {}) => { + let output = input; + if (output.startsWith('./')) { + output = output.slice(2); + state.prefix = './'; + } + return output; +}; + +exports.wrapOutput = (input, state = {}, options = {}) => { + const prepend = options.contains ? '' : '^'; + const append = options.contains ? '' : '$'; + + let output = `${prepend}(?:${input})${append}`; + if (state.negated === true) { + output = `(?:^(?!${output}).*$)`; + } + return output; +}; diff --git a/node_modules/picomatch/package.json b/node_modules/picomatch/package.json new file mode 100644 index 0000000..3db22d4 --- /dev/null +++ b/node_modules/picomatch/package.json @@ -0,0 +1,81 @@ +{ + "name": "picomatch", + "description": "Blazing fast and accurate glob matcher written in JavaScript, with no dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.", + "version": "2.3.1", + "homepage": "https://github.com/micromatch/picomatch", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "funding": "https://github.com/sponsors/jonschlinkert", + "repository": "micromatch/picomatch", + "bugs": { + "url": "https://github.com/micromatch/picomatch/issues" + }, + "license": "MIT", + "files": [ + "index.js", + "lib" + ], + "main": "index.js", + "engines": { + "node": ">=8.6" + }, + "scripts": { + "lint": "eslint --cache --cache-location node_modules/.cache/.eslintcache --report-unused-disable-directives --ignore-path .gitignore .", + "mocha": "mocha --reporter dot", + "test": "npm run lint && npm run mocha", + "test:ci": "npm run test:cover", + "test:cover": "nyc npm run mocha" + }, + "devDependencies": { + "eslint": "^6.8.0", + "fill-range": "^7.0.1", + "gulp-format-md": "^2.0.0", + "mocha": "^6.2.2", + "nyc": "^15.0.0", + "time-require": "github:jonschlinkert/time-require" + }, + "keywords": [ + "glob", + "match", + "picomatch" + ], + "nyc": { + "reporter": [ + "html", + "lcov", + "text-summary" + ] + }, + "verb": { + "toc": { + "render": true, + "method": "preWrite", + "maxdepth": 3 + }, + "layout": "empty", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + }, + "related": { + "list": [ + "braces", + "micromatch" + ] + }, + "reflinks": [ + "braces", + "expand-brackets", + "extglob", + "fill-range", + "micromatch", + "minimatch", + "nanomatch", + "picomatch" + ] + } +} diff --git a/node_modules/readdirp/LICENSE b/node_modules/readdirp/LICENSE new file mode 100644 index 0000000..037cbb4 --- /dev/null +++ b/node_modules/readdirp/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller (https://paulmillr.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/readdirp/README.md b/node_modules/readdirp/README.md new file mode 100644 index 0000000..465593c --- /dev/null +++ b/node_modules/readdirp/README.md @@ -0,0 +1,122 @@ +# readdirp [![Weekly downloads](https://img.shields.io/npm/dw/readdirp.svg)](https://github.com/paulmillr/readdirp) + +Recursive version of [fs.readdir](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback). Exposes a **stream API** and a **promise API**. + + +```sh +npm install readdirp +``` + +```javascript +const readdirp = require('readdirp'); + +// Use streams to achieve small RAM & CPU footprint. +// 1) Streams example with for-await. +for await (const entry of readdirp('.')) { + const {path} = entry; + console.log(`${JSON.stringify({path})}`); +} + +// 2) Streams example, non for-await. +// Print out all JS files along with their size within the current folder & subfolders. +readdirp('.', {fileFilter: '*.js', alwaysStat: true}) + .on('data', (entry) => { + const {path, stats: {size}} = entry; + console.log(`${JSON.stringify({path, size})}`); + }) + // Optionally call stream.destroy() in `warn()` in order to abort and cause 'close' to be emitted + .on('warn', error => console.error('non-fatal error', error)) + .on('error', error => console.error('fatal error', error)) + .on('end', () => console.log('done')); + +// 3) Promise example. More RAM and CPU than streams / for-await. +const files = await readdirp.promise('.'); +console.log(files.map(file => file.path)); + +// Other options. +readdirp('test', { + fileFilter: '*.js', + directoryFilter: ['!.git', '!*modules'] + // directoryFilter: (di) => di.basename.length === 9 + type: 'files_directories', + depth: 1 +}); +``` + +For more examples, check out `examples` directory. + +## API + +`const stream = readdirp(root[, options])` — **Stream API** + +- Reads given root recursively and returns a `stream` of [entry infos](#entryinfo) +- Optionally can be used like `for await (const entry of stream)` with node.js 10+ (`asyncIterator`). +- `on('data', (entry) => {})` [entry info](#entryinfo) for every file / dir. +- `on('warn', (error) => {})` non-fatal `Error` that prevents a file / dir from being processed. Example: inaccessible to the user. +- `on('error', (error) => {})` fatal `Error` which also ends the stream. Example: illegal options where passed. +- `on('end')` — we are done. Called when all entries were found and no more will be emitted. +- `on('close')` — stream is destroyed via `stream.destroy()`. + Could be useful if you want to manually abort even on a non fatal error. + At that point the stream is no longer `readable` and no more entries, warning or errors are emitted +- To learn more about streams, consult the very detailed [nodejs streams documentation](https://nodejs.org/api/stream.html) + or the [stream-handbook](https://github.com/substack/stream-handbook) + +`const entries = await readdirp.promise(root[, options])` — **Promise API**. Returns a list of [entry infos](#entryinfo). + +First argument is awalys `root`, path in which to start reading and recursing into subdirectories. + +### options + +- `fileFilter: ["*.js"]`: filter to include or exclude files. A `Function`, Glob string or Array of glob strings. + - **Function**: a function that takes an entry info as a parameter and returns true to include or false to exclude the entry + - **Glob string**: a string (e.g., `*.js`) which is matched using [picomatch](https://github.com/micromatch/picomatch), so go there for more + information. Globstars (`**`) are not supported since specifying a recursive pattern for an already recursive function doesn't make sense. Negated globs (as explained in the minimatch documentation) are allowed, e.g., `!*.txt` matches everything but text files. + - **Array of glob strings**: either need to be all inclusive or all exclusive (negated) patterns otherwise an error is thrown. + `['*.json', '*.js']` includes all JavaScript and Json files. + `['!.git', '!node_modules']` includes all directories except the '.git' and 'node_modules'. + - Directories that do not pass a filter will not be recursed into. +- `directoryFilter: ['!.git']`: filter to include/exclude directories found and to recurse into. Directories that do not pass a filter will not be recursed into. +- `depth: 5`: depth at which to stop recursing even if more subdirectories are found +- `type: 'files'`: determines if data events on the stream should be emitted for `'files'` (default), `'directories'`, `'files_directories'`, or `'all'`. Setting to `'all'` will also include entries for other types of file descriptors like character devices, unix sockets and named pipes. +- `alwaysStat: false`: always return `stats` property for every file. Default is `false`, readdirp will return `Dirent` entries. Setting it to `true` can double readdir execution time - use it only when you need file `size`, `mtime` etc. Cannot be enabled on node <10.10.0. +- `lstat: false`: include symlink entries in the stream along with files. When `true`, `fs.lstat` would be used instead of `fs.stat` + +### `EntryInfo` + +Has the following properties: + +- `path: 'assets/javascripts/react.js'`: path to the file/directory (relative to given root) +- `fullPath: '/Users/dev/projects/app/assets/javascripts/react.js'`: full path to the file/directory found +- `basename: 'react.js'`: name of the file/directory +- `dirent: fs.Dirent`: built-in [dir entry object](https://nodejs.org/api/fs.html#fs_class_fs_dirent) - only with `alwaysStat: false` +- `stats: fs.Stats`: built in [stat object](https://nodejs.org/api/fs.html#fs_class_fs_stats) - only with `alwaysStat: true` + +## Changelog + +- 3.5 (Oct 13, 2020) disallows recursive directory-based symlinks. + Before, it could have entered infinite loop. +- 3.4 (Mar 19, 2020) adds support for directory-based symlinks. +- 3.3 (Dec 6, 2019) stabilizes RAM consumption and enables perf management with `highWaterMark` option. Fixes race conditions related to `for-await` looping. +- 3.2 (Oct 14, 2019) improves performance by 250% and makes streams implementation more idiomatic. +- 3.1 (Jul 7, 2019) brings `bigint` support to `stat` output on Windows. This is backwards-incompatible for some cases. Be careful. It you use it incorrectly, you'll see "TypeError: Cannot mix BigInt and other types, use explicit conversions". +- 3.0 brings huge performance improvements and stream backpressure support. +- Upgrading 2.x to 3.x: + - Signature changed from `readdirp(options)` to `readdirp(root, options)` + - Replaced callback API with promise API. + - Renamed `entryType` option to `type` + - Renamed `entryType: 'both'` to `'files_directories'` + - `EntryInfo` + - Renamed `stat` to `stats` + - Emitted only when `alwaysStat: true` + - `dirent` is emitted instead of `stats` by default with `alwaysStat: false` + - Renamed `name` to `basename` + - Removed `parentDir` and `fullParentDir` properties +- Supported node.js versions: + - 3.x: node 8+ + - 2.x: node 0.6+ + +## License + +Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller () + +MIT License, see [LICENSE](LICENSE) file. diff --git a/node_modules/readdirp/index.d.ts b/node_modules/readdirp/index.d.ts new file mode 100644 index 0000000..cbbd76c --- /dev/null +++ b/node_modules/readdirp/index.d.ts @@ -0,0 +1,43 @@ +// TypeScript Version: 3.2 + +/// + +import * as fs from 'fs'; +import { Readable } from 'stream'; + +declare namespace readdir { + interface EntryInfo { + path: string; + fullPath: string; + basename: string; + stats?: fs.Stats; + dirent?: fs.Dirent; + } + + interface ReaddirpOptions { + root?: string; + fileFilter?: string | string[] | ((entry: EntryInfo) => boolean); + directoryFilter?: string | string[] | ((entry: EntryInfo) => boolean); + type?: 'files' | 'directories' | 'files_directories' | 'all'; + lstat?: boolean; + depth?: number; + alwaysStat?: boolean; + } + + interface ReaddirpStream extends Readable, AsyncIterable { + read(): EntryInfo; + [Symbol.asyncIterator](): AsyncIterableIterator; + } + + function promise( + root: string, + options?: ReaddirpOptions + ): Promise; +} + +declare function readdir( + root: string, + options?: readdir.ReaddirpOptions +): readdir.ReaddirpStream; + +export = readdir; diff --git a/node_modules/readdirp/index.js b/node_modules/readdirp/index.js new file mode 100644 index 0000000..cf739b2 --- /dev/null +++ b/node_modules/readdirp/index.js @@ -0,0 +1,287 @@ +'use strict'; + +const fs = require('fs'); +const { Readable } = require('stream'); +const sysPath = require('path'); +const { promisify } = require('util'); +const picomatch = require('picomatch'); + +const readdir = promisify(fs.readdir); +const stat = promisify(fs.stat); +const lstat = promisify(fs.lstat); +const realpath = promisify(fs.realpath); + +/** + * @typedef {Object} EntryInfo + * @property {String} path + * @property {String} fullPath + * @property {fs.Stats=} stats + * @property {fs.Dirent=} dirent + * @property {String} basename + */ + +const BANG = '!'; +const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR'; +const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]); +const FILE_TYPE = 'files'; +const DIR_TYPE = 'directories'; +const FILE_DIR_TYPE = 'files_directories'; +const EVERYTHING_TYPE = 'all'; +const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]; + +const isNormalFlowError = error => NORMAL_FLOW_ERRORS.has(error.code); +const [maj, min] = process.versions.node.split('.').slice(0, 2).map(n => Number.parseInt(n, 10)); +const wantBigintFsStats = process.platform === 'win32' && (maj > 10 || (maj === 10 && min >= 5)); + +const normalizeFilter = filter => { + if (filter === undefined) return; + if (typeof filter === 'function') return filter; + + if (typeof filter === 'string') { + const glob = picomatch(filter.trim()); + return entry => glob(entry.basename); + } + + if (Array.isArray(filter)) { + const positive = []; + const negative = []; + for (const item of filter) { + const trimmed = item.trim(); + if (trimmed.charAt(0) === BANG) { + negative.push(picomatch(trimmed.slice(1))); + } else { + positive.push(picomatch(trimmed)); + } + } + + if (negative.length > 0) { + if (positive.length > 0) { + return entry => + positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename)); + } + return entry => !negative.some(f => f(entry.basename)); + } + return entry => positive.some(f => f(entry.basename)); + } +}; + +class ReaddirpStream extends Readable { + static get defaultOptions() { + return { + root: '.', + /* eslint-disable no-unused-vars */ + fileFilter: (path) => true, + directoryFilter: (path) => true, + /* eslint-enable no-unused-vars */ + type: FILE_TYPE, + lstat: false, + depth: 2147483648, + alwaysStat: false + }; + } + + constructor(options = {}) { + super({ + objectMode: true, + autoDestroy: true, + highWaterMark: options.highWaterMark || 4096 + }); + const opts = { ...ReaddirpStream.defaultOptions, ...options }; + const { root, type } = opts; + + this._fileFilter = normalizeFilter(opts.fileFilter); + this._directoryFilter = normalizeFilter(opts.directoryFilter); + + const statMethod = opts.lstat ? lstat : stat; + // Use bigint stats if it's windows and stat() supports options (node 10+). + if (wantBigintFsStats) { + this._stat = path => statMethod(path, { bigint: true }); + } else { + this._stat = statMethod; + } + + this._maxDepth = opts.depth; + this._wantsDir = [DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); + this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); + this._wantsEverything = type === EVERYTHING_TYPE; + this._root = sysPath.resolve(root); + this._isDirent = ('Dirent' in fs) && !opts.alwaysStat; + this._statsProp = this._isDirent ? 'dirent' : 'stats'; + this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent }; + + // Launch stream with one parent, the root dir. + this.parents = [this._exploreDir(root, 1)]; + this.reading = false; + this.parent = undefined; + } + + async _read(batch) { + if (this.reading) return; + this.reading = true; + + try { + while (!this.destroyed && batch > 0) { + const { path, depth, files = [] } = this.parent || {}; + + if (files.length > 0) { + const slice = files.splice(0, batch).map(dirent => this._formatEntry(dirent, path)); + for (const entry of await Promise.all(slice)) { + if (this.destroyed) return; + + const entryType = await this._getEntryType(entry); + if (entryType === 'directory' && this._directoryFilter(entry)) { + if (depth <= this._maxDepth) { + this.parents.push(this._exploreDir(entry.fullPath, depth + 1)); + } + + if (this._wantsDir) { + this.push(entry); + batch--; + } + } else if ((entryType === 'file' || this._includeAsFile(entry)) && this._fileFilter(entry)) { + if (this._wantsFile) { + this.push(entry); + batch--; + } + } + } + } else { + const parent = this.parents.pop(); + if (!parent) { + this.push(null); + break; + } + this.parent = await parent; + if (this.destroyed) return; + } + } + } catch (error) { + this.destroy(error); + } finally { + this.reading = false; + } + } + + async _exploreDir(path, depth) { + let files; + try { + files = await readdir(path, this._rdOptions); + } catch (error) { + this._onError(error); + } + return { files, depth, path }; + } + + async _formatEntry(dirent, path) { + let entry; + try { + const basename = this._isDirent ? dirent.name : dirent; + const fullPath = sysPath.resolve(sysPath.join(path, basename)); + entry = { path: sysPath.relative(this._root, fullPath), fullPath, basename }; + entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath); + } catch (err) { + this._onError(err); + } + return entry; + } + + _onError(err) { + if (isNormalFlowError(err) && !this.destroyed) { + this.emit('warn', err); + } else { + this.destroy(err); + } + } + + async _getEntryType(entry) { + // entry may be undefined, because a warning or an error were emitted + // and the statsProp is undefined + const stats = entry && entry[this._statsProp]; + if (!stats) { + return; + } + if (stats.isFile()) { + return 'file'; + } + if (stats.isDirectory()) { + return 'directory'; + } + if (stats && stats.isSymbolicLink()) { + const full = entry.fullPath; + try { + const entryRealPath = await realpath(full); + const entryRealPathStats = await lstat(entryRealPath); + if (entryRealPathStats.isFile()) { + return 'file'; + } + if (entryRealPathStats.isDirectory()) { + const len = entryRealPath.length; + if (full.startsWith(entryRealPath) && full.substr(len, 1) === sysPath.sep) { + const recursiveError = new Error( + `Circular symlink detected: "${full}" points to "${entryRealPath}"` + ); + recursiveError.code = RECURSIVE_ERROR_CODE; + return this._onError(recursiveError); + } + return 'directory'; + } + } catch (error) { + this._onError(error); + } + } + } + + _includeAsFile(entry) { + const stats = entry && entry[this._statsProp]; + + return stats && this._wantsEverything && !stats.isDirectory(); + } +} + +/** + * @typedef {Object} ReaddirpArguments + * @property {Function=} fileFilter + * @property {Function=} directoryFilter + * @property {String=} type + * @property {Number=} depth + * @property {String=} root + * @property {Boolean=} lstat + * @property {Boolean=} bigint + */ + +/** + * Main function which ends up calling readdirRec and reads all files and directories in given root recursively. + * @param {String} root Root directory + * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth + */ +const readdirp = (root, options = {}) => { + let type = options.entryType || options.type; + if (type === 'both') type = FILE_DIR_TYPE; // backwards-compatibility + if (type) options.type = type; + if (!root) { + throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)'); + } else if (typeof root !== 'string') { + throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)'); + } else if (type && !ALL_TYPES.includes(type)) { + throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`); + } + + options.root = root; + return new ReaddirpStream(options); +}; + +const readdirpPromise = (root, options = {}) => { + return new Promise((resolve, reject) => { + const files = []; + readdirp(root, options) + .on('data', entry => files.push(entry)) + .on('end', () => resolve(files)) + .on('error', error => reject(error)); + }); +}; + +readdirp.promise = readdirpPromise; +readdirp.ReaddirpStream = ReaddirpStream; +readdirp.default = readdirp; + +module.exports = readdirp; diff --git a/node_modules/readdirp/package.json b/node_modules/readdirp/package.json new file mode 100644 index 0000000..dba5388 --- /dev/null +++ b/node_modules/readdirp/package.json @@ -0,0 +1,122 @@ +{ + "name": "readdirp", + "description": "Recursive version of fs.readdir with streaming API.", + "version": "3.6.0", + "homepage": "https://github.com/paulmillr/readdirp", + "repository": { + "type": "git", + "url": "git://github.com/paulmillr/readdirp.git" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/paulmillr/readdirp/issues" + }, + "author": "Thorsten Lorenz (thlorenz.com)", + "contributors": [ + "Thorsten Lorenz (thlorenz.com)", + "Paul Miller (https://paulmillr.com)" + ], + "main": "index.js", + "engines": { + "node": ">=8.10.0" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "recursive", + "fs", + "stream", + "streams", + "readdir", + "filesystem", + "find", + "filter" + ], + "scripts": { + "dtslint": "dtslint", + "nyc": "nyc", + "mocha": "mocha --exit", + "lint": "eslint --report-unused-disable-directives --ignore-path .gitignore .", + "test": "npm run lint && nyc npm run mocha" + }, + "dependencies": { + "picomatch": "^2.2.1" + }, + "devDependencies": { + "@types/node": "^14", + "chai": "^4.2", + "chai-subset": "^1.6", + "dtslint": "^3.3.0", + "eslint": "^7.0.0", + "mocha": "^7.1.1", + "nyc": "^15.0.0", + "rimraf": "^3.0.0", + "typescript": "^4.0.3" + }, + "nyc": { + "reporter": [ + "html", + "text" + ] + }, + "eslintConfig": { + "root": true, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 9, + "sourceType": "script" + }, + "env": { + "node": true, + "es6": true + }, + "rules": { + "array-callback-return": "error", + "no-empty": [ + "error", + { + "allowEmptyCatch": true + } + ], + "no-else-return": [ + "error", + { + "allowElseIf": false + } + ], + "no-lonely-if": "error", + "no-var": "error", + "object-shorthand": "error", + "prefer-arrow-callback": [ + "error", + { + "allowNamedFunctions": true + } + ], + "prefer-const": [ + "error", + { + "ignoreReadBeforeAssign": true + } + ], + "prefer-destructuring": [ + "error", + { + "object": true, + "array": false + } + ], + "prefer-spread": "error", + "prefer-template": "error", + "radix": "error", + "semi": "error", + "strict": "error", + "quotes": [ + "error", + "single" + ] + } + } +} diff --git a/node_modules/regexparam/dist/index.js b/node_modules/regexparam/dist/index.js new file mode 100644 index 0000000..e7858ba --- /dev/null +++ b/node_modules/regexparam/dist/index.js @@ -0,0 +1,39 @@ +function parse(str, loose) { + if (str instanceof RegExp) return { keys:false, pattern:str }; + var c, o, tmp, ext, keys=[], pattern='', arr = str.split('/'); + arr[0] || arr.shift(); + + while (tmp = arr.shift()) { + c = tmp[0]; + if (c === '*') { + keys.push('wild'); + pattern += '/(.*)'; + } else if (c === ':') { + o = tmp.indexOf('?', 1); + ext = tmp.indexOf('.', 1); + keys.push( tmp.substring(1, !!~o ? o : !!~ext ? ext : tmp.length) ); + pattern += !!~o && !~ext ? '(?:/([^/]+?))?' : '/([^/]+?)'; + if (!!~ext) pattern += (!!~o ? '?' : '') + '\\' + tmp.substring(ext); + } else { + pattern += '/' + tmp; + } + } + + return { + keys: keys, + pattern: new RegExp('^' + pattern + (loose ? '(?=$|\/)' : '\/?$'), 'i') + }; +} + +var RGX = /(\/|^)([:*][^/]*?)(\?)?(?=[/.]|$)/g; + +// error if key missing? +function inject(route, values) { + return route.replace(RGX, (x, lead, key, optional) => { + x = values[key=='*' ? 'wild' : key.substring(1)]; + return x ? '/'+x : (optional || key=='*') ? '' : '/' + key; + }); +} + +exports.inject = inject; +exports.parse = parse; \ No newline at end of file diff --git a/node_modules/regexparam/dist/index.min.js b/node_modules/regexparam/dist/index.min.js new file mode 100644 index 0000000..e72296c --- /dev/null +++ b/node_modules/regexparam/dist/index.min.js @@ -0,0 +1 @@ +!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(e.regexparam={})}(this,(function(e){var n=/(\/|^)([:*][^/]*?)(\?)?(?=[/.]|$)/g;e.inject=function(e,t){return e.replace(n,(e,n,i,r)=>(e=t["*"==i?"wild":i.substring(1)])?"/"+e:r||"*"==i?"":"/"+i)},e.parse=function(e,n){if(e instanceof RegExp)return{keys:!1,pattern:e};var t,i,r,f,s=[],p="",o=e.split("/");for(o[0]||o.shift();r=o.shift();)"*"===(t=r[0])?(s.push("wild"),p+="/(.*)"):":"===t?(i=r.indexOf("?",1),f=r.indexOf(".",1),s.push(r.substring(1,~i?i:~f?f:r.length)),p+=~i&&!~f?"(?:/([^/]+?))?":"/([^/]+?)",~f&&(p+=(~i?"?":"")+"\\"+r.substring(f))):p+="/"+r;return{keys:s,pattern:new RegExp("^"+p+(n?"(?=$|/)":"/?$"),"i")}}})); \ No newline at end of file diff --git a/node_modules/regexparam/dist/index.mjs b/node_modules/regexparam/dist/index.mjs new file mode 100644 index 0000000..4bc4035 --- /dev/null +++ b/node_modules/regexparam/dist/index.mjs @@ -0,0 +1,36 @@ +export function parse(str, loose) { + if (str instanceof RegExp) return { keys:false, pattern:str }; + var c, o, tmp, ext, keys=[], pattern='', arr = str.split('/'); + arr[0] || arr.shift(); + + while (tmp = arr.shift()) { + c = tmp[0]; + if (c === '*') { + keys.push('wild'); + pattern += '/(.*)'; + } else if (c === ':') { + o = tmp.indexOf('?', 1); + ext = tmp.indexOf('.', 1); + keys.push( tmp.substring(1, !!~o ? o : !!~ext ? ext : tmp.length) ); + pattern += !!~o && !~ext ? '(?:/([^/]+?))?' : '/([^/]+?)'; + if (!!~ext) pattern += (!!~o ? '?' : '') + '\\' + tmp.substring(ext); + } else { + pattern += '/' + tmp; + } + } + + return { + keys: keys, + pattern: new RegExp('^' + pattern + (loose ? '(?=$|\/)' : '\/?$'), 'i') + }; +} + +var RGX = /(\/|^)([:*][^/]*?)(\?)?(?=[/.]|$)/g; + +// error if key missing? +export function inject(route, values) { + return route.replace(RGX, (x, lead, key, optional) => { + x = values[key=='*' ? 'wild' : key.substring(1)]; + return x ? '/'+x : (optional || key=='*') ? '' : '/' + key; + }); +} diff --git a/node_modules/regexparam/index.d.ts b/node_modules/regexparam/index.d.ts new file mode 100644 index 0000000..5eaf8d2 --- /dev/null +++ b/node_modules/regexparam/index.d.ts @@ -0,0 +1,26 @@ +export function parse(route: string, loose?: boolean): { + keys: string[]; + pattern: RegExp; +} + +export function parse(route: RegExp): { + keys: false; + pattern: RegExp; +} + +export type RouteParams = + T extends `${infer Prev}/*/${infer Rest}` + ? RouteParams & { wild: string } & RouteParams + : T extends `${string}:${infer P}?/${infer Rest}` + ? { [K in P]?: string } & RouteParams + : T extends `${string}:${infer P}/${infer Rest}` + ? { [K in P]: string } & RouteParams + : T extends `${string}:${infer P}?` + ? { [K in P]?: string } + : T extends `${string}:${infer P}` + ? { [K in P]: string } + : T extends `${string}*` + ? { wild: string } + : {}; + +export function inject(route: T, values: RouteParams): string; diff --git a/node_modules/regexparam/license b/node_modules/regexparam/license new file mode 100644 index 0000000..a3f96f8 --- /dev/null +++ b/node_modules/regexparam/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Luke Edwards (lukeed.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/regexparam/package.json b/node_modules/regexparam/package.json new file mode 100644 index 0000000..3a968e1 --- /dev/null +++ b/node_modules/regexparam/package.json @@ -0,0 +1,48 @@ +{ + "name": "regexparam", + "version": "2.0.2", + "repository": "lukeed/regexparam", + "description": "A tiny (394B) utility that converts route patterns into RegExp. Limited alternative to `path-to-regexp` 🙇‍", + "unpkg": "dist/index.min.js", + "module": "dist/index.mjs", + "main": "dist/index.js", + "types": "index.d.ts", + "license": "MIT", + "author": { + "name": "Luke Edwards", + "email": "luke.edwards05@gmail.com", + "url": "https://lukeed.com" + }, + "engines": { + "node": ">=8" + }, + "scripts": { + "build": "bundt", + "test": "uvu -r esm test" + }, + "exports": { + ".": { + "types": "./index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js", + "default": "./dist/index.js" + }, + "./package.json": "./package.json" + }, + "files": [ + "*.d.ts", + "dist" + ], + "keywords": [ + "regexp", + "route", + "routing", + "inject", + "parse" + ], + "devDependencies": { + "bundt": "1.1.2", + "esm": "3.2.25", + "uvu": "0.5.1" + } +} diff --git a/node_modules/regexparam/readme.md b/node_modules/regexparam/readme.md new file mode 100644 index 0000000..63ff81c --- /dev/null +++ b/node_modules/regexparam/readme.md @@ -0,0 +1,237 @@ +# regexparam [![CI](https://github.com/lukeed/regexparam/actions/workflows/ci.yml/badge.svg)](https://github.com/lukeed/regexparam/actions/workflows/ci.yml) + +> A tiny (394B) utility that converts route patterns into RegExp. Limited alternative to [`path-to-regexp`](https://github.com/pillarjs/path-to-regexp) 🙇 + +With `regexparam`, you may turn a pathing string (eg, `/users/:id`) into a regular expression. + +An object with shape of `{ keys, pattern }` is returned, where `pattern` is the `RegExp` and `keys` is an array of your parameter name(s) in the order that they appeared. + +Unlike [`path-to-regexp`](https://github.com/pillarjs/path-to-regexp), this module does not create a `keys` dictionary, nor mutate an existing variable. Also, this only ships a parser, which only accept strings. Similarly, and most importantly, `regexparam` **only** handles basic pathing operators: + +* Static (`/foo`, `/foo/bar`) +* Parameter (`/:title`, `/books/:title`, `/books/:genre/:title`) +* Parameter w/ Suffix (`/movies/:title.mp4`, `/movies/:title.(mp4|mov)`) +* Optional Parameters (`/:title?`, `/books/:title?`, `/books/:genre/:title?`) +* Wildcards (`*`, `/books/*`, `/books/:genre/*`) + +This module exposes three module definitions: + +* **CommonJS**: [`dist/index.js`](https://unpkg.com/regexparam/dist/index.js) +* **ESModule**: [`dist/index.mjs`](https://unpkg.com/regexparam/dist/index.mjs) +* **UMD**: [`dist/index.min.js`](https://unpkg.com/regexparam/dist/index.min.js) + +## Install + +``` +$ npm install --save regexparam +``` + + +## Usage + +```js +import { parse, inject } from 'regexparam'; + +// Example param-assignment +function exec(path, result) { + let i=0, out={}; + let matches = result.pattern.exec(path); + while (i < result.keys.length) { + out[ result.keys[i] ] = matches[++i] || null; + } + return out; +} + + +// Parameter, with Optional Parameter +// --- +let foo = parse('/books/:genre/:title?') +// foo.pattern => /^\/books\/([^\/]+?)(?:\/([^\/]+?))?\/?$/i +// foo.keys => ['genre', 'title'] + +foo.pattern.test('/books/horror'); //=> true +foo.pattern.test('/books/horror/goosebumps'); //=> true + +exec('/books/horror', foo); +//=> { genre: 'horror', title: null } + +exec('/books/horror/goosebumps', foo); +//=> { genre: 'horror', title: 'goosebumps' } + + +// Parameter, with suffix +// --- +let bar = parse('/movies/:title.(mp4|mov)'); +// bar.pattern => /^\/movies\/([^\/]+?)\.(mp4|mov)\/?$/i +// bar.keys => ['title'] + +bar.pattern.test('/movies/narnia'); //=> false +bar.pattern.test('/movies/narnia.mp3'); //=> false +bar.pattern.test('/movies/narnia.mp4'); //=> true + +exec('/movies/narnia.mp4', bar); +//=> { title: 'narnia' } + + +// Wildcard +// --- +let baz = parse('users/*'); +// baz.pattern => /^\/users\/(.*)\/?$/i +// baz.keys => ['wild'] + +baz.pattern.test('/users'); //=> false +baz.pattern.test('/users/lukeed'); //=> true + +exec('/users/lukeed/repos/new', baz); +//=> { wild: 'lukeed/repos/new' } + + +// Injecting +// --- + +inject('/users/:id', { + id: 'lukeed' +}); //=> '/users/lukeed' + +inject('/movies/:title.mp4', { + title: 'narnia' +}); //=> '/movies/narnia.mp4' + +inject('/:foo/:bar?/:baz?', { + foo: 'aaa' +}); //=> '/aaa' + +inject('/:foo/:bar?/:baz?', { + foo: 'aaa', + baz: 'ccc' +}); //=> '/aaa/ccc' + +inject('/posts/:slug/*', { + slug: 'hello', +}); //=> '/posts/hello' + +inject('/posts/:slug/*', { + slug: 'hello', + wild: 'x/y/z', +}); //=> '/posts/hello/x/y/z' + +// Missing non-optional value +// ~> keeps the pattern in output +inject('/hello/:world', { + abc: 123 +}); //=> '/hello/:world' +``` + +> **Important:** When matching/testing against a generated RegExp, your path **must** begin with a leading slash (`"/"`)! + +## Regular Expressions + +For fine-tuned control, you may pass a `RegExp` value directly to `regexparam` as its only parameter. + +In these situations, `regexparam` **does not** parse nor manipulate your pattern in any way! Because of this, `regexparam` has no "insight" on your route, and instead trusts your input fully. In code, this means that the return value's `keys` is always equal to `false` and the `pattern` is identical to your input value. + +This also means that you must manage and parse your own `keys`~!
+You may use [named capture groups](https://javascript.info/regexp-groups#named-groups) or traverse the matched segments manually the "old-fashioned" way: + +> **Important:** Please check your target browsers' and target [Node.js runtimes' support](https://node.green/#ES2018-features--RegExp-named-capture-groups)! + +```js +// Named capture group +const named = regexparam.parse(/^\/posts[/](?[0-9]{4})[/](?[0-9]{2})[/](?[^\/]+)/i); +const { groups } = named.pattern.exec('/posts/2019/05/hello-world'); +console.log(groups); +//=> { year: '2019', month: '05', title: 'hello-world' } + +// Widely supported / "Old-fashioned" +const named = regexparam.parse(/^\/posts[/]([0-9]{4})[/]([0-9]{2})[/]([^\/]+)/i); +const [url, year, month, title] = named.pattern.exec('/posts/2019/05/hello-world'); +console.log(year, month, title); +//=> 2019 05 hello-world +``` + + +## API + +### regexparam.parse(input: RegExp) +### regexparam.parse(input: string, loose?: boolean) +Returns: `Object` + +Parse a route pattern into an equivalent RegExp pattern. Also collects the names of pattern's parameters as a `keys` array. An `input` that's already a RegExp is kept as is, and `regexparam` makes no additional insights. + +Returns a `{ keys, pattern }` object, where `pattern` is always a `RegExp` instance and `keys` is either `false` or a list of extracted parameter names. + +> **Important:** The `keys` will _always_ be `false` when `input` is a RegExp and it will _always_ be an Array when `input` is a string. + +#### input +Type: `string` or `RegExp` + +When `input` is a string, it's treated as a route pattern and an equivalent RegExp is generated. + +> **Note:** It does not matter if `input` strings begin with a `/` — it will be added if missing. + +When `input` is a RegExp, it will be used **as is** – no modifications will be made. + +#### loose +Type: `boolean`<br> +Default: `false` + +Should the `RegExp` match URLs that are longer than the [`str`](#str) pattern itself?<br> +By default, the generated `RegExp` will test that the URL begins and _ends with_ the pattern. + +> **Important:** When `input` is a RegExp, the `loose` argument is ignored! + +```js +const { parse } = require('regexparam'); + +parse('/users').pattern.test('/users/lukeed'); //=> false +parse('/users', true).pattern.test('/users/lukeed'); //=> true + +parse('/users/:name').pattern.test('/users/lukeed/repos'); //=> false +parse('/users/:name', true).pattern.test('/users/lukeed/repos'); //=> true +``` + + +### regexparam.inject(pattern: string, values: object) +Returns: `string` + +Returns a new string by replacing the `pattern` segments/parameters with their matching values. + +> **Important:** Named segments (eg, `/:name`) that _do not_ have a `values` match will be kept in the output. This is true _except for_ optional segments (eg, `/:name?`) and wildcard segments (eg, `/*`). + +#### pattern +Type: `string` + +The route pattern that to receive injections. + +#### values +Type: `Record<string, string>` + +The values to be injected. The keys within `values` must match the `pattern`'s segments in order to be replaced. + +> **Note:** To replace a wildcard segment (eg, `/*`), define a `values.wild` key. + + +## Deno + +As of version `1.3.0`, you may use `regexparam` with Deno. These options are all valid: + +```ts +// The official Deno registry: +import regexparam from 'https://deno.land/x/regexparam/src/index.js'; +// Third-party CDNs with ESM support: +import regexparam from 'https://cdn.skypack.dev/regexparam'; +import regexparam from 'https://esm.sh/regexparam'; +``` + +> **Note:** All registries support versioned URLs, if desired. <br>The above examples always resolve to the latest published version. + + +## Related + +- [trouter](https://github.com/lukeed/trouter) - A server-side HTTP router that extends from this module. +- [matchit](https://github.com/lukeed/matchit) - Similar (650B) library, but relies on String comparison instead of `RegExp`s. + + +## License + +MIT © [Luke Edwards](https://lukeed.com) diff --git a/node_modules/sirv/build.js b/node_modules/sirv/build.js new file mode 100644 index 0000000..0884d9f --- /dev/null +++ b/node_modules/sirv/build.js @@ -0,0 +1,194 @@ +const fs = require('fs'); +const { join, normalize, resolve } = require('path'); +const { totalist } = require('totalist/sync'); +const { parse } = require('@polka/url'); +const { lookup } = require('mrmime'); + +const noop = () => {}; + +function isMatch(uri, arr) { + for (let i=0; i < arr.length; i++) { + if (arr[i].test(uri)) return true; + } +} + +function toAssume(uri, extns) { + let i=0, x, len=uri.length - 1; + if (uri.charCodeAt(len) === 47) { + uri = uri.substring(0, len); + } + + let arr=[], tmp=`${uri}/index`; + for (; i < extns.length; i++) { + x = extns[i] ? `.${extns[i]}` : ''; + if (uri) arr.push(uri + x); + arr.push(tmp + x); + } + + return arr; +} + +function viaCache(cache, uri, extns) { + let i=0, data, arr=toAssume(uri, extns); + for (; i < arr.length; i++) { + if (data = cache[arr[i]]) return data; + } +} + +function viaLocal(dir, isEtag, uri, extns) { + let i=0, arr=toAssume(uri, extns); + let abs, stats, name, headers; + for (; i < arr.length; i++) { + abs = normalize(join(dir, name=arr[i])); + if (abs.startsWith(dir) && fs.existsSync(abs)) { + stats = fs.statSync(abs); + if (stats.isDirectory()) continue; + headers = toHeaders(name, stats, isEtag); + headers['Cache-Control'] = isEtag ? 'no-cache' : 'no-store'; + return { abs, stats, headers }; + } + } +} + +function is404(req, res) { + return (res.statusCode=404,res.end()); +} + +function send(req, res, file, stats, headers) { + let code=200, tmp, opts={}; + headers = { ...headers }; + + for (let key in headers) { + tmp = res.getHeader(key); + if (tmp) headers[key] = tmp; + } + + if (tmp = res.getHeader('content-type')) { + headers['Content-Type'] = tmp; + } + + if (req.headers.range) { + code = 206; + let [x, y] = req.headers.range.replace('bytes=', '').split('-'); + let end = opts.end = parseInt(y, 10) || stats.size - 1; + let start = opts.start = parseInt(x, 10) || 0; + + if (end >= stats.size) { + end = stats.size - 1; + } + + if (start >= stats.size) { + res.setHeader('Content-Range', `bytes */${stats.size}`); + res.statusCode = 416; + return res.end(); + } + + headers['Content-Range'] = `bytes ${start}-${end}/${stats.size}`; + headers['Content-Length'] = (end - start + 1); + headers['Accept-Ranges'] = 'bytes'; + } + + res.writeHead(code, headers); + fs.createReadStream(file, opts).pipe(res); +} + +const ENCODING = { + '.br': 'br', + '.gz': 'gzip', +}; + +function toHeaders(name, stats, isEtag) { + let enc = ENCODING[name.slice(-3)]; + + let ctype = lookup(name.slice(0, enc && -3)) || ''; + if (ctype === 'text/html') ctype += ';charset=utf-8'; + + let headers = { + 'Content-Length': stats.size, + 'Content-Type': ctype, + 'Last-Modified': stats.mtime.toUTCString(), + }; + + if (enc) headers['Content-Encoding'] = enc; + if (isEtag) headers['ETag'] = `W/"${stats.size}-${stats.mtime.getTime()}"`; + + return headers; +} + +module.exports = function (dir, opts={}) { + dir = resolve(dir || '.'); + + let isNotFound = opts.onNoMatch || is404; + let setHeaders = opts.setHeaders || noop; + + let extensions = opts.extensions || ['html', 'htm']; + let gzips = opts.gzip && extensions.map(x => `${x}.gz`).concat('gz'); + let brots = opts.brotli && extensions.map(x => `${x}.br`).concat('br'); + + const FILES = {}; + + let fallback = '/'; + let isEtag = !!opts.etag; + let isSPA = !!opts.single; + if (typeof opts.single === 'string') { + let idx = opts.single.lastIndexOf('.'); + fallback += !!~idx ? opts.single.substring(0, idx) : opts.single; + } + + let ignores = []; + if (opts.ignores !== false) { + ignores.push(/[/]([A-Za-z\s\d~$._-]+\.\w+){1,}$/); // any extn + if (opts.dotfiles) ignores.push(/\/\.\w/); + else ignores.push(/\/\.well-known/); + [].concat(opts.ignores || []).forEach(x => { + ignores.push(new RegExp(x, 'i')); + }); + } + + let cc = opts.maxAge != null && `public,max-age=${opts.maxAge}`; + if (cc && opts.immutable) cc += ',immutable'; + else if (cc && opts.maxAge === 0) cc += ',must-revalidate'; + + if (!opts.dev) { + totalist(dir, (name, abs, stats) => { + if (/\.well-known[\\+\/]/.test(name)) {} // keep + else if (!opts.dotfiles && /(^\.|[\\+|\/+]\.)/.test(name)) return; + + let headers = toHeaders(name, stats, isEtag); + if (cc) headers['Cache-Control'] = cc; + + FILES['/' + name.normalize().replace(/\\+/g, '/')] = { abs, stats, headers }; + }); + } + + let lookup = opts.dev ? viaLocal.bind(0, dir, isEtag) : viaCache.bind(0, FILES); + + return function (req, res, next) { + let extns = ['']; + let pathname = parse(req).pathname; + let val = req.headers['accept-encoding'] || ''; + if (gzips && val.includes('gzip')) extns.unshift(...gzips); + if (brots && /(br|brotli)/i.test(val)) extns.unshift(...brots); + extns.push(...extensions); // [...br, ...gz, orig, ...exts] + + if (pathname.indexOf('%') !== -1) { + try { pathname = decodeURI(pathname) } + catch (err) { /* malform uri */ } + } + + let data = lookup(pathname, extns) || isSPA && !isMatch(pathname, ignores) && lookup(fallback, extns); + if (!data) return next ? next() : isNotFound(req, res); + + if (isEtag && req.headers['if-none-match'] === data.headers['ETag']) { + res.writeHead(304); + return res.end(); + } + + if (gzips || brots) { + res.setHeader('Vary', 'Accept-Encoding'); + } + + setHeaders(res, pathname, data.stats); + send(req, res, data.abs, data.stats, data.headers); + }; +} diff --git a/node_modules/sirv/build.mjs b/node_modules/sirv/build.mjs new file mode 100644 index 0000000..c93bbe6 --- /dev/null +++ b/node_modules/sirv/build.mjs @@ -0,0 +1,194 @@ +import * as fs from 'fs'; +import { join, normalize, resolve } from 'path'; +import { totalist } from 'totalist/sync'; +import { parse } from '@polka/url'; +import { lookup } from 'mrmime'; + +const noop = () => {}; + +function isMatch(uri, arr) { + for (let i=0; i < arr.length; i++) { + if (arr[i].test(uri)) return true; + } +} + +function toAssume(uri, extns) { + let i=0, x, len=uri.length - 1; + if (uri.charCodeAt(len) === 47) { + uri = uri.substring(0, len); + } + + let arr=[], tmp=`${uri}/index`; + for (; i < extns.length; i++) { + x = extns[i] ? `.${extns[i]}` : ''; + if (uri) arr.push(uri + x); + arr.push(tmp + x); + } + + return arr; +} + +function viaCache(cache, uri, extns) { + let i=0, data, arr=toAssume(uri, extns); + for (; i < arr.length; i++) { + if (data = cache[arr[i]]) return data; + } +} + +function viaLocal(dir, isEtag, uri, extns) { + let i=0, arr=toAssume(uri, extns); + let abs, stats, name, headers; + for (; i < arr.length; i++) { + abs = normalize(join(dir, name=arr[i])); + if (abs.startsWith(dir) && fs.existsSync(abs)) { + stats = fs.statSync(abs); + if (stats.isDirectory()) continue; + headers = toHeaders(name, stats, isEtag); + headers['Cache-Control'] = isEtag ? 'no-cache' : 'no-store'; + return { abs, stats, headers }; + } + } +} + +function is404(req, res) { + return (res.statusCode=404,res.end()); +} + +function send(req, res, file, stats, headers) { + let code=200, tmp, opts={}; + headers = { ...headers }; + + for (let key in headers) { + tmp = res.getHeader(key); + if (tmp) headers[key] = tmp; + } + + if (tmp = res.getHeader('content-type')) { + headers['Content-Type'] = tmp; + } + + if (req.headers.range) { + code = 206; + let [x, y] = req.headers.range.replace('bytes=', '').split('-'); + let end = opts.end = parseInt(y, 10) || stats.size - 1; + let start = opts.start = parseInt(x, 10) || 0; + + if (end >= stats.size) { + end = stats.size - 1; + } + + if (start >= stats.size) { + res.setHeader('Content-Range', `bytes */${stats.size}`); + res.statusCode = 416; + return res.end(); + } + + headers['Content-Range'] = `bytes ${start}-${end}/${stats.size}`; + headers['Content-Length'] = (end - start + 1); + headers['Accept-Ranges'] = 'bytes'; + } + + res.writeHead(code, headers); + fs.createReadStream(file, opts).pipe(res); +} + +const ENCODING = { + '.br': 'br', + '.gz': 'gzip', +}; + +function toHeaders(name, stats, isEtag) { + let enc = ENCODING[name.slice(-3)]; + + let ctype = lookup(name.slice(0, enc && -3)) || ''; + if (ctype === 'text/html') ctype += ';charset=utf-8'; + + let headers = { + 'Content-Length': stats.size, + 'Content-Type': ctype, + 'Last-Modified': stats.mtime.toUTCString(), + }; + + if (enc) headers['Content-Encoding'] = enc; + if (isEtag) headers['ETag'] = `W/"${stats.size}-${stats.mtime.getTime()}"`; + + return headers; +} + +export default function (dir, opts={}) { + dir = resolve(dir || '.'); + + let isNotFound = opts.onNoMatch || is404; + let setHeaders = opts.setHeaders || noop; + + let extensions = opts.extensions || ['html', 'htm']; + let gzips = opts.gzip && extensions.map(x => `${x}.gz`).concat('gz'); + let brots = opts.brotli && extensions.map(x => `${x}.br`).concat('br'); + + const FILES = {}; + + let fallback = '/'; + let isEtag = !!opts.etag; + let isSPA = !!opts.single; + if (typeof opts.single === 'string') { + let idx = opts.single.lastIndexOf('.'); + fallback += !!~idx ? opts.single.substring(0, idx) : opts.single; + } + + let ignores = []; + if (opts.ignores !== false) { + ignores.push(/[/]([A-Za-z\s\d~$._-]+\.\w+){1,}$/); // any extn + if (opts.dotfiles) ignores.push(/\/\.\w/); + else ignores.push(/\/\.well-known/); + [].concat(opts.ignores || []).forEach(x => { + ignores.push(new RegExp(x, 'i')); + }); + } + + let cc = opts.maxAge != null && `public,max-age=${opts.maxAge}`; + if (cc && opts.immutable) cc += ',immutable'; + else if (cc && opts.maxAge === 0) cc += ',must-revalidate'; + + if (!opts.dev) { + totalist(dir, (name, abs, stats) => { + if (/\.well-known[\\+\/]/.test(name)) {} // keep + else if (!opts.dotfiles && /(^\.|[\\+|\/+]\.)/.test(name)) return; + + let headers = toHeaders(name, stats, isEtag); + if (cc) headers['Cache-Control'] = cc; + + FILES['/' + name.normalize().replace(/\\+/g, '/')] = { abs, stats, headers }; + }); + } + + let lookup = opts.dev ? viaLocal.bind(0, dir, isEtag) : viaCache.bind(0, FILES); + + return function (req, res, next) { + let extns = ['']; + let pathname = parse(req).pathname; + let val = req.headers['accept-encoding'] || ''; + if (gzips && val.includes('gzip')) extns.unshift(...gzips); + if (brots && /(br|brotli)/i.test(val)) extns.unshift(...brots); + extns.push(...extensions); // [...br, ...gz, orig, ...exts] + + if (pathname.indexOf('%') !== -1) { + try { pathname = decodeURI(pathname) } + catch (err) { /* malform uri */ } + } + + let data = lookup(pathname, extns) || isSPA && !isMatch(pathname, ignores) && lookup(fallback, extns); + if (!data) return next ? next() : isNotFound(req, res); + + if (isEtag && req.headers['if-none-match'] === data.headers['ETag']) { + res.writeHead(304); + return res.end(); + } + + if (gzips || brots) { + res.setHeader('Vary', 'Accept-Encoding'); + } + + setHeaders(res, pathname, data.stats); + send(req, res, data.abs, data.stats, data.headers); + }; +} diff --git a/node_modules/sirv/package.json b/node_modules/sirv/package.json new file mode 100644 index 0000000..143ed9d --- /dev/null +++ b/node_modules/sirv/package.json @@ -0,0 +1,27 @@ +{ + "name": "sirv", + "version": "2.0.4", + "description": "The optimized & lightweight middleware for serving requests to static assets", + "repository": "lukeed/sirv", + "module": "build.mjs", + "types": "sirv.d.ts", + "main": "build.js", + "license": "MIT", + "files": [ + "build.*", + "sirv.d.ts" + ], + "author": { + "name": "Luke Edwards", + "email": "luke@lukeed.com", + "url": "https://lukeed.com" + }, + "engines": { + "node": ">= 10" + }, + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + } +} \ No newline at end of file diff --git a/node_modules/sirv/readme.md b/node_modules/sirv/readme.md new file mode 100644 index 0000000..d4a56da --- /dev/null +++ b/node_modules/sirv/readme.md @@ -0,0 +1,238 @@ +# sirv ![CI](https://github.com/lukeed/sirv/workflows/CI/badge.svg) + +> The optimized and lightweight middleware for serving requests to static assets + +You may use `sirv` as a *very* fast and lightweight alternative to [`serve-static`](https://www.npmjs.com/package/serve-static). + +The massive performance advantage over `serve-static` is explained by **not** relying on the file system for existence checks on every request. These are expensive interactions and must be avoided whenever possible! Instead, when not in "dev" mode, `sirv` performs all its file-system operations upfront and then relies on its cache for future operations. + +This middleware will work out of the box for [Polka](https://github.com/lukeed/polka), Express, and other Express-like frameworks. It will also work with the native `http`, `https` and `http2` modules. It requires _very_ little effort to modify/wrap it for servers that don't accept the `(req, res, next)` signature. + +:bulb: For a feature-complete CLI application, check out the sibling [`sirv-cli`](https://github.com/lukeed/sirv/tree/master/packages/sirv-cli) package as an alternative to [`zeit/serve`](https://github.com/zeit/serve)~! + +## Install + +``` +$ npm install --save sirv +``` + + +## Usage + +```js +const sirv = require('sirv'); +const polka = require('polka'); +const compress = require('compression')(); + +// Init `sirv` handler +const assets = sirv('public', { + maxAge: 31536000, // 1Y + immutable: true +}); + +polka() + .use(compress, assets) + .use('/api', require('./api')) + .listen(3000, err => { + if (err) throw err; + console.log('> Ready on localhost:3000~!'); + }); +``` + + +## API + +### sirv(dir, opts={}) + +Returns: `Function` + +The returned function is a middleware in the standard Express-like signature: `(req, res, next)`, where `req` is the [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage), `res` is the [`http.ServerResponse`](https://nodejs.org/dist/latest-v9.x/docs/api/http.html#http_class_http_serverresponse), and `next` (in this case) is the function to call if no file was found for the given path. + +When defined, a `next()` callback is always called _instead of_ the [`opts.onNoMatch`](#optsonnomatch) callback. However, unlike `onNoMatch`, your `next()` is given no arguments. + +#### dir +Type: `String`<br> +Default: `.` + +The directory from which to read and serve assets. It is resolved to an absolute path — you must provide an absolute path yourself if `process.cwd()` is not the correct assumption. + +#### opts.dev +Type: `Boolean`<br> +Default: `false` + +Enable "dev" mode, which disables/skips caching. Instead, `sirv` will traverse the file system ***on every request***. + +Additionally, `dev` mode will ignore `maxAge` and `immutable` as these options generate a production-oriented `Cache-Control` header value. + +> **Important:** Do not use `dev` mode in production! + +#### opts.etag +Type: `Boolean`<br> +Default: `false` + +Generate and attach an `ETag` header to responses. + +> **Note:** If an incoming request's [`If-None-Match` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) matches the `ETag` value, a `304` response is given. + +#### opts.dotfiles +Type: `Boolean`<br> +Default: `false` + +Allow requests to dotfiles (files or directories beginning with a `.`). + +> **Note:** Requests to [`/.well-known/*`](https://tools.ietf.org/html/rfc8615) are always allowed. + +#### opts.extensions +Type: `Array<String>`<br> +Default: `['html', 'htm']` + +The file extension fallbacks to check for if a pathame is not initially found. For example, if a `/login` request cannot find a `login` filename, it will then look for `login.html` and `login.htm` before giving up~! + +> **Important:** Actually, `sirv` will **also** look for `login/index.html` and `login/index.htm` before giving up. + +#### opts.gzip +Type: `Boolean`<br> +Default: `false` + +Determine if `sirv` look for **precompiled** `*.gz` files.<br> +Must be enabled _and_ the incoming request's [`Accept Encoding`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) must include "gzip" in order for `sirv` to search for the gzip'd alternative. + +> **Note:** The `.gz` assumption also applies to the `opts.extensions` list. + +```js +// NOTE: PSEUDO CODE +// Showing lookup logic + +// Request: [Accept-Encoding: gzip] "/foobar.jpg" +lookup([ + '/foobar.jpg.gz', '/foobar.jpg', + '/foobar.jpg.html.gz', '/foobar.jpg/index.html.gz', + '/foobar.jpg.htm.gz', '/foobar.jpg/index.htm.gz', + '/foobar.jpg.html', '/foobar.jpg/index.html', + '/foobar.jpg.htm', '/foobar.jpg/index.htm', +]); + +// Request: [Accept-Encoding: gzip] "/" +lookup([ + '/index.html.gz', + '/index.htm.gz', + '/index.html', + '/index.htm', +]); +``` + + +#### opts.brotli +Type: `Boolean`<br> +Default: `false` + +Determine if `sirv` look for **precompiled** `*.br` files.<br> +Must be enabled _and_ the incoming request's [`Accept Encoding`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) must include either "br" or "brotli" in order for `sirv` to search for the brotli-compressed alternative. + +> **Note:** The `.br` assumption also applies to the `opts.extensions` list. + +When both `opts.broli` and `opts.gzip` are enabled — and all conditions are equal — then the brotli variant always takes priority. + +```js +// NOTE: PSEUDO CODE +// Showing lookup logic + +// Request: [Accept-Encoding: br] "/foobar.jpg" +lookup([ + '/foobar.jpg.br', '/foobar.jpg', + '/foobar.jpg.html.br', '/foobar.jpg/index.html.br', + '/foobar.jpg.htm.br', '/foobar.jpg/index.htm.br', + '/foobar.jpg.html', '/foobar.jpg/index.html', + '/foobar.jpg.htm', '/foobar.jpg/index.htm', +]); + +// Request: [Accept-Encoding: br,gz] "/" +lookup([ + '/index.html.br' + '/index.htm.br' + '/index.html.gz' + '/index.htm.gz' + '/index.html' + '/index.htm' +]); +``` + +#### opts.maxAge +Type: `Number`<br> +Default: `undefined` + +Enables the `Cache-Control` header on responses and sets the `max-age` value (in seconds).<br> +For example, `maxAge: 31536000` is equivalent to one year. + +#### opts.immutable +Type: `Boolean`<br> +Default: `false` + +Appends the [`immutable` directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Revalidation_and_reloading) on your `Cache-Control` header, used for uniquely-named assets that will not change! + +> **Important:** Will only work if `opts.maxAge` has a value defined! + +#### opts.single +Type: `Boolean` or `String`<br> +Default: `false` + +Treat the directory as a single-page application. + +When `true`, the directory's index page (default `index.html`) will be sent if the request asset does not exist.<br> +You may pass a `string` value to use a file _instead of_ `index.html` as your fallback. + +For example, if "/about" is requested but no variants of that file exist, then the response for "/" is sent instead: + +```js +// Note: This is psuedo code to illustrate what's happening + +// Request: "/about" +let file = find(['/about', '/about.html', '/about.htm', '/about/index.html', '/about.htm']); +if (file) { + send(file); +} else if (opts.single === true) { + file = find(['/', '/index.html', '/index.htm']); + send(file); +} else if (typeof opts.single === 'string') { + file = find([opts.single]); + send(file); +} else { + // next() or 404 +} +``` + +#### opts.ignores +Type: `false` or `Array<String | RegExp>` + +Specify paths/patterns that should ignore the fallback behavior that `opts.single` provides. + +By default, any asset-like path (URLs that end with an extension) will be ignored. This means that, for example, if `/foobar.jpg` is not found, a `404` response is sent instead of the `index.html` fallback. + +Additionally, any `/.well-known/*` pathname ignores the fallback – as do all other dotfile requests when `opts.dotfiles` is enabled. + +Any string value(s) will be passed through `new RegExp(value, 'i')` directly. + +Finally, you may set `ignores: false` to disable ***all*** ignores, including the defaults. Put differently, this will fallback ***all*** unknown pathnames to your `index.html` (or custom `opts.single` value). + +> **Important:** Only has an effect if `opts.single` is enabled. + +#### opts.onNoMatch +Type: `Function` + +A custom function to run if a file cannot be found for a given request. <br>By default, `sirv` will send a basic `(404) Not found` response. + +The function receives the current `req <IncomingMessage>, res <ServerResponse>` pair for as its two arguments. + +> **Note:** This won't run if a `next` callback has been provided to the middleware; see [`sirv`](#sirvdir-opts) description. + +#### opts.setHeaders +Type: `Function` + +A custom function to append or change any headers on the outgoing response. There is no default. + +Its signature is `(res, pathname, stats)`, where `res` is the `ServerResponse`, `pathname` is incoming request path (stripped of queries), and `stats` is the file's result from [`fs.statSync`](https://nodejs.org/api/fs.html#fs_fs_statsync_path). + + +## License + +MIT © [Luke Edwards](https://lukeed.com) diff --git a/node_modules/sirv/sirv.d.ts b/node_modules/sirv/sirv.d.ts new file mode 100644 index 0000000..c05040f --- /dev/null +++ b/node_modules/sirv/sirv.d.ts @@ -0,0 +1,25 @@ +declare module 'sirv' { + import type { Stats } from 'fs'; + import type { IncomingMessage, ServerResponse } from 'http'; + + type Arrayable<T> = T | T[]; + export type NextHandler = () => void | Promise<void>; + export type RequestHandler = (req: IncomingMessage, res: ServerResponse, next?: NextHandler) => void; + + export interface Options { + dev?: boolean; + etag?: boolean; + maxAge?: number; + immutable?: boolean; + single?: string | boolean; + ignores?: false | Arrayable<string | RegExp>; + extensions?: string[]; + dotfiles?: boolean; + brotli?: boolean; + gzip?: boolean; + onNoMatch?: (req: IncomingMessage, res: ServerResponse) => void; + setHeaders?: (res: ServerResponse, pathname: string, stats: Stats) => void; + } + + export default function(dir?: string, opts?: Options): RequestHandler; +} diff --git a/node_modules/sort-on/index.d.ts b/node_modules/sort-on/index.d.ts new file mode 100644 index 0000000..01d0179 --- /dev/null +++ b/node_modules/sort-on/index.d.ts @@ -0,0 +1,61 @@ +export type Property<T> = string | ((element: T) => unknown) | Array<string | ((element: T) => unknown)>; + +export type Options = { + /** + One or more locales to use when sorting strings. + + Should be a locale string or array of locale strings that contain one or more language or locale tags. + + If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. + + If you omit this parameter, the default locale of the JavaScript runtime is used. + + This parameter must conform to BCP 47 standards. See {@link Intl.Collator} for more details. + */ + readonly locales?: string | readonly string[]; + + /** + Comparison options. + + See {@link Intl.Collator} for more details. + */ + readonly localeOptions?: Intl.CollatorOptions; +}; + +/** +Sort an array on an object property. + +@param array - The array to sort. +@param property - The string can be a [dot path](https://github.com/sindresorhus/dot-prop) to a nested object property. Prefix it with `-` to sort it in descending order. +@returns A new sorted version of the given array. + +@example +``` +import sortOn from 'sort-on'; + +// Sort by an object property +sortOn([{x: 'b'}, {x: 'a'}, {x: 'c'}], 'x'); +//=> [{x: 'a'}, {x: 'b'}, {x: 'c'}] + +// Sort descending by an object property +sortOn([{x: 'b'}, {x: 'a'}, {x: 'c'}], '-x'); +//=> [{x: 'c'}, {x: 'b'}, {x: 'a'}] + +// Sort by a nested object property +sortOn([{x: {y: 'b'}}, {x: {y: 'a'}}], 'x.y'); +//=> [{x: {y: 'a'}}, {x: {y: 'b'}}] + +// Sort descending by a nested object property +sortOn([{x: {y: 'b'}}, {x: {y: 'a'}}], '-x.y'); +//=> [{x: {y: 'b'}, {x: {y: 'a'}}}] + +// Sort by the `x` property, then `y` +sortOn([{x: 'c', y: 'c'}, {x: 'b', y: 'a'}, {x: 'b', y: 'b'}], ['x', 'y']); +//=> [{x: 'b', y: 'a'}, {x: 'b', y: 'b'}, {x: 'c', y: 'c'}] + +// Sort by the returned value +sortOn([{x: 'b'}, {x: 'a'}, {x: 'c'}], el => el.x); +//=> [{x: 'a'}, {x: 'b'}, {x: 'c'}] +``` +*/ +export default function sortOn<T>(array: readonly T[], property: Property<T>, options?: Options): T[]; diff --git a/node_modules/sort-on/index.js b/node_modules/sort-on/index.js new file mode 100644 index 0000000..f32e309 --- /dev/null +++ b/node_modules/sort-on/index.js @@ -0,0 +1,60 @@ +import {getProperty} from 'dot-prop'; + +export default function sortOn(array, property, {locales, localeOptions} = {}) { + if (!Array.isArray(array)) { + throw new TypeError(`Expected type \`Array\`, got \`${typeof array}\``); + } + + return [...array].sort((a, b) => { + let returnValue = 0; + + [property].flat().some(element => { + let isDescending; + let x; + let y; + + if (typeof element === 'function') { + x = element(a); + y = element(b); + } else if (typeof element === 'string') { + isDescending = element.charAt(0) === '-'; + element = isDescending ? element.slice(1) : element; + x = getProperty(a, element); + y = getProperty(b, element); + } else { + x = a; + y = b; + } + + if (x === y) { + returnValue = 0; + return false; + } + + if (y !== 0 && !y) { + returnValue = isDescending ? 1 : -1; + return true; + } + + if (x !== 0 && !x) { + returnValue = isDescending ? -1 : 1; + return true; + } + + if (typeof x === 'string' && typeof y === 'string') { + returnValue = isDescending ? y.localeCompare(x, locales, localeOptions) : x.localeCompare(y, locales, localeOptions); + return returnValue !== 0; + } + + if (isDescending) { + returnValue = x < y ? 1 : -1; + } else { + returnValue = x < y ? -1 : 1; + } + + return true; + }); + + return returnValue; + }); +} diff --git a/node_modules/sort-on/license b/node_modules/sort-on/license new file mode 100644 index 0000000..fa7ceba --- /dev/null +++ b/node_modules/sort-on/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/sort-on/package.json b/node_modules/sort-on/package.json new file mode 100644 index 0000000..c2cf867 --- /dev/null +++ b/node_modules/sort-on/package.json @@ -0,0 +1,47 @@ +{ + "name": "sort-on", + "version": "6.0.0", + "description": "Sort an array on an object property", + "license": "MIT", + "repository": "sindresorhus/sort-on", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "engines": { + "node": ">=18" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "sort", + "sorting", + "array", + "by", + "object", + "property", + "dot", + "path", + "get" + ], + "dependencies": { + "dot-prop": "^8.0.2" + }, + "devDependencies": { + "ava": "^5.3.1", + "tsd": "^0.29.0", + "xo": "^0.56.0" + } +} diff --git a/node_modules/sort-on/readme.md b/node_modules/sort-on/readme.md new file mode 100644 index 0000000..6ce60a2 --- /dev/null +++ b/node_modules/sort-on/readme.md @@ -0,0 +1,82 @@ +# sort-on + +> Sort an array on an object property + +## Install + +```sh +npm install sort-on +``` + +## Usage + +```js +import sortOn from 'sort-on'; + +// Sort by an object property +sortOn([{x: 'b'}, {x: 'a'}, {x: 'c'}], 'x'); +//=> [{x: 'a'}, {x: 'b'}, {x: 'c'}] + +// Sort descending by an object property +sortOn([{x: 'b'}, {x: 'a'}, {x: 'c'}], '-x'); +//=> [{x: 'c'}, {x: 'b'}, {x: 'a'}] + +// Sort by a nested object property +sortOn([{x: {y: 'b'}}, {x: {y: 'a'}}], 'x.y'); +//=> [{x: {y: 'a'}}, {x: {y: 'b'}}] + +// Sort descending by a nested object property +sortOn([{x: {y: 'b'}}, {x: {y: 'a'}}], '-x.y'); +//=> [{x: {y: 'b'}, {x: {y: 'a'}}}] + +// Sort by the `x` property, then `y` +sortOn([{x: 'c', y: 'c'}, {x: 'b', y: 'a'}, {x: 'b', y: 'b'}], ['x', 'y']); +//=> [{x: 'b', y: 'a'}, {x: 'b', y: 'b'}, {x: 'c', y: 'c'}] + +// Sort by the returned value +sortOn([{x: 'b'}, {x: 'a'}, {x: 'c'}], element => element.x); +//=> [{x: 'a'}, {x: 'b'}, {x: 'c'}] +``` + +## API + +### sortOn(array, property, options) + +Returns a new sorted version of the given array. + +#### array + +Type: `unknown[]` + +The array to sort. + +#### property + +Type: `string | string[] | Function` + +The string can be a [dot path](https://github.com/sindresorhus/dot-prop) to a nested object property. + +Prefix it with `-` to sort it in descending order. + +#### options + +Type: `object` + +##### locales + +Type: `string | string[]`\ +Default: The default locale of the JavaScript runtime. + +One or more locales to use when sorting strings. + +Should be a locale string or array of locale strings that contain one or more language or locale tags. + +If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. + +This parameter must conform to BCP 47 standards. See [`Intl.Collator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator) for more details. + +##### localeOptions + +Type: [`Intl.CollatorOptions`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator#options) + +Comparison options. diff --git a/node_modules/steno/LICENSE b/node_modules/steno/LICENSE new file mode 100644 index 0000000..d3b5f5f --- /dev/null +++ b/node_modules/steno/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2021 typicode + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/node_modules/steno/README.md b/node_modules/steno/README.md new file mode 100644 index 0000000..92d1e6b --- /dev/null +++ b/node_modules/steno/README.md @@ -0,0 +1,50 @@ +# Steno [![](http://img.shields.io/npm/dm/steno.svg?style=flat)](https://www.npmjs.org/package/steno) [![Node.js CI](https://github.com/typicode/steno/actions/workflows/node.js.yml/badge.svg)](https://github.com/typicode/steno/actions/workflows/node.js.yml) + +> Specialized fast async file writer + +**Steno** makes writing to the same file often/concurrently fast and safe. + +Used in [lowdb](https://github.com/typicode/lowdb). + +_https://en.wikipedia.org/wiki/Stenotype_ + +## Features + +- ⚡ Fast (see benchmark) +- 🐦 Lightweight (~6kb) +- 👍 ⚛️ Safe: No partial writes (writes are atomic) +- 👍 🏁 Safe: No race conditions (writes are ordered even if they're async) + +## Usage + +```javascript +import { Writer } from 'steno' + +// Create a singleton writer +const file = new Writer('file.txt') + +// Use it in the rest of your code +async function save() { + await file.write('some data') +} +``` + +## Benchmark + +`npm run benchmark` (see `src/benchmark.ts`) + +``` +Write 1KB data to the same file x 1000 + fs : 62ms + steno : 1ms + +Write 1MB data to the same file x 1000 + fs : 2300ms + steno : 5ms +``` + +_Steno uses a smart queue and avoids unnecessary writes._ + +## License + +MIT - [Typicode](https://github.com/typicode) diff --git a/node_modules/steno/lib/index.d.ts b/node_modules/steno/lib/index.d.ts new file mode 100644 index 0000000..ea67814 --- /dev/null +++ b/node_modules/steno/lib/index.d.ts @@ -0,0 +1,11 @@ +/// <reference types="node" resolution-mode="require"/> +/// <reference types="node" resolution-mode="require"/> +import { PathLike } from 'node:fs'; +import { writeFile } from 'node:fs/promises'; +type Data = Parameters<typeof writeFile>[1]; +export declare class Writer { + #private; + constructor(filename: PathLike); + write(data: Data): Promise<void>; +} +export {}; diff --git a/node_modules/steno/lib/index.js b/node_modules/steno/lib/index.js new file mode 100644 index 0000000..a779c03 --- /dev/null +++ b/node_modules/steno/lib/index.js @@ -0,0 +1,86 @@ +import { rename, writeFile } from 'node:fs/promises'; +import { basename, dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +// Returns a temporary file +// Example: for /some/file will return /some/.file.tmp +function getTempFilename(file) { + const f = file instanceof URL ? fileURLToPath(file) : file.toString(); + return join(dirname(f), `.${basename(f)}.tmp`); +} +// Retries an asynchronous operation with a delay between retries and a maximum retry count +async function retryAsyncOperation(fn, maxRetries, delayMs) { + for (let i = 0; i < maxRetries; i++) { + try { + return await fn(); + } + catch (error) { + if (i < maxRetries - 1) { + await new Promise((resolve) => setTimeout(resolve, delayMs)); + } + else { + throw error; // Rethrow the error if max retries reached + } + } + } +} +export class Writer { + #filename; + #tempFilename; + #locked = false; + #prev = null; + #next = null; + #nextPromise = null; + #nextData = null; + // File is locked, add data for later + #add(data) { + // Only keep most recent data + this.#nextData = data; + // Create a singleton promise to resolve all next promises once next data is written + this.#nextPromise ||= new Promise((resolve, reject) => { + this.#next = [resolve, reject]; + }); + // Return a promise that will resolve at the same time as next promise + return new Promise((resolve, reject) => { + this.#nextPromise?.then(resolve).catch(reject); + }); + } + // File isn't locked, write data + async #write(data) { + // Lock file + this.#locked = true; + try { + // Atomic write + await writeFile(this.#tempFilename, data, 'utf-8'); + await retryAsyncOperation(async () => { + await rename(this.#tempFilename, this.#filename); + }, 10, 100); + // Call resolve + this.#prev?.[0](); + } + catch (err) { + // Call reject + if (err instanceof Error) { + this.#prev?.[1](err); + } + throw err; + } + finally { + // Unlock file + this.#locked = false; + this.#prev = this.#next; + this.#next = this.#nextPromise = null; + if (this.#nextData !== null) { + const nextData = this.#nextData; + this.#nextData = null; + await this.write(nextData); + } + } + } + constructor(filename) { + this.#filename = filename; + this.#tempFilename = getTempFilename(filename); + } + async write(data) { + return this.#locked ? this.#add(data) : this.#write(data); + } +} diff --git a/node_modules/steno/package.json b/node_modules/steno/package.json new file mode 100644 index 0000000..603ec33 --- /dev/null +++ b/node_modules/steno/package.json @@ -0,0 +1,62 @@ +{ + "name": "steno", + "version": "4.0.2", + "description": "Specialized fast async file writer", + "keywords": [ + "fs", + "file", + "write", + "writer", + "asynchronous", + "fast", + "race", + "condition", + "atomic", + "writing", + "safe" + ], + "homepage": "https://github.com/typicode/steno", + "bugs": { + "url": "https://github.com/typicode/steno/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/typicode/steno.git" + }, + "funding": "https://github.com/sponsors/typicode", + "license": "MIT", + "author": "Typicode <typicode@gmail.com>", + "type": "module", + "exports": "./lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib/index.js", + "lib/index.d.ts" + ], + "scripts": { + "test": "node --import tsx/esm --test src/test.ts", + "build": "del-cli lib && tsc", + "lint": "eslint src --ext .ts --ignore-path .gitignore", + "prepare": "husky install", + "prepublishOnly": "npm run build", + "postversion": "git push && git push --tags && npm publish", + "benchmark": "npm run build && node lib/benchmark.js", + "commit": "commit" + }, + "devDependencies": { + "@commitlint/cli": "^17.7.2", + "@commitlint/config-conventional": "^17.7.0", + "@commitlint/prompt-cli": "^17.7.2", + "@sindresorhus/tsconfig": "^5.0.0", + "@types/async-retry": "^1.4.8", + "@types/node": "^20.8.3", + "@typicode/eslint-config": "^1.2.0", + "del-cli": "^5.1.0", + "husky": "^8.0.3", + "tsx": "^4.7.0", + "typescript": "^5.2.2" + }, + "engines": { + "node": ">=18" + } +} diff --git a/node_modules/to-regex-range/LICENSE b/node_modules/to-regex-range/LICENSE new file mode 100644 index 0000000..7cccaf9 --- /dev/null +++ b/node_modules/to-regex-range/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/to-regex-range/README.md b/node_modules/to-regex-range/README.md new file mode 100644 index 0000000..38887da --- /dev/null +++ b/node_modules/to-regex-range/README.md @@ -0,0 +1,305 @@ +# to-regex-range [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [![NPM version](https://img.shields.io/npm/v/to-regex-range.svg?style=flat)](https://www.npmjs.com/package/to-regex-range) [![NPM monthly downloads](https://img.shields.io/npm/dm/to-regex-range.svg?style=flat)](https://npmjs.org/package/to-regex-range) [![NPM total downloads](https://img.shields.io/npm/dt/to-regex-range.svg?style=flat)](https://npmjs.org/package/to-regex-range) [![Linux Build Status](https://img.shields.io/travis/micromatch/to-regex-range.svg?style=flat&label=Travis)](https://travis-ci.org/micromatch/to-regex-range) + +> Pass two numbers, get a regex-compatible source string for matching ranges. Validated against more than 2.78 million test assertions. + +Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save to-regex-range +``` + +<details> +<summary><strong>What does this do?</strong></summary> + +<br> + +This libary generates the `source` string to be passed to `new RegExp()` for matching a range of numbers. + +**Example** + +```js +const toRegexRange = require('to-regex-range'); +const regex = new RegExp(toRegexRange('15', '95')); +``` + +A string is returned so that you can do whatever you need with it before passing it to `new RegExp()` (like adding `^` or `$` boundaries, defining flags, or combining it another string). + +<br> + +</details> + +<details> +<summary><strong>Why use this library?</strong></summary> + +<br> + +### Convenience + +Creating regular expressions for matching numbers gets deceptively complicated pretty fast. + +For example, let's say you need a validation regex for matching part of a user-id, postal code, social security number, tax id, etc: + +* regex for matching `1` => `/1/` (easy enough) +* regex for matching `1` through `5` => `/[1-5]/` (not bad...) +* regex for matching `1` or `5` => `/(1|5)/` (still easy...) +* regex for matching `1` through `50` => `/([1-9]|[1-4][0-9]|50)/` (uh-oh...) +* regex for matching `1` through `55` => `/([1-9]|[1-4][0-9]|5[0-5])/` (no prob, I can do this...) +* regex for matching `1` through `555` => `/([1-9]|[1-9][0-9]|[1-4][0-9]{2}|5[0-4][0-9]|55[0-5])/` (maybe not...) +* regex for matching `0001` through `5555` => `/(0{3}[1-9]|0{2}[1-9][0-9]|0[1-9][0-9]{2}|[1-4][0-9]{3}|5[0-4][0-9]{2}|55[0-4][0-9]|555[0-5])/` (okay, I get the point!) + +The numbers are contrived, but they're also really basic. In the real world you might need to generate a regex on-the-fly for validation. + +**Learn more** + +If you're interested in learning more about [character classes](http://www.regular-expressions.info/charclass.html) and other regex features, I personally have always found [regular-expressions.info](http://www.regular-expressions.info/charclass.html) to be pretty useful. + +### Heavily tested + +As of April 07, 2019, this library runs [>1m test assertions](./test/test.js) against generated regex-ranges to provide brute-force verification that results are correct. + +Tests run in ~280ms on my MacBook Pro, 2.5 GHz Intel Core i7. + +### Optimized + +Generated regular expressions are optimized: + +* duplicate sequences and character classes are reduced using quantifiers +* smart enough to use `?` conditionals when number(s) or range(s) can be positive or negative +* uses fragment caching to avoid processing the same exact string more than once + +<br> + +</details> + +## Usage + +Add this library to your javascript application with the following line of code + +```js +const toRegexRange = require('to-regex-range'); +``` + +The main export is a function that takes two integers: the `min` value and `max` value (formatted as strings or numbers). + +```js +const source = toRegexRange('15', '95'); +//=> 1[5-9]|[2-8][0-9]|9[0-5] + +const regex = new RegExp(`^${source}$`); +console.log(regex.test('14')); //=> false +console.log(regex.test('50')); //=> true +console.log(regex.test('94')); //=> true +console.log(regex.test('96')); //=> false +``` + +## Options + +### options.capture + +**Type**: `boolean` + +**Deafault**: `undefined` + +Wrap the returned value in parentheses when there is more than one regex condition. Useful when you're dynamically generating ranges. + +```js +console.log(toRegexRange('-10', '10')); +//=> -[1-9]|-?10|[0-9] + +console.log(toRegexRange('-10', '10', { capture: true })); +//=> (-[1-9]|-?10|[0-9]) +``` + +### options.shorthand + +**Type**: `boolean` + +**Deafault**: `undefined` + +Use the regex shorthand for `[0-9]`: + +```js +console.log(toRegexRange('0', '999999')); +//=> [0-9]|[1-9][0-9]{1,5} + +console.log(toRegexRange('0', '999999', { shorthand: true })); +//=> \d|[1-9]\d{1,5} +``` + +### options.relaxZeros + +**Type**: `boolean` + +**Default**: `true` + +This option relaxes matching for leading zeros when when ranges are zero-padded. + +```js +const source = toRegexRange('-0010', '0010'); +const regex = new RegExp(`^${source}$`); +console.log(regex.test('-10')); //=> true +console.log(regex.test('-010')); //=> true +console.log(regex.test('-0010')); //=> true +console.log(regex.test('10')); //=> true +console.log(regex.test('010')); //=> true +console.log(regex.test('0010')); //=> true +``` + +When `relaxZeros` is false, matching is strict: + +```js +const source = toRegexRange('-0010', '0010', { relaxZeros: false }); +const regex = new RegExp(`^${source}$`); +console.log(regex.test('-10')); //=> false +console.log(regex.test('-010')); //=> false +console.log(regex.test('-0010')); //=> true +console.log(regex.test('10')); //=> false +console.log(regex.test('010')); //=> false +console.log(regex.test('0010')); //=> true +``` + +## Examples + +| **Range** | **Result** | **Compile time** | +| --- | --- | --- | +| `toRegexRange(-10, 10)` | `-[1-9]\|-?10\|[0-9]` | _132μs_ | +| `toRegexRange(-100, -10)` | `-1[0-9]\|-[2-9][0-9]\|-100` | _50μs_ | +| `toRegexRange(-100, 100)` | `-[1-9]\|-?[1-9][0-9]\|-?100\|[0-9]` | _42μs_ | +| `toRegexRange(001, 100)` | `0{0,2}[1-9]\|0?[1-9][0-9]\|100` | _109μs_ | +| `toRegexRange(001, 555)` | `0{0,2}[1-9]\|0?[1-9][0-9]\|[1-4][0-9]{2}\|5[0-4][0-9]\|55[0-5]` | _51μs_ | +| `toRegexRange(0010, 1000)` | `0{0,2}1[0-9]\|0{0,2}[2-9][0-9]\|0?[1-9][0-9]{2}\|1000` | _31μs_ | +| `toRegexRange(1, 50)` | `[1-9]\|[1-4][0-9]\|50` | _24μs_ | +| `toRegexRange(1, 55)` | `[1-9]\|[1-4][0-9]\|5[0-5]` | _23μs_ | +| `toRegexRange(1, 555)` | `[1-9]\|[1-9][0-9]\|[1-4][0-9]{2}\|5[0-4][0-9]\|55[0-5]` | _30μs_ | +| `toRegexRange(1, 5555)` | `[1-9]\|[1-9][0-9]{1,2}\|[1-4][0-9]{3}\|5[0-4][0-9]{2}\|55[0-4][0-9]\|555[0-5]` | _43μs_ | +| `toRegexRange(111, 555)` | `11[1-9]\|1[2-9][0-9]\|[2-4][0-9]{2}\|5[0-4][0-9]\|55[0-5]` | _38μs_ | +| `toRegexRange(29, 51)` | `29\|[34][0-9]\|5[01]` | _24μs_ | +| `toRegexRange(31, 877)` | `3[1-9]\|[4-9][0-9]\|[1-7][0-9]{2}\|8[0-6][0-9]\|87[0-7]` | _32μs_ | +| `toRegexRange(5, 5)` | `5` | _8μs_ | +| `toRegexRange(5, 6)` | `5\|6` | _11μs_ | +| `toRegexRange(1, 2)` | `1\|2` | _6μs_ | +| `toRegexRange(1, 5)` | `[1-5]` | _15μs_ | +| `toRegexRange(1, 10)` | `[1-9]\|10` | _22μs_ | +| `toRegexRange(1, 100)` | `[1-9]\|[1-9][0-9]\|100` | _25μs_ | +| `toRegexRange(1, 1000)` | `[1-9]\|[1-9][0-9]{1,2}\|1000` | _31μs_ | +| `toRegexRange(1, 10000)` | `[1-9]\|[1-9][0-9]{1,3}\|10000` | _34μs_ | +| `toRegexRange(1, 100000)` | `[1-9]\|[1-9][0-9]{1,4}\|100000` | _36μs_ | +| `toRegexRange(1, 1000000)` | `[1-9]\|[1-9][0-9]{1,5}\|1000000` | _42μs_ | +| `toRegexRange(1, 10000000)` | `[1-9]\|[1-9][0-9]{1,6}\|10000000` | _42μs_ | + +## Heads up! + +**Order of arguments** + +When the `min` is larger than the `max`, values will be flipped to create a valid range: + +```js +toRegexRange('51', '29'); +``` + +Is effectively flipped to: + +```js +toRegexRange('29', '51'); +//=> 29|[3-4][0-9]|5[0-1] +``` + +**Steps / increments** + +This library does not support steps (increments). A pr to add support would be welcome. + +## History + +### v2.0.0 - 2017-04-21 + +**New features** + +Adds support for zero-padding! + +### v1.0.0 + +**Optimizations** + +Repeating ranges are now grouped using quantifiers. rocessing time is roughly the same, but the generated regex is much smaller, which should result in faster matching. + +## Attribution + +Inspired by the python library [range-regex](https://github.com/dimka665/range-regex). + +## About + +<details> +<summary><strong>Contributing</strong></summary> + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +</details> + +<details> +<summary><strong>Running Tests</strong></summary> + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +$ npm install && npm test +``` + +</details> + +<details> +<summary><strong>Building docs</strong></summary> + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +$ npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +</details> + +### Related projects + +You might also be interested in these projects: + +* [expand-range](https://www.npmjs.com/package/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. Used… [more](https://github.com/jonschlinkert/expand-range) | [homepage](https://github.com/jonschlinkert/expand-range "Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. Used by micromatch.") +* [fill-range](https://www.npmjs.com/package/fill-range): Fill in a range of numbers or letters, optionally passing an increment or `step` to… [more](https://github.com/jonschlinkert/fill-range) | [homepage](https://github.com/jonschlinkert/fill-range "Fill in a range of numbers or letters, optionally passing an increment or `step` to use, or create a regex-compatible range with `options.toRegex`") +* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/micromatch/micromatch "Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch.") +* [repeat-element](https://www.npmjs.com/package/repeat-element): Create an array by repeating the given value n times. | [homepage](https://github.com/jonschlinkert/repeat-element "Create an array by repeating the given value n times.") +* [repeat-string](https://www.npmjs.com/package/repeat-string): Repeat the given string n times. Fastest implementation for repeating a string. | [homepage](https://github.com/jonschlinkert/repeat-string "Repeat the given string n times. Fastest implementation for repeating a string.") + +### Contributors + +| **Commits** | **Contributor** | +| --- | --- | +| 63 | [jonschlinkert](https://github.com/jonschlinkert) | +| 3 | [doowb](https://github.com/doowb) | +| 2 | [realityking](https://github.com/realityking) | + +### Author + +**Jon Schlinkert** + +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) + +Please consider supporting me on Patreon, or [start your own Patreon page](https://patreon.com/invite/bxpbvm)! + +<a href="https://www.patreon.com/jonschlinkert"> +<img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="50"> +</a> + +### License + +Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 07, 2019._ \ No newline at end of file diff --git a/node_modules/to-regex-range/index.js b/node_modules/to-regex-range/index.js new file mode 100644 index 0000000..77fbace --- /dev/null +++ b/node_modules/to-regex-range/index.js @@ -0,0 +1,288 @@ +/*! + * to-regex-range <https://github.com/micromatch/to-regex-range> + * + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +const isNumber = require('is-number'); + +const toRegexRange = (min, max, options) => { + if (isNumber(min) === false) { + throw new TypeError('toRegexRange: expected the first argument to be a number'); + } + + if (max === void 0 || min === max) { + return String(min); + } + + if (isNumber(max) === false) { + throw new TypeError('toRegexRange: expected the second argument to be a number.'); + } + + let opts = { relaxZeros: true, ...options }; + if (typeof opts.strictZeros === 'boolean') { + opts.relaxZeros = opts.strictZeros === false; + } + + let relax = String(opts.relaxZeros); + let shorthand = String(opts.shorthand); + let capture = String(opts.capture); + let wrap = String(opts.wrap); + let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; + + if (toRegexRange.cache.hasOwnProperty(cacheKey)) { + return toRegexRange.cache[cacheKey].result; + } + + let a = Math.min(min, max); + let b = Math.max(min, max); + + if (Math.abs(a - b) === 1) { + let result = min + '|' + max; + if (opts.capture) { + return `(${result})`; + } + if (opts.wrap === false) { + return result; + } + return `(?:${result})`; + } + + let isPadded = hasPadding(min) || hasPadding(max); + let state = { min, max, a, b }; + let positives = []; + let negatives = []; + + if (isPadded) { + state.isPadded = isPadded; + state.maxLen = String(state.max).length; + } + + if (a < 0) { + let newMin = b < 0 ? Math.abs(b) : 1; + negatives = splitToPatterns(newMin, Math.abs(a), state, opts); + a = state.a = 0; + } + + if (b >= 0) { + positives = splitToPatterns(a, b, state, opts); + } + + state.negatives = negatives; + state.positives = positives; + state.result = collatePatterns(negatives, positives, opts); + + if (opts.capture === true) { + state.result = `(${state.result})`; + } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { + state.result = `(?:${state.result})`; + } + + toRegexRange.cache[cacheKey] = state; + return state.result; +}; + +function collatePatterns(neg, pos, options) { + let onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; + let onlyPositive = filterPatterns(pos, neg, '', false, options) || []; + let intersected = filterPatterns(neg, pos, '-?', true, options) || []; + let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); + return subpatterns.join('|'); +} + +function splitToRanges(min, max) { + let nines = 1; + let zeros = 1; + + let stop = countNines(min, nines); + let stops = new Set([max]); + + while (min <= stop && stop <= max) { + stops.add(stop); + nines += 1; + stop = countNines(min, nines); + } + + stop = countZeros(max + 1, zeros) - 1; + + while (min < stop && stop <= max) { + stops.add(stop); + zeros += 1; + stop = countZeros(max + 1, zeros) - 1; + } + + stops = [...stops]; + stops.sort(compare); + return stops; +} + +/** + * Convert a range to a regex pattern + * @param {Number} `start` + * @param {Number} `stop` + * @return {String} + */ + +function rangeToPattern(start, stop, options) { + if (start === stop) { + return { pattern: start, count: [], digits: 0 }; + } + + let zipped = zip(start, stop); + let digits = zipped.length; + let pattern = ''; + let count = 0; + + for (let i = 0; i < digits; i++) { + let [startDigit, stopDigit] = zipped[i]; + + if (startDigit === stopDigit) { + pattern += startDigit; + + } else if (startDigit !== '0' || stopDigit !== '9') { + pattern += toCharacterClass(startDigit, stopDigit, options); + + } else { + count++; + } + } + + if (count) { + pattern += options.shorthand === true ? '\\d' : '[0-9]'; + } + + return { pattern, count: [count], digits }; +} + +function splitToPatterns(min, max, tok, options) { + let ranges = splitToRanges(min, max); + let tokens = []; + let start = min; + let prev; + + for (let i = 0; i < ranges.length; i++) { + let max = ranges[i]; + let obj = rangeToPattern(String(start), String(max), options); + let zeros = ''; + + if (!tok.isPadded && prev && prev.pattern === obj.pattern) { + if (prev.count.length > 1) { + prev.count.pop(); + } + + prev.count.push(obj.count[0]); + prev.string = prev.pattern + toQuantifier(prev.count); + start = max + 1; + continue; + } + + if (tok.isPadded) { + zeros = padZeros(max, tok, options); + } + + obj.string = zeros + obj.pattern + toQuantifier(obj.count); + tokens.push(obj); + start = max + 1; + prev = obj; + } + + return tokens; +} + +function filterPatterns(arr, comparison, prefix, intersection, options) { + let result = []; + + for (let ele of arr) { + let { string } = ele; + + // only push if _both_ are negative... + if (!intersection && !contains(comparison, 'string', string)) { + result.push(prefix + string); + } + + // or _both_ are positive + if (intersection && contains(comparison, 'string', string)) { + result.push(prefix + string); + } + } + return result; +} + +/** + * Zip strings + */ + +function zip(a, b) { + let arr = []; + for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); + return arr; +} + +function compare(a, b) { + return a > b ? 1 : b > a ? -1 : 0; +} + +function contains(arr, key, val) { + return arr.some(ele => ele[key] === val); +} + +function countNines(min, len) { + return Number(String(min).slice(0, -len) + '9'.repeat(len)); +} + +function countZeros(integer, zeros) { + return integer - (integer % Math.pow(10, zeros)); +} + +function toQuantifier(digits) { + let [start = 0, stop = ''] = digits; + if (stop || start > 1) { + return `{${start + (stop ? ',' + stop : '')}}`; + } + return ''; +} + +function toCharacterClass(a, b, options) { + return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; +} + +function hasPadding(str) { + return /^-?(0+)\d/.test(str); +} + +function padZeros(value, tok, options) { + if (!tok.isPadded) { + return value; + } + + let diff = Math.abs(tok.maxLen - String(value).length); + let relax = options.relaxZeros !== false; + + switch (diff) { + case 0: + return ''; + case 1: + return relax ? '0?' : '0'; + case 2: + return relax ? '0{0,2}' : '00'; + default: { + return relax ? `0{0,${diff}}` : `0{${diff}}`; + } + } +} + +/** + * Cache + */ + +toRegexRange.cache = {}; +toRegexRange.clearCache = () => (toRegexRange.cache = {}); + +/** + * Expose `toRegexRange` + */ + +module.exports = toRegexRange; diff --git a/node_modules/to-regex-range/package.json b/node_modules/to-regex-range/package.json new file mode 100644 index 0000000..4ef194f --- /dev/null +++ b/node_modules/to-regex-range/package.json @@ -0,0 +1,88 @@ +{ + "name": "to-regex-range", + "description": "Pass two numbers, get a regex-compatible source string for matching ranges. Validated against more than 2.78 million test assertions.", + "version": "5.0.1", + "homepage": "https://github.com/micromatch/to-regex-range", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "contributors": [ + "Jon Schlinkert (http://twitter.com/jonschlinkert)", + "Rouven Weßling (www.rouvenwessling.de)" + ], + "repository": "micromatch/to-regex-range", + "bugs": { + "url": "https://github.com/micromatch/to-regex-range/issues" + }, + "license": "MIT", + "files": [ + "index.js" + ], + "main": "index.js", + "engines": { + "node": ">=8.0" + }, + "scripts": { + "test": "mocha" + }, + "dependencies": { + "is-number": "^7.0.0" + }, + "devDependencies": { + "fill-range": "^6.0.0", + "gulp-format-md": "^2.0.0", + "mocha": "^6.0.2", + "text-table": "^0.2.0", + "time-diff": "^0.3.1" + }, + "keywords": [ + "bash", + "date", + "expand", + "expansion", + "expression", + "glob", + "match", + "match date", + "match number", + "match numbers", + "match year", + "matches", + "matching", + "number", + "numbers", + "numerical", + "range", + "ranges", + "regex", + "regexp", + "regular", + "regular expression", + "sequence" + ], + "verb": { + "layout": "default", + "toc": false, + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + }, + "helpers": { + "examples": { + "displayName": "examples" + } + }, + "related": { + "list": [ + "expand-range", + "fill-range", + "micromatch", + "repeat-element", + "repeat-string" + ] + } + } +} diff --git a/node_modules/totalist/dist/index.js b/node_modules/totalist/dist/index.js new file mode 100644 index 0000000..ad75d83 --- /dev/null +++ b/node_modules/totalist/dist/index.js @@ -0,0 +1,24 @@ +const { join, resolve } = require('path'); +const { readdir, stat } = require('fs'); +const { promisify } = require('util'); + +const toStats = promisify(stat); +const toRead = promisify(readdir); + +async function totalist(dir, callback, pre='') { + dir = resolve('.', dir); + await toRead(dir).then(arr => { + return Promise.all( + arr.map(str => { + let abs = join(dir, str); + return toStats(abs).then(stats => { + return stats.isDirectory() + ? totalist(abs, callback, join(pre, str)) + : callback(join(pre, str), abs, stats) + }); + }) + ); + }); +} + +exports.totalist = totalist; \ No newline at end of file diff --git a/node_modules/totalist/dist/index.mjs b/node_modules/totalist/dist/index.mjs new file mode 100644 index 0000000..e445936 --- /dev/null +++ b/node_modules/totalist/dist/index.mjs @@ -0,0 +1,22 @@ +import { join, resolve } from 'path'; +import { readdir, stat } from 'fs'; +import { promisify } from 'util'; + +const toStats = promisify(stat); +const toRead = promisify(readdir); + +export async function totalist(dir, callback, pre='') { + dir = resolve('.', dir); + await toRead(dir).then(arr => { + return Promise.all( + arr.map(str => { + let abs = join(dir, str); + return toStats(abs).then(stats => { + return stats.isDirectory() + ? totalist(abs, callback, join(pre, str)) + : callback(join(pre, str), abs, stats) + }); + }) + ); + }); +} diff --git a/node_modules/totalist/index.d.ts b/node_modules/totalist/index.d.ts new file mode 100644 index 0000000..bbb3698 --- /dev/null +++ b/node_modules/totalist/index.d.ts @@ -0,0 +1,3 @@ +import { Stats } from 'fs'; +export type Caller = (relPath: string, absPath: string, stats: Stats) => any; +export function totalist(dir: string, callback: Caller, prefix?: string): Promise<void>; diff --git a/node_modules/totalist/license b/node_modules/totalist/license new file mode 100644 index 0000000..a3f96f8 --- /dev/null +++ b/node_modules/totalist/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/totalist/package.json b/node_modules/totalist/package.json new file mode 100644 index 0000000..764ec86 --- /dev/null +++ b/node_modules/totalist/package.json @@ -0,0 +1,55 @@ +{ + "name": "totalist", + "version": "3.0.1", + "repository": "lukeed/totalist", + "description": "A tiny (195B to 220B) utility to recursively list all (total) files in a directory", + "module": "dist/index.mjs", + "main": "dist/index.js", + "types": "index.d.ts", + "exports": { + ".": { + "types": "./index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js" + }, + "./sync": { + "types": "./sync/index.d.ts", + "import": "./sync/index.mjs", + "require": "./sync/index.js" + } + }, + "license": "MIT", + "files": [ + "index.d.ts", + "dist", + "sync" + ], + "author": { + "name": "Luke Edwards", + "email": "luke.edwards05@gmail.com", + "url": "https://lukeed.com" + }, + "engines": { + "node": ">=6" + }, + "keywords": [ + "list", + "recursive", + "files", + "glob", + "tree" + ], + "scripts": { + "build": "bundt", + "test": "uvu -r esm test -i fixtures" + }, + "modes": { + "sync": "src/sync.js", + "default": "src/async.js" + }, + "devDependencies": { + "bundt": "1.1.1", + "esm": "3.2.25", + "uvu": "0.3.3" + } +} diff --git a/node_modules/totalist/readme.md b/node_modules/totalist/readme.md new file mode 100644 index 0000000..79491ee --- /dev/null +++ b/node_modules/totalist/readme.md @@ -0,0 +1,109 @@ +# totalist [![build status](https://badgen.now.sh/github/status/lukeed/totalist)](https://github.com/lukeed/totalist/actions) [![codecov](https://badgen.now.sh/codecov/c/github/lukeed/totalist)](https://codecov.io/gh/lukeed/totalist) + +> A tiny (195B to 224B) utility to recursively list all (total) files in a directory + +Traverse a directory recursively, running a function for **every file** found. + +With this module, you easily apply custom logic to decide which file(s) to process without worrying about accidentally accessing a directory or making repeat `fs.Stats` requests. + +## Install + +``` +$ npm install --save totalist +``` + + +## Modes + +There are two "versions" of `totalist` available: + +#### "async" +> **Node.js:** >= 8.x<br> +> **Size (gzip):** 220 bytes<br> +> **Availability:** [CommonJS](https://unpkg.com/totalist/dist/index.js), [ES Module](https://unpkg.com/totalist/dist/index.mjs) + +This is the primary/default mode. It makes use of `async`/`await` and [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original). + +#### "sync" +> **Node.js:** >= 6.x<br> +> **Size (gzip):** 195 bytes<br> +> **Availability:** [CommonJS](https://unpkg.com/totalist/sync/index.js), [ES Module](https://unpkg.com/totalist/sync/index.mjs) + +This is the opt-in mode, ideal for scenarios where `async` usage cannot be supported. + + +## Usage + +***Selecting a Mode*** + +```js +// import via npm module +import { totalist } from 'totalist'; +import { totalist } from 'totalist/sync'; +``` + +***Example Usage*** + +```js +import { totalist } from 'totalist/sync'; + +const styles = new Set(); +const scripts = new Set(); + +totalist('src', (name, abs, stats) => { + if (/\.js$/.test(name)) { + scripts.add(abs); + if (stats.size >= 100e3) { + console.warn(`[WARN] "${name}" might cause performance issues (${stats.size})`); + } + } else if (/\.css$/.test(name)) { + styles.add(abs); + } +}); + +console.log([...scripts]); +//=> [..., '/Users/lukeed/.../src/path/to/example.css', ...] +``` + + +## API + +### totalist(dir, callback) +Returns: `void` + +> **Important:** The "async" usage must be `await`ed or included within a Promise chain. + +#### dir +Type: `string`<br> +Required: `true` + +The directory to traverse. + +This may be a relative _or_ an absolute path. + +> **Note**: Node.js will assume a relative path is meant to be resolved from the current location (`process.cwd()`). + +#### callback +Type: `Function`<br> +Required: `true` + +The callback function to run for _every_ file. + +The function receives three parameters: + +##### relPath +Type: `String`<br> +The path _relative to_ the initial `dir` value you provided. + +##### absPath +Type: `String`<br> +The absolute path of the file. + +##### stats +Type: `fs.Stats`<br> +The [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object for the file. + + +## License + +MIT © [Luke Edwards](https://lukeed.com) diff --git a/node_modules/totalist/sync/index.d.ts b/node_modules/totalist/sync/index.d.ts new file mode 100644 index 0000000..5f2d6d5 --- /dev/null +++ b/node_modules/totalist/sync/index.d.ts @@ -0,0 +1,3 @@ +import { Stats } from 'fs'; +export type Caller = (relPath: string, absPath: string, stats: Stats) => any; +export function totalist(dir: string, callback: Caller, prefix?: string): void; diff --git a/node_modules/totalist/sync/index.js b/node_modules/totalist/sync/index.js new file mode 100644 index 0000000..9e5bc46 --- /dev/null +++ b/node_modules/totalist/sync/index.js @@ -0,0 +1,17 @@ +const { join, resolve } = require('path'); +const { readdirSync, statSync } = require('fs'); + +function totalist(dir, callback, pre='') { + dir = resolve('.', dir); + let arr = readdirSync(dir); + let i=0, abs, stats; + for (; i < arr.length; i++) { + abs = join(dir, arr[i]); + stats = statSync(abs); + stats.isDirectory() + ? totalist(abs, callback, join(pre, arr[i])) + : callback(join(pre, arr[i]), abs, stats); + } +} + +exports.totalist = totalist; \ No newline at end of file diff --git a/node_modules/totalist/sync/index.mjs b/node_modules/totalist/sync/index.mjs new file mode 100644 index 0000000..e751c3f --- /dev/null +++ b/node_modules/totalist/sync/index.mjs @@ -0,0 +1,15 @@ +import { join, resolve } from 'path'; +import { readdirSync, statSync } from 'fs'; + +export function totalist(dir, callback, pre='') { + dir = resolve('.', dir); + let arr = readdirSync(dir); + let i=0, abs, stats; + for (; i < arr.length; i++) { + abs = join(dir, arr[i]); + stats = statSync(abs); + stats.isDirectory() + ? totalist(abs, callback, join(pre, arr[i])) + : callback(join(pre, arr[i]), abs, stats); + } +} diff --git a/node_modules/type-fest/index.d.ts b/node_modules/type-fest/index.d.ts new file mode 100644 index 0000000..3c7621b --- /dev/null +++ b/node_modules/type-fest/index.d.ts @@ -0,0 +1,130 @@ +// Basic +export * from './source/primitive'; +export * from './source/typed-array'; +export * from './source/basic'; +export * from './source/observable-like'; + +// Utilities +export type {EmptyObject, IsEmptyObject} from './source/empty-object'; +export type {Except} from './source/except'; +export type {TaggedUnion} from './source/tagged-union'; +export type {Writable} from './source/writable'; +export type {WritableDeep} from './source/writable-deep'; +export type {Merge} from './source/merge'; +export type {MergeDeep, MergeDeepOptions} from './source/merge-deep'; +export type {MergeExclusive} from './source/merge-exclusive'; +export type {RequireAtLeastOne} from './source/require-at-least-one'; +export type {RequireExactlyOne} from './source/require-exactly-one'; +export type {RequireAllOrNone} from './source/require-all-or-none'; +export type { + OmitIndexSignature, + /** + @deprecated Renamed to {@link OmitIndexSignature}. + */ + OmitIndexSignature as RemoveIndexSignature, +} from './source/omit-index-signature'; +export type {PickIndexSignature} from './source/pick-index-signature'; +export type {PartialDeep, PartialDeepOptions} from './source/partial-deep'; +export type {RequiredDeep} from './source/required-deep'; +export type {PartialOnUndefinedDeep, PartialOnUndefinedDeepOptions} from './source/partial-on-undefined-deep'; +export type {ReadonlyDeep} from './source/readonly-deep'; +export type {LiteralUnion} from './source/literal-union'; +export type {Promisable} from './source/promisable'; +export type {Opaque, UnwrapOpaque} from './source/opaque'; +export type {InvariantOf} from './source/invariant-of'; +export type {SetOptional} from './source/set-optional'; +export type {SetReadonly} from './source/set-readonly'; +export type {SetRequired} from './source/set-required'; +export type {SetNonNullable} from './source/set-non-nullable'; +export type {ValueOf} from './source/value-of'; +export type {AsyncReturnType} from './source/async-return-type'; +export type {ConditionalExcept} from './source/conditional-except'; +export type {ConditionalKeys} from './source/conditional-keys'; +export type {ConditionalPick} from './source/conditional-pick'; +export type {ConditionalPickDeep, ConditionalPickDeepOptions} from './source/conditional-pick-deep'; +export type {UnionToIntersection} from './source/union-to-intersection'; +export type {Stringified} from './source/stringified'; +export type {FixedLengthArray} from './source/fixed-length-array'; +export type {MultidimensionalArray} from './source/multidimensional-array'; +export type {MultidimensionalReadonlyArray} from './source/multidimensional-readonly-array'; +export type {IterableElement} from './source/iterable-element'; +export type {Entry} from './source/entry'; +export type {Entries} from './source/entries'; +export type {SetReturnType} from './source/set-return-type'; +export type {Asyncify} from './source/asyncify'; +export type {Simplify} from './source/simplify'; +export type {Jsonify} from './source/jsonify'; +export type {Jsonifiable} from './source/jsonifiable'; +export type {Schema} from './source/schema'; +export type {LiteralToPrimitive} from './source/literal-to-primitive'; +export type {LiteralToPrimitiveDeep} from './source/literal-to-primitive-deep'; +export type { + PositiveInfinity, + NegativeInfinity, + Finite, + Integer, + Float, + NegativeFloat, + Negative, + NonNegative, + NegativeInteger, + NonNegativeInteger, +} from './source/numeric'; +export type {StringKeyOf} from './source/string-key-of'; +export type {Exact} from './source/exact'; +export type {ReadonlyTuple} from './source/readonly-tuple'; +export type {OptionalKeysOf} from './source/optional-keys-of'; +export type {OverrideProperties} from './source/override-properties'; +export type {HasOptionalKeys} from './source/has-optional-keys'; +export type {RequiredKeysOf} from './source/required-keys-of'; +export type {HasRequiredKeys} from './source/has-required-keys'; +export type {ReadonlyKeysOf} from './source/readonly-keys-of'; +export type {HasReadonlyKeys} from './source/has-readonly-keys'; +export type {WritableKeysOf} from './source/writable-keys-of'; +export type {HasWritableKeys} from './source/has-writable-keys'; +export type {Spread} from './source/spread'; +export type {TupleToUnion} from './source/tuple-to-union'; +export type {IsEqual} from './source/is-equal'; +export type { + IsLiteral, + IsStringLiteral, + IsNumericLiteral, + IsBooleanLiteral, + IsSymbolLiteral, +} from './source/is-literal'; +export type {IsAny} from './source/is-any'; +export type {IfAny} from './source/if-any'; +export type {IsNever} from './source/is-never'; +export type {IfNever} from './source/if-never'; +export type {IsUnknown} from './source/is-unknown'; +export type {IfUnknown} from './source/if-unknown'; + +// Template literal types +export type {CamelCase} from './source/camel-case'; +export type {CamelCasedProperties} from './source/camel-cased-properties'; +export type {CamelCasedPropertiesDeep} from './source/camel-cased-properties-deep'; +export type {KebabCase} from './source/kebab-case'; +export type {KebabCasedProperties} from './source/kebab-cased-properties'; +export type {KebabCasedPropertiesDeep} from './source/kebab-cased-properties-deep'; +export type {PascalCase} from './source/pascal-case'; +export type {PascalCasedProperties} from './source/pascal-cased-properties'; +export type {PascalCasedPropertiesDeep} from './source/pascal-cased-properties-deep'; +export type {SnakeCase} from './source/snake-case'; +export type {SnakeCasedProperties} from './source/snake-cased-properties'; +export type {SnakeCasedPropertiesDeep} from './source/snake-cased-properties-deep'; +export type {ScreamingSnakeCase} from './source/screaming-snake-case'; +export type {DelimiterCase} from './source/delimiter-case'; +export type {DelimiterCasedProperties} from './source/delimiter-cased-properties'; +export type {DelimiterCasedPropertiesDeep} from './source/delimiter-cased-properties-deep'; +export type {Join} from './source/join'; +export type {Split} from './source/split'; +export type {Trim} from './source/trim'; +export type {Replace} from './source/replace'; +export type {Includes} from './source/includes'; +export type {Get} from './source/get'; +export type {LastArrayElement} from './source/last-array-element'; + +// Miscellaneous +export type {GlobalThis} from './source/global-this'; +export type {PackageJson} from './source/package-json'; +export type {TsConfigJson} from './source/tsconfig-json'; diff --git a/node_modules/type-fest/package.json b/node_modules/type-fest/package.json new file mode 100644 index 0000000..35800bd --- /dev/null +++ b/node_modules/type-fest/package.json @@ -0,0 +1,59 @@ +{ + "name": "type-fest", + "version": "3.13.1", + "description": "A collection of essential TypeScript types", + "license": "(MIT OR CC0-1.0)", + "repository": "sindresorhus/type-fest", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "types": "./index.d.ts", + "engines": { + "node": ">=14.16" + }, + "scripts": { + "test": "xo && tsd && tsc && node script/test/source-files-extension.js" + }, + "files": [ + "index.d.ts", + "source" + ], + "keywords": [ + "typescript", + "ts", + "types", + "utility", + "util", + "utilities", + "omit", + "merge", + "json", + "generics" + ], + "devDependencies": { + "@sindresorhus/tsconfig": "~0.7.0", + "expect-type": "^0.15.0", + "tsd": "^0.28.1", + "typescript": "^5.0.4", + "xo": "^0.54.2" + }, + "xo": { + "rules": { + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/naming-convention": "off", + "import/extensions": "off", + "@typescript-eslint/no-redeclare": "off", + "@typescript-eslint/no-confusing-void-expression": "off", + "@typescript-eslint/no-unsafe-argument": "off" + } + }, + "tsd": { + "compilerOptions": { + "noUnusedLocals": false + } + } +} diff --git a/node_modules/type-fest/readme.md b/node_modules/type-fest/readme.md new file mode 100644 index 0000000..ea4949f --- /dev/null +++ b/node_modules/type-fest/readme.md @@ -0,0 +1,922 @@ +<div align="center"> + <br> + <br> + <img src="media/logo.svg" alt="type-fest" height="300"> + <br> + <br> + <b>A collection of essential TypeScript types</b> + <br> + <br> + <br> + <br> + <hr> + <div align="center"> + <p> + <p> + <sup> + <a href="https://github.com/sponsors/sindresorhus">Sindre Sorhus' open source work is supported by the community</a> + </sup> + </p> + <sup>Special thanks to:</sup> + <br> + <br> + <a href="https://standardresume.co/tech"> + <img src="https://sindresorhus.com/assets/thanks/standard-resume-logo.svg" width="180"/> + </a> + <br> + <br> + <br> + <a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=type-fest&utm_source=github"> + <div> + <img src="https://sindresorhus.com/assets/thanks/workos-logo-white-bg.svg" width="220" alt="WorkOS"> + </div> + <b>Your app, enterprise-ready.</b> + <div> + <sub>Start selling to enterprise customers with just a few lines of code.</sub> + <br> + <sup>Add Single Sign-On (and more) in minutes instead of months.</sup> + </div> + </a> + </p> + </div> + <br> + <hr> +</div> +<br> +<br> + +[![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://giphy.com/gifs/illustration-rainbow-unicorn-26AHG5KGFxSkUWw1i) +[![npm dependents](https://badgen.net/npm/dependents/type-fest)](https://www.npmjs.com/package/type-fest?activeTab=dependents) +[![npm downloads](https://badgen.net/npm/dt/type-fest)](https://www.npmjs.com/package/type-fest) +[![Docs](https://paka.dev/badges/v0/cute.svg)](https://paka.dev/npm/type-fest) + +Many of the types here should have been built-in. You can help by suggesting some of them to the [TypeScript project](https://github.com/Microsoft/TypeScript/blob/main/CONTRIBUTING.md). + +Either add this package as a dependency or copy-paste the needed types. No credit required. 👌 + +PR welcome for additional commonly needed types and docs improvements. Read the [contributing guidelines](.github/contributing.md) first. + +**Help wanted with reviewing [proposals](https://github.com/sindresorhus/type-fest/issues) and [pull requests](https://github.com/sindresorhus/type-fest/pulls).** + +## Install + +```sh +npm install type-fest +``` + +*Requires TypeScript >=4.7* + +## Usage + +```ts +import type {Except} from 'type-fest'; + +type Foo = { + unicorn: string; + rainbow: boolean; +}; + +type FooWithoutRainbow = Except<Foo, 'rainbow'>; +//=> {unicorn: string} +``` + +## API + +Click the type names for complete docs. + +### Basic + +- [`Primitive`](source/primitive.d.ts) - Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive). +- [`Class`](source/basic.d.ts) - Matches a [`class`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). +- [`Constructor`](source/basic.d.ts) - Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). +- [`AbstractClass`](source/basic.d.ts) - Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/classes.html#abstract-classes). +- [`AbstractConstructor`](source/basic.d.ts) - Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-2.html#abstract-construct-signatures) constructor. +- [`TypedArray`](source/typed-array.d.ts) - Matches any [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray), like `Uint8Array` or `Float64Array`. +- [`ObservableLike`](source/observable-like.d.ts) - Matches a value that is like an [Observable](https://github.com/tc39/proposal-observable). + +### Utilities + +- [`EmptyObject`](source/empty-object.d.ts) - Represents a strictly empty plain object, the `{}` value. +- [`IsEmptyObject`](source/empty-object.d.ts) - Returns a `boolean` for whether the type is strictly equal to an empty plain object, the `{}` value. +- [`Except`](source/except.d.ts) - Create a type from an object type without certain keys. This is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys). +- [`Writable`](source/writable.d.ts) - Create a type that strips `readonly` from all or some of an object's keys. The inverse of `Readonly<T>`. +- [`WritableDeep`](source/writable-deep.d.ts) - Create a deeply mutable version of an `object`/`ReadonlyMap`/`ReadonlySet`/`ReadonlyArray` type. The inverse of `ReadonlyDeep<T>`. Use `Writable<T>` if you only need one level deep. +- [`Merge`](source/merge.d.ts) - Merge two types into a new type. Keys of the second type overrides keys of the first type. +- [`MergeDeep`](source/merge-deep.d.ts) - Merge two objects or two arrays/tuples recursively into a new type. +- [`MergeExclusive`](source/merge-exclusive.d.ts) - Create a type that has mutually exclusive keys. +- [`OverrideProperties`](source/override-properties.d.ts) - Override only existing properties of the given type. Similar to `Merge`, but enforces that the original type has the properties you want to override. +- [`RequireAtLeastOne`](source/require-at-least-one.d.ts) - Create a type that requires at least one of the given keys. +- [`RequireExactlyOne`](source/require-exactly-one.d.ts) - Create a type that requires exactly a single key of the given keys and disallows more. +- [`RequireAllOrNone`](source/require-all-or-none.d.ts) - Create a type that requires all of the given keys or none of the given keys. +- [`RequiredDeep`](source/required-deep.d.ts) - Create a deeply required version of another type. Use [`Required<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#requiredtype) if you only need one level deep. +- [`OmitIndexSignature`](source/omit-index-signature.d.ts) - Omit any index signatures from the given object type, leaving only explicitly defined properties. +- [`PickIndexSignature`](source/pick-index-signature.d.ts) - Pick only index signatures from the given object type, leaving out all explicitly defined properties. +- [`PartialDeep`](source/partial-deep.d.ts) - Create a deeply optional version of another type. Use [`Partial<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype) if you only need one level deep. +- [`PartialOnUndefinedDeep`](source/partial-on-undefined-deep.d.ts) - Create a deep version of another type where all keys accepting `undefined` type are set to optional. +- [`ReadonlyDeep`](source/readonly-deep.d.ts) - Create a deeply immutable version of an `object`/`Map`/`Set`/`Array` type. Use [`Readonly<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlytype) if you only need one level deep. +- [`LiteralUnion`](source/literal-union.d.ts) - Create a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union. Workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729). +- [`Opaque`](source/opaque.d.ts) - Create an [opaque type](https://codemix.com/opaque-types-in-javascript/). +- [`UnwrapOpaque`](source/opaque.d.ts) - Revert an [opaque type](https://codemix.com/opaque-types-in-javascript/) back to its original type. +- [`InvariantOf`](source/invariant-of.d.ts) - Create an [invariant type](https://basarat.gitbook.io/typescript/type-system/type-compatibility#footnote-invariance), which is a type that does not accept supertypes and subtypes. +- [`SetOptional`](source/set-optional.d.ts) - Create a type that makes the given keys optional. +- [`SetReadonly`](source/set-readonly.d.ts) - Create a type that makes the given keys readonly. +- [`SetRequired`](source/set-required.d.ts) - Create a type that makes the given keys required. +- [`SetNonNullable`](source/set-non-nullable.d.ts) - Create a type that makes the given keys non-nullable. +- [`ValueOf`](source/value-of.d.ts) - Create a union of the given object's values, and optionally specify which keys to get the values from. +- [`ConditionalKeys`](source/conditional-keys.d.ts) - Extract keys from a shape where values extend the given `Condition` type. +- [`ConditionalPick`](source/conditional-pick.d.ts) - Like `Pick` except it selects properties from a shape where the values extend the given `Condition` type. +- [`ConditionalPickDeep`](source/conditional-pick-deep.d.ts) - Like `ConditionalPick` except that it selects the properties deeply. +- [`ConditionalExcept`](source/conditional-except.d.ts) - Like `Omit` except it removes properties from a shape where the values extend the given `Condition` type. +- [`UnionToIntersection`](source/union-to-intersection.d.ts) - Convert a union type to an intersection type. +- [`LiteralToPrimitive`](source/literal-to-primitive.d.ts) - Convert a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) to the [primitive type](source/primitive.d.ts) it belongs to. +- [`LiteralToPrimitiveDeep`](source/literal-to-primitive-deep.d.ts) - Like `LiteralToPrimitive` except it converts literal types inside an object or array deeply. +- [`Stringified`](source/stringified.d.ts) - Create a type with the keys of the given type changed to `string` type. +- [`IterableElement`](source/iterable-element.d.ts) - Get the element type of an `Iterable`/`AsyncIterable`. For example, an array or a generator. +- [`Entry`](source/entry.d.ts) - Create a type that represents the type of an entry of a collection. +- [`Entries`](source/entries.d.ts) - Create a type that represents the type of the entries of a collection. +- [`SetReturnType`](source/set-return-type.d.ts) - Create a function type with a return type of your choice and the same parameters as the given function type. +- [`Simplify`](source/simplify.d.ts) - Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability. +- [`Get`](source/get.d.ts) - Get a deeply-nested property from an object using a key path, like [Lodash's `.get()`](https://lodash.com/docs/latest#get) function. +- [`StringKeyOf`](source/string-key-of.d.ts) - Get keys of the given type as strings. +- [`Schema`](source/schema.d.ts) - Create a deep version of another object type where property values are recursively replaced into a given value type. +- [`Exact`](source/exact.d.ts) - Create a type that does not allow extra properties. +- [`OptionalKeysOf`](source/optional-keys-of.d.ts) - Extract all optional keys from the given type. +- [`HasOptionalKeys`](source/has-optional-keys.d.ts) - Create a `true`/`false` type depending on whether the given type has any optional fields. +- [`RequiredKeysOf`](source/required-keys-of.d.ts) - Extract all required keys from the given type. +- [`HasRequiredKeys`](source/has-required-keys.d.ts) - Create a `true`/`false` type depending on whether the given type has any required fields. +- [`ReadonlyKeysOf`](source/readonly-keys-of.d.ts) - Extract all readonly keys from the given type. +- [`HasReadonlyKeys`](source/has-readonly-keys.d.ts) - Create a `true`/`false` type depending on whether the given type has any readonly fields. +- [`WritableKeysOf`](source/writable-keys-of.d.ts) - Extract all writable (non-readonly) keys from the given type. +- [`HasWritableKeys`](source/has-writable-keys.d.ts) - Create a `true`/`false` type depending on whether the given type has any writable fields. +- [`Spread`](source/spread.d.ts) - Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax. +- [`IsEqual`](source/is-equal.d.ts) - Returns a boolean for whether the two given types are equal. +- [`TaggedUnion`](source/tagged-union.d.ts) - Create a union of types that share a common discriminant property. + +### Type Guard + +#### `IsType` vs. `IfType` + +For every `IsT` type (e.g. `IsAny`), there is an associated `IfT` type that can help simplify conditional types. While the `IsT` types return a `boolean`, the `IfT` types act like an `If`/`Else` - they resolve to the given `TypeIfT` or `TypeIfNotT` depending on whether `IsX` is `true` or not. By default, `IfT` returns a `boolean`: + +```ts +type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = ( + IsAny<T> extends true ? TypeIfAny : TypeIfNotAny +); +``` + +#### Usage + +```ts +import type {IsAny, IfAny} from 'type-fest'; + +type ShouldBeTrue = IsAny<any> extends true ? true : false; +//=> true + +type ShouldBeFalse = IfAny<'not any'>; +//=> false + +type ShouldBeNever = IfAny<'not any', 'not never', 'never'>; +//=> 'never' +``` + +- [`IsLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). +- [`IsStringLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `string` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). +- [`IsNumericLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). +- [`IsBooleanLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `true` or `false` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). +- [`IsSymbolLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `symbol` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). +- [`IsAny`](source/is-any.d.ts) - Returns a boolean for whether the given type is `any`. (Conditional version: [`IfAny`](source/if-any.d.ts).) +- [`IsNever`](source/is-never.d.ts) - Returns a boolean for whether the given type is `never`. (Conditional version: [`IfNever`](source/if-never.d.ts).) +- [`IsUnknown`](source/is-unknown.d.ts) - Returns a boolean for whether the given type is `unknown`. (Conditional version: [`IfUnknown`](source/if-unknown.d.ts).) + +### JSON + +- [`Jsonify`](source/jsonify.d.ts) - Transform a type to one that is assignable to the `JsonValue` type. +- [`Jsonifiable`](source/jsonifiable.d.ts) - Matches a value that can be losslessly converted to JSON. +- [`JsonPrimitive`](source/basic.d.ts) - Matches a JSON primitive. +- [`JsonObject`](source/basic.d.ts) - Matches a JSON object. +- [`JsonArray`](source/basic.d.ts) - Matches a JSON array. +- [`JsonValue`](source/basic.d.ts) - Matches any valid JSON value. + +### Async + +- [`Promisable`](source/promisable.d.ts) - Create a type that represents either the value or the value wrapped in `PromiseLike`. +- [`AsyncReturnType`](source/async-return-type.d.ts) - Unwrap the return type of a function that returns a `Promise`. +- [`Asyncify`](source/asyncify.d.ts) - Create an async version of the given function type. + +### String + +- [`Trim`](source/trim.d.ts) - Remove leading and trailing spaces from a string. +- [`Split`](source/split.d.ts) - Represents an array of strings split using a given character or character set. +- [`Replace`](source/replace.d.ts) - Represents a string with some or all matches replaced by a replacement. + +### Array + +- [`Includes`](source/includes.d.ts) - Returns a boolean for whether the given array includes the given item. +- [`Join`](source/join.d.ts) - Join an array of strings and/or numbers using the given string as a delimiter. +- [`LastArrayElement`](source/last-array-element.d.ts) - Extracts the type of the last element of an array. +- [`FixedLengthArray`](source/fixed-length-array.d.ts) - Create a type that represents an array of the given type and length. +- [`MultidimensionalArray`](source/multidimensional-array.d.ts) - Create a type that represents a multidimensional array of the given type and dimensions. +- [`MultidimensionalReadonlyArray`](source/multidimensional-readonly-array.d.ts) - Create a type that represents a multidimensional readonly array of the given type and dimensions. +- [`ReadonlyTuple`](source/readonly-tuple.d.ts) - Create a type that represents a read-only tuple of the given type and length. +- [`TupleToUnion`](source/tuple-to-union.d.ts) - Convert a tuple/array into a union type of its elements. + +### Numeric + +- [`PositiveInfinity`](source/numeric.d.ts) - Matches the hidden `Infinity` type. +- [`NegativeInfinity`](source/numeric.d.ts) - Matches the hidden `-Infinity` type. +- [`Finite`](source/numeric.d.ts) - A finite `number`. +- [`Integer`](source/numeric.d.ts) - A `number` that is an integer. +- [`Float`](source/numeric.d.ts) - A `number` that is not an integer. +- [`NegativeFloat`](source/numeric.d.ts) - A negative (`-∞ < x < 0`) `number` that is not an integer. +- [`Negative`](source/numeric.d.ts) - A negative `number`/`bigint` (`-∞ < x < 0`) +- [`NonNegative`](source/numeric.d.ts) - A non-negative `number`/`bigint` (`0 <= x < ∞`). +- [`NegativeInteger`](source/numeric.d.ts) - A negative (`-∞ < x < 0`) `number` that is an integer. +- [`NonNegativeInteger`](source/numeric.d.ts) - A non-negative (`0 <= x < ∞`) `number` that is an integer. + +### Change case + +- [`CamelCase`](source/camel-case.d.ts) - Convert a string literal to camel-case (`fooBar`). +- [`CamelCasedProperties`](source/camel-cased-properties.d.ts) - Convert object properties to camel-case (`fooBar`). +- [`CamelCasedPropertiesDeep`](source/camel-cased-properties-deep.d.ts) - Convert object properties to camel-case recursively (`fooBar`). +- [`KebabCase`](source/kebab-case.d.ts) - Convert a string literal to kebab-case (`foo-bar`). +- [`KebabCasedProperties`](source/kebab-cased-properties.d.ts) - Convert a object properties to kebab-case recursively (`foo-bar`). +- [`KebabCasedPropertiesDeep`](source/kebab-cased-properties-deep.d.ts) - Convert object properties to kebab-case (`foo-bar`). +- [`PascalCase`](source/pascal-case.d.ts) - Converts a string literal to pascal-case (`FooBar`) +- [`PascalCasedProperties`](source/pascal-cased-properties.d.ts) - Converts object properties to pascal-case (`FooBar`) +- [`PascalCasedPropertiesDeep`](source/pascal-cased-properties-deep.d.ts) - Converts object properties to pascal-case (`FooBar`) +- [`SnakeCase`](source/snake-case.d.ts) - Convert a string literal to snake-case (`foo_bar`). +- [`SnakeCasedProperties`](source/snake-cased-properties.d.ts) - Convert object properties to snake-case (`foo_bar`). +- [`SnakeCasedPropertiesDeep`](source/snake-cased-properties-deep.d.ts) - Convert object properties to snake-case recursively (`foo_bar`). +- [`ScreamingSnakeCase`](source/screaming-snake-case.d.ts) - Convert a string literal to screaming-snake-case (`FOO_BAR`). +- [`DelimiterCase`](source/delimiter-case.d.ts) - Convert a string literal to a custom string delimiter casing. +- [`DelimiterCasedProperties`](source/delimiter-cased-properties.d.ts) - Convert object properties to a custom string delimiter casing. +- [`DelimiterCasedPropertiesDeep`](source/delimiter-cased-properties-deep.d.ts) - Convert object properties to a custom string delimiter casing recursively. + +### Miscellaneous + +- [`GlobalThis`](source/global-this.d.ts) - Declare locally scoped properties on `globalThis`. +- [`PackageJson`](source/package-json.d.ts) - Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file). It also includes support for [TypeScript Declaration Files](https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html). +- [`TsConfigJson`](source/tsconfig-json.d.ts) - Type for [TypeScript's `tsconfig.json` file](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). + +## Declined types + +*If we decline a type addition, we will make sure to document the better solution here.* + +- [`Diff` and `Spread`](https://github.com/sindresorhus/type-fest/pull/7) - The pull request author didn't provide any real-world use-cases and the PR went stale. If you think this type is useful, provide some real-world use-cases and we might reconsider. +- [`Dictionary`](https://github.com/sindresorhus/type-fest/issues/33) - You only save a few characters (`Dictionary<number>` vs `Record<string, number>`) from [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type), which is more flexible and well-known. Also, you shouldn't use an object as a dictionary. We have `Map` in JavaScript now. +- [`ExtractProperties` and `ExtractMethods`](https://github.com/sindresorhus/type-fest/pull/4) - The types violate the single responsibility principle. Instead, refine your types into more granular type hierarchies. +- [`Url2Json`](https://github.com/sindresorhus/type-fest/pull/262) - Inferring search parameters from a URL string is a cute idea, but not very useful in practice, since search parameters are usually dynamic and defined separately. +- [`Nullish`](https://github.com/sindresorhus/type-fest/pull/318) - The type only saves a couple of characters, not everyone knows what "nullish" means, and I'm also trying to [get away from `null`](https://github.com/sindresorhus/meta/discussions/7). +- [`TitleCase`](https://github.com/sindresorhus/type-fest/pull/303) - It's not solving a common need and is a better fit for a separate package. +- [`ExtendOr` and `ExtendAnd`](https://github.com/sindresorhus/type-fest/pull/247) - The benefits don't outweigh having to learn what they mean. +- [`PackageJsonExtras`](https://github.com/sindresorhus/type-fest/issues/371) - There are too many possible configurations that can be put into `package.json`. If you would like to extend `PackageJson` to support an additional configuration in your project, please see the *Extending existing types* section below. + +## Alternative type names + +*If you know one of our types by a different name, add it here for discovery.* + +- `PartialBy` - See [`SetOptional`](https://github.com/sindresorhus/type-fest/blob/main/source/set-optional.d.ts) +- `RecordDeep`- See [`Schema`](https://github.com/sindresorhus/type-fest/blob/main/source/schema.d.ts) +- `Mutable`- See [`Writable`](https://github.com/sindresorhus/type-fest/blob/main/source/writable.d.ts) +- `Prettify`- See [`Simplify`](https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts) + +## Tips + +### Extending existing types + +- [`PackageJson`](source/package-json.d.ts) - There are a lot of tools that place extra configurations inside the `package.json` file. You can extend `PackageJson` to support these additional configurations. + <details> + <summary> + Example + </summary> + + [Playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBDAnmApnA3gBQIYGMDW2A5igFIDOEAdnNuXAEJ0o4HFmVUC+cAZlBBBwA5ElQBaXinIxhAbgCwAKFCRYCZGnQAZYFRgooPfoJHSANntmKlysWlaESFanAC8jZo-YuaAMgwLKwBhal5gIgB+AC44XX1DADpQqnCiLhsgA) + + ```ts + import type {PackageJson as BasePackageJson} from 'type-fest'; + import type {Linter} from 'eslint'; + + type PackageJson = BasePackageJson & {eslintConfig?: Linter.Config}; + ``` + </details> + +### Related + +- [typed-query-selector](https://github.com/g-plane/typed-query-selector) - Enhances `document.querySelector` and `document.querySelectorAll` with a template literal type that matches element types returned from an HTML element query selector. +- [`Linter.Config`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/eslint/index.d.ts) - Definitions for the [ESLint configuration schema](https://eslint.org/docs/user-guide/configuring/language-options). + +### Built-in types + +There are many advanced types most users don't know about. + +- [`Partial<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype) - Make all properties in `T` optional. + <details> + <summary> + Example + </summary> + + [Playground](https://www.typescriptlang.org/play/#code/JYOwLgpgTgZghgYwgAgHIHsAmEDC6QzADmyA3gLABQyycADnanALYQBcyAzmFKEQNxUaddFDAcQAV2YAjaIMoBfKlQQAbOJ05osEAIIMAQpOBrsUMkOR1eANziRkCfISKSoD4Pg4ZseAsTIALyW1DS0DEysHADkvvoMMQA0VsKi4sgAzAAMuVaKClY2wPaOknSYDrguADwA0sgQAB6QIJjaANYQAJ7oMDp+LsQAfAAUXd0cdUnI9mo+uv6uANp1ALoAlKHhyGAAFsCcAHTOAW4eYF4gyxNrwbNwago0ypRWp66jH8QcAApwYmAjxq8SWIy2FDCNDA3ToKFBQyIdR69wmfQG1TOhShyBgomQX3w3GQE2Q6IA8jIAFYQBBgI4TTiEs5bTQYsFInrLTbbHZOIlgZDlSqQABqj0kKBC3yINx6a2xfOQwH6o2FVXFaklwSCIUkbQghBAEEwENSfNOlykEGefNe5uhB2O6sgS3GPRmLogmslG1tLxUOKgEDA7hAuydtteryAA) + + ```ts + interface NodeConfig { + appName: string; + port: number; + } + + class NodeAppBuilder { + private configuration: NodeConfig = { + appName: 'NodeApp', + port: 3000 + }; + + private updateConfig<Key extends keyof NodeConfig>(key: Key, value: NodeConfig[Key]) { + this.configuration[key] = value; + } + + config(config: Partial<NodeConfig>) { + type NodeConfigKey = keyof NodeConfig; + + for (const key of Object.keys(config) as NodeConfigKey[]) { + const updateValue = config[key]; + + if (updateValue === undefined) { + continue; + } + + this.updateConfig(key, updateValue); + } + + return this; + } + } + + // `Partial<NodeConfig>`` allows us to provide only a part of the + // NodeConfig interface. + new NodeAppBuilder().config({appName: 'ToDoApp'}); + ``` + </details> + +- [`Required<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#requiredtype) - Make all properties in `T` required. + <details> + <summary> + Example + </summary> + + [Playground](https://typescript-play.js.org/?target=6#code/AQ4SwOwFwUwJwGYEMDGNgGED21VQGJZwC2wA3gFCjXAzFJgA2A-AFzADOUckA5gNxUaIYjA4ckvGG07c+g6gF8KQkAgCuEFFDA5O6gEbEwUbLm2ESwABQIixACJIoSdgCUYAR3Vg4MACYAPGYuFvYAfACU5Ko0APRxwADKMBD+wFAAFuh2Vv7OSBlYGdmc8ABu8LHKsRyGxqY4oQT21pTCIHQMjOwA5DAAHgACxAAOjDAAdChYxL0ANLHUouKSMH0AEmAAhJhY6ozpAJ77GTCMjMCiV0ToSAb7UJPPC9WRgrEJwAAqR6MwSRQPFGUFocDgRHYxnEfGAowh-zgUCOwF6KwkUl6tXqJhCeEsxDaS1AXSYfUGI3GUxmc0WSneQA) + + ```ts + interface ContactForm { + email?: string; + message?: string; + } + + function submitContactForm(formData: Required<ContactForm>) { + // Send the form data to the server. + } + + submitContactForm({ + email: 'ex@mple.com', + message: 'Hi! Could you tell me more about…', + }); + + // TypeScript error: missing property 'message' + submitContactForm({ + email: 'ex@mple.com', + }); + ``` + </details> + +- [`Readonly<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlytype) - Make all properties in `T` readonly. + <details> + <summary> + Example + </summary> + + [Playground](https://typescript-play.js.org/?target=6#code/AQ4UwOwVwW2AZA9gc3mAbmANsA3gKFCOAHkAzMgGkOJABEwAjKZa2kAUQCcvEu32AMQCGAF2FYBIAL4BufDRABLCKLBcywgMZgEKZOoDCiCGSXI8i4hGEwwALmABnUVxXJ57YFgzZHSVF8sT1BpBSItLGEnJz1kAy5LLy0TM2RHACUwYQATEywATwAeAITjU3MAPnkrCJMXLigtUT4AClxgGztKbyDgaX99I1TzAEokr1BRAAslJwA6FIqLAF48TtswHp9MHDla9hJGACswZvmyLjAwAC8wVpm5xZHkUZDaMKIwqyWXYCW0oN4sNlsA1h0ug5gAByACyBQAggAHJHQ7ZBIFoXbzBjMCz7OoQP5YIaJNYQMAAdziCVaALGNSIAHomcAACoFJFgADKWjcSNEwG4vC4ji0wggEEQguiTnMEGALWAV1yAFp8gVgEjeFyuKICvMrCTgVxnst5jtsGC4ljsPNhXxGaAWcAAOq6YRXYDCRg+RWIcA5JSC+kWdCepQ+v3RYCU3RInzRMCGwlpC19NYBW1Ye08R1AA) + + ```ts + enum LogLevel { + Off, + Debug, + Error, + Fatal + }; + + interface LoggerConfig { + name: string; + level: LogLevel; + } + + class Logger { + config: Readonly<LoggerConfig>; + + constructor({name, level}: LoggerConfig) { + this.config = {name, level}; + Object.freeze(this.config); + } + } + + const config: LoggerConfig = { + name: 'MyApp', + level: LogLevel.Debug + }; + + const logger = new Logger(config); + + // TypeScript Error: cannot assign to read-only property. + logger.config.level = LogLevel.Error; + + // We are able to edit config variable as we please. + config.level = LogLevel.Error; + ``` + </details> + +- [`Pick<T, K>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys) - From `T`, pick a set of properties whose keys are in the union `K`. + <details> + <summary> + Example + </summary> + + [Playground](https://typescript-play.js.org/?target=6#code/AQ4SwOwFwUwJwGYEMDGNgEE5TCgNugN4BQoZwOUBAXMAM5RyQDmA3KeSFABYCuAtgCMISMHloMmENh04oA9tBjQJjFuzIBfYrOAB6PcADCcGElh1gEGAHcKATwAO6ebyjB5CTNlwFwSxFR0BX5HeToYABNgBDh5fm8cfBg6AHIKG3ldA2BHOOcfFNpUygJ0pAhokr4hETFUgDpswywkggAFUwA3MFtgAF5gQgowKhhVKTYKGuFRcXo1aVZgbTIoJ3RW3xhOmB6+wfbcAGsAHi3kgBpgEtGy4AAfG54BWfqAPnZm4AAlZUj4MAkMA8GAGB4vEgfMlLLw6CwPBA8PYRmMgZVgAC6CgmI4cIommQELwICh8RBgKZKvALh1ur0bHQABR5PYMui0Wk7em2ADaAF0AJS0AASABUALIAGQAogR+Mp3CROCAFBBwVC2ikBpj5CgBIqGjizLA5TAFdAmalImAuqlBRoVQh5HBgEy1eDWfs7J5cjzGYKhroVfpDEhHM4MV6GRR5NN0JrtnRg6BVirTFBeHAKYmYY6QNpdB73LmCJZBlSAXAubtvczeSmQMNSuMbmKNgBlHFgPEUNwusBIPAAQlS1xetTmxT0SDoESgdD0C4aACtHMwxytLrohawgA) + + ```ts + interface Article { + title: string; + thumbnail: string; + content: string; + } + + // Creates new type out of the `Article` interface composed + // from the Articles' two properties: `title` and `thumbnail`. + // `ArticlePreview = {title: string; thumbnail: string}` + type ArticlePreview = Pick<Article, 'title' | 'thumbnail'>; + + // Render a list of articles using only title and description. + function renderArticlePreviews(previews: ArticlePreview[]): HTMLElement { + const articles = document.createElement('div'); + + for (const preview of previews) { + // Append preview to the articles. + } + + return articles; + } + + const articles = renderArticlePreviews([ + { + title: 'TypeScript tutorial!', + thumbnail: '/assets/ts.jpg' + } + ]); + ``` + </details> + +- [`Record<K, T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type) - Construct a type with a set of properties `K` of type `T`. + <details> + <summary> + Example + </summary> + + [Playground](https://typescript-play.js.org/?target=6#code/AQ4ejYAUHsGcCWAXBMB2dgwGbAKYC2ADgDYwCeeemCaWArgE7ADGMxAhmuQHQBQoYEnJE8wALKEARnkaxEKdMAC8wAOS0kstGuAAfdQBM8ANzxlRjXQbVaWACwC0JPB0NqA3HwGgIwAJJoWozYHCxixnAsjAhStADmwESMMJYo1Fi4HMCIaPEu+MRklHj8gpqyoeHAAKJFFFTAAN4+giDYCIxwSAByHAR4AFw5SDF5Xm2gJBzdfQPD3WPxE5PAlBxdAPLYNQAelgh4aOHDaPQEMowrIAC+3oJ+AMKMrlrAXFhSAFZ4LEhC9g4-0BmA4JBISXgiCkBQABpILrJ5MhUGhYcATGD6Bk4Hh-jNgABrPDkOBlXyQAAq9ngYmJpOAAHcEOCRjAXqwYODfoo6DhakUSph+Uh7GI4P0xER4Cj0OSQGwMP8tP1hgAlX7swwAHgRl2RvIANALSA08ABtAC6AD4VM1Wm0Kow0MMrYaHYJjGYLLJXZb3at1HYnC43Go-QHQDcvA6-JsmEJXARgCDgMYWAhjIYhDAU+YiMAAFIwex0ZmilMITCGF79TLAGRsAgJYAAZRwSEZGzEABFTOZUrJ5Yn+jwnWgeER6HB7AAKJrADpdXqS4ZqYultTG6azVfqHswPBbtauLY7fayQ7HIbAAAMwBuAEoYw9IBq2Ixs9h2eFMOQYPQObALQKJgggABeYhghCIpikkKRpOQRIknAsZUiIeCttECBEP8NSMCkjDDAARMGziuIYxHwYOjDCMBmDNnAuTxA6irdCOBB1Lh5Dqpqn66tISIykawBnOCtqqC0gbjqc9DgpGkxegOliyfJDrRkAA) + + ```ts + // Positions of employees in our company. + type MemberPosition = 'intern' | 'developer' | 'tech-lead'; + + // Interface describing properties of a single employee. + interface Employee { + firstName: string; + lastName: string; + yearsOfExperience: number; + } + + // Create an object that has all possible `MemberPosition` values set as keys. + // Those keys will store a collection of Employees of the same position. + const team: Record<MemberPosition, Employee[]> = { + intern: [], + developer: [], + 'tech-lead': [], + }; + + // Our team has decided to help John with his dream of becoming Software Developer. + team.intern.push({ + firstName: 'John', + lastName: 'Doe', + yearsOfExperience: 0 + }); + + // `Record` forces you to initialize all of the property keys. + // TypeScript Error: "tech-lead" property is missing + const teamEmpty: Record<MemberPosition, null> = { + intern: null, + developer: null, + }; + ``` + </details> + +- [`Exclude<T, U>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#excludetype-excludedunion) - Exclude from `T` those types that are assignable to `U`. + <details> + <summary> + Example + </summary> + + [Playground](https://typescript-play.js.org/?target=6#code/JYOwLgpgTgZghgYwgAgMrQG7QMIHsQzADmyA3gFDLIAOuUYAXMiAK4A2byAPsgM5hRQJHqwC2AI2gBucgF9y5MAE9qKAEoQAjiwj8AEnBAATNtGQBeZAAooWphu26wAGmS3e93bRC8IASgsAPmRDJRlyAHoI5ABRAA8ENhYjFFYOZGVVZBgoXFFkAAM0zh5+QRBhZhYJaAKAOkjogEkQZAQ4X2QAdwALCFbaemRgXmQtFjhOMFwq9K6ULuB0lk6U+HYwZAxJnQaYFhAEMGB8ZCIIMAAFOjAANR2IK0HGWISklIAedCgsKDwCYgAbQA5M9gQBdVzFQJ+JhiSRQMiUYYwayZCC4VHPCzmSzAspCYEBWxgFhQAZwKC+FpgJ43VwARgADH4ZFQSWSBjcZPJyPtDsdTvxKWBvr8rD1DCZoJ5HPopaYoK4EPhCEQmGKcKriLCtrhgEYkVQVT5Nr4fmZLLZtMBbFZgT0wGBqES6ghbHBIJqoBKFdBWQpjfh+DQbhY2tqiHVsbjLMVkAB+ZAAZiZaeQTHOVxu9ySjxNaujNwDVHNvzqbBGkBAdPoAfkQA) + + ```ts + interface ServerConfig { + port: null | string | number; + } + + type RequestHandler = (request: Request, response: Response) => void; + + // Exclude `null` type from `null | string | number`. + // In case the port is equal to `null`, we will use default value. + function getPortValue(port: Exclude<ServerConfig['port'], null>): number { + if (typeof port === 'string') { + return parseInt(port, 10); + } + + return port; + } + + function startServer(handler: RequestHandler, config: ServerConfig): void { + const server = require('http').createServer(handler); + + const port = config.port === null ? 3000 : getPortValue(config.port); + server.listen(port); + } + ``` + </details> + +- [`Extract<T, U>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union) - Extract from `T` those types that are assignable to `U`. + <details> + <summary> + Example + </summary> + + [Playground](https://typescript-play.js.org/?target=6#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXzSwEdkQBJYACgEoAueVZAWwCMQYBuAKDDwGcM8MgBF4AXngBlAJ6scESgHIRi6ty5ZUGdoihgEABXZ888AN5d48ANoiAuvUat23K6ihMQ9ATE0BzV3goPy8GZjZOLgBfLi4Aejj4AEEICBwAdz54MAALKFQQ+BxEeAAHY1NgKAwoIKy0grr4DByEUpgccpgMaXgAaxBerCzi+B9-ZulygDouFHRsU1z8kKMYE1RhaqgAHkt4AHkWACt4EAAPbVRgLLWNgBp9gGlBs8uQa6yAUUuYPQwdgNpKM7nh7mMML4CgA+R5WABqUAgpDeVxuhxO1he0jsXGh8EoOBO9COx3BQPo2PBADckaR6IjkSA6PBqTgsMBzPsicdrEC7OJWXSQNwYvFEgAVTS9JLXODpeDpKBZFg4GCoWa8VACIJykAKiQWKy2YQOAioYikCg0OEMDyhRSy4DyxS24KhAAMjyi6gS8AAwjh5OD0iBFHAkJoEOksC1mnkMJq8gUQKDNttKPlnfrwYp3J5XfBHXqoKpfYkAOI4ansTxaeDADmoRSCCBYAbxhC6TDx6rwYHIRX5bScjA4bLJwoDmDwDkfbA9JMrVMVdM1TN69LgkTgwgkchUahqIA) + + ```ts + declare function uniqueId(): number; + + const ID = Symbol('ID'); + + interface Person { + [ID]: number; + name: string; + age: number; + } + + // Allows changing the person data as long as the property key is of string type. + function changePersonData< + Obj extends Person, + Key extends Extract<keyof Person, string>, + Value extends Obj[Key] + > (obj: Obj, key: Key, value: Value): void { + obj[key] = value; + } + + // Tiny Andrew was born. + const andrew = { + [ID]: uniqueId(), + name: 'Andrew', + age: 0, + }; + + // Cool, we're fine with that. + changePersonData(andrew, 'name', 'Pony'); + + // Goverment didn't like the fact that you wanted to change your identity. + changePersonData(andrew, ID, uniqueId()); + ``` + </details> + +- [`NonNullable<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#nonnullabletype) - Exclude `null` and `undefined` from `T`. + <details> + <summary> + Example + </summary> + Works with <a href="https://www.typescriptlang.org/tsconfig#strictNullChecks"><code>strictNullChecks</code></a> set to <code>true</code>. + + [Playground](https://typescript-play.js.org/?target=6#code/C4TwDgpgBACg9gJ2AOQK4FsBGEFQLxQDOwCAlgHYDmUAPlORtrnQwDasDcAUFwPQBU-WAEMkUOADMowqAGNWwwoSgATCBIqlgpOOSjAAFsOBRSy1IQgr9cKJlSlW1mZYQA3HFH68u8xcoBlHA8EACEHJ08Aby4oKDBUTFZSWXjEFEYcAEIALihkXTR2YSSIAB54JDQsHAA+blj4xOTUsHSACkMzPKD3HHDHNQQAGjSkPMqMmoQASh7g-oihqBi4uNIpdraxPAI2VhmVxrX9AzMAOm2ppnwoAA4ABifuE4BfKAhWSyOTuK7CS7pao3AhXF5rV48E4ICDAVAIPT-cGQyG+XTEIgLMJLTx7CAAdygvRCA0iCHaMwarhJOIQjUBSHaACJHk8mYdeLwxtdcVAAOSsh58+lXdr7Dlcq7A3n3J4PEUdADMcspUE53OluAIUGVTx46oAKuAIAFZGQwCYAKIIBCILjUxaDHAMnla+iodjcIA) + + ```ts + type PortNumber = string | number | null; + + /** Part of a class definition that is used to build a server */ + class ServerBuilder { + portNumber!: NonNullable<PortNumber>; + + port(this: ServerBuilder, port: PortNumber): ServerBuilder { + if (port == null) { + this.portNumber = 8000; + } else { + this.portNumber = port; + } + + return this; + } + } + + const serverBuilder = new ServerBuilder(); + + serverBuilder + .port('8000') // portNumber = '8000' + .port(null) // portNumber = 8000 + .port(3000); // portNumber = 3000 + + // TypeScript error + serverBuilder.portNumber = null; + ``` + </details> + +- [`Parameters<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterstype) - Obtain the parameters of a function type in a tuple. + <details> + <summary> + Example + </summary> + + [Playground](https://typescript-play.js.org/?target=6#code/GYVwdgxgLglg9mABAZwBYmMANgUwBQxgAOIUAXIgIZgCeA2gLoCUFAbnDACaIDeAUIkQB6IYgCypSlBxUATrMo1ECsJzgBbLEoipqAc0J7EMKMgDkiHLnU4wp46pwAPHMgB0fAL58+oSLARECEosLAA5ABUYG2QAHgAxJGdpVWREPDdMylk9ZApqemZEAF4APipacrw-CApEgBogkKwAYThwckQwEHUAIxxZJl4BYVEImiIZKF0oZRwiWVdbeygJmThgOYgcGFYcbhqApCJsyhtpWXcR1cnEePBoeDAABVPzgbTixFeFd8uEsClADcIxGiygIFkSEOT3SmTc2VydQeRx+ZxwF2QQ34gkEwDgsnSuFmMBKiAADEDjIhYk1Qm0OlSYABqZnYka4xA1DJZHJYkGc7yCbyeRA+CAIZCzNAYbA4CIAdxg2zJwVCkWirjwMswuEaACYmCCgA) + + ```ts + function shuffle(input: any[]): void { + // Mutate array randomly changing its' elements indexes. + } + + function callNTimes<Fn extends (...arguments_: any[]) => any> (func: Fn, callCount: number) { + // Type that represents the type of the received function parameters. + type FunctionParameters = Parameters<Fn>; + + return function (...arguments_: FunctionParameters) { + for (let i = 0; i < callCount; i++) { + func(...arguments_); + } + } + } + + const shuffleTwice = callNTimes(shuffle, 2); + ``` + </details> + +- [`ConstructorParameters<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#constructorparameterstype) - Obtain the parameters of a constructor function type in a tuple. + <details> + <summary> + Example + </summary> + + [Playground](https://typescript-play.js.org/?target=6#code/MYGwhgzhAECCBOAXAlqApgWQPYBM0mgG8AoaaFRENALmgkXmQDsBzAblOmCycTV4D8teo1YdO3JiICuwRFngAKClWENmLAJRFOZRAAtkEAHQq00ALzlklNBzIBfYk+KhIMAJJTEYJsDQAwmDA+mgAPAAq0GgAHnxMODCKTGgA7tCKxllg8CwQtL4AngDaALraFgB80EWa1SRkAA6MAG5gfNAB4FABPDJyCrQR9tDNyG0dwMGhtBhgjWEiGgA00F70vv4RhY3hEZXVVinpc42KmuJkkv3y8Bly8EPaDWTkhiZd7r3e8LK3llwGCMXGQWGhEOsfH5zJlsrl8p0+gw-goAAo5MAAW3BaHgEEilU0tEhmzQ212BJ0ry4SOg+kg+gBBiMximIGA0nAfAQLGk2N4EAAEgzYcYcnkLsRdDTvNEYkYUKwSdCme9WdM0MYwYhFPSIPpJdTkAAzDKxBUaZX+aAAQgsVmkCTQxuYaBw2ng4Ok8CYcotSu8pMur09iG9vuObxZnx6SN+AyUWTF8MN0CcZE4Ywm5jZHK5aB5fP4iCFIqT4oRRTKRLo6lYVNeAHpG50wOzOe1zHr9NLQ+HoABybsD4HOKXXRA1JCoKhBELmI5pNaB6Fz0KKBAodDYPAgSUTmqYsAALx4m5nC6nW9nGq14KtaEUA9gR9PvuNCjQ9BgACNvcwNBtAcLiAA) + + ```ts + class ArticleModel { + title: string; + content?: string; + + constructor(title: string) { + this.title = title; + } + } + + class InstanceCache<T extends (new (...arguments_: any[]) => any)> { + private ClassConstructor: T; + private cache: Map<string, InstanceType<T>> = new Map(); + + constructor (ctr: T) { + this.ClassConstructor = ctr; + } + + getInstance (...arguments_: ConstructorParameters<T>): InstanceType<T> { + const hash = this.calculateArgumentsHash(...arguments_); + + const existingInstance = this.cache.get(hash); + if (existingInstance !== undefined) { + return existingInstance; + } + + return new this.ClassConstructor(...arguments_); + } + + private calculateArgumentsHash(...arguments_: any[]): string { + // Calculate hash. + return 'hash'; + } + } + + const articleCache = new InstanceCache(ArticleModel); + const amazonArticle = articleCache.getInstance('Amazon forests burining!'); + ``` + </details> + +- [`ReturnType<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype) - Obtain the return type of a function type. + <details> + <summary> + Example + </summary> + + [Playground](https://typescript-play.js.org/?target=6#code/MYGwhgzhAECSAmICmBlJAnAbgS2E6A3gFDTTwD2AcuQC4AW2AdgOYAUAlAFzSbnbyEAvkWFFQkGJSQB3GMVI1sNZNwg10TZgG4S0YOUY0kh1es07d+xmvQBXYDXLpWi5UlMaWAGj0GjJ6BtNdkJdBQYIADpXZGgAXmgYpB1ScOwoq38aeN9DYxoU6GFRKzVoJjUwRjwAYXJbPPRuAFkwAAcAHgAxBodsAx9GWwBbACMMAD4cxhloVraOCyYjdAAzMDxoOut1e0d0UNIZ6WhWSPOwdGYIbiqATwBtAF0uaHudUQB6ACpv6ABpJBINqJdAbADW0Do5BOw3u5R2VTwMHIq2gAANtjZ0bkbHsnFCwJh8ONjHp0EgwEZ4JFoN9PkRVr1FAZoMwkDRYIjqkgOrosepoEgAB7+eAwAV2BxOLy6ACCVxgIrFEoMeOl6AACpcwMMORgIB1JRMiBNWKVdhruJKfOdIpdrtwFddXlzKjyACp3Nq842HaDIbL6BrZBIVGhIpB1EMYSLsmjmtWW-YhAA+qegAAYLKQLQj3ZsEsdccmnGcLor2Dn8xGedHGpEIBzEzspfsfMHDNAANTQACMVaIljV5GQkRA5DYmIpVKQAgAJARO9le33BDXIyi0YuLW2nJFGLqkOvxFB0YPdBSaLZ0IwNzyPkO8-xkGgsLh8Al427a3hWAhXwwHA8EHT5PmgAB1bAQBAANJ24adKWpft72RaBUTgRBUCAj89HAM8xCTaBjggABRQx0DuHJv25P9dCkWRZVIAAiBjoFImpmjlFBgA0NpsjadByDacgIDAEAIAAQmYpjoGYgAZSBsmGPw6DtZiiFA8CoJguDmAQmoZ2QvtUKQLdoAYmBTwgdEiCAA) + + ```ts + /** Provides every element of the iterable `iter` into the `callback` function and stores the results in an array. */ + function mapIter< + Elem, + Func extends (elem: Elem) => any, + Ret extends ReturnType<Func> + >(iter: Iterable<Elem>, callback: Func): Ret[] { + const mapped: Ret[] = []; + + for (const elem of iter) { + mapped.push(callback(elem)); + } + + return mapped; + } + + const setObject: Set<string> = new Set(); + const mapObject: Map<number, string> = new Map(); + + mapIter(setObject, (value: string) => value.indexOf('Foo')); // number[] + + mapIter(mapObject, ([key, value]: [number, string]) => { + return key % 2 === 0 ? value : 'Odd'; + }); // string[] + ``` + </details> + +- [`InstanceType<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#instancetypetype) - Obtain the instance type of a constructor function type. + <details> + <summary> + Example + </summary> + + [Playground](https://typescript-play.js.org/?target=6#code/MYGwhgzhAECSAmICmBlJAnAbgS2E6A3gFDTTwD2AcuQC4AW2AdgOYAUAlAFzSbnbyEAvkWFFQkGJSQB3GMVI1sNZNwg10TZgG4S0YOUY0kh1es07d+xmvQBXYDXLpWi5UlMaWAGj0GjJ6BtNdkJdBQYIADpXZGgAXmgYpB1ScOwoq38aeN9DYxoU6GFRKzVoJjUwRjwAYXJbPPRuAFkwAAcAHgAxBodsAx9GWwBbACMMAD4cxhloVraOCyYjdAAzMDxoOut1e0d0UNIZ6WhWSPOwdGYIbiqATwBtAF0uaHudUQB6ACpv6ABpJBINqJdAbADW0Do5BOw3u5R2VTwMHIq2gAANtjZ0bkbHsnFCwJh8ONjHp0EgwEZ4JFoN9PkRVr1FAZoMwkDRYIjqkgOrosepoEgAB7+eAwAV2BxOLy6ACCVxgIrFEoMeOl6AACpcwMMORgIB1JRMiBNWKVdhruJKfOdIpdrtwFddXlzKjyACp3Nq842HaDIbL6BrZBIVGhIpB1EMYSLsmjmtWW-YhAA+qegAAYLKQLQj3ZsEsdccmnGcLor2Dn8xGedHGpEIBzEzspfsfMHDNAANTQACMVaIljV5GQkRA5DYmIpVKQAgAJARO9le33BDXIyi0YuLW2nJFGLqkOvxFB0YPdBSaLZ0IwNzyPkO8-xkGgsLh8Al427a3hWAhXwwHA8EHT5PmgAB1bAQBAANJ24adKWpft72RaBUTgRBUCAj89HAM8xCTaBjggABRQx0DuHJv25P9dCkWRZVIAAiBjoFImpmjlFBgA0NpsjadByDacgIDAEAIAAQmYpjoGYgAZSBsmGPw6DtZiiFA8CoJguDmAQmoZ2QvtUKQLdoAYmBTwgdEiCAA) + + ```ts + class IdleService { + doNothing (): void {} + } + + class News { + title: string; + content: string; + + constructor(title: string, content: string) { + this.title = title; + this.content = content; + } + } + + const instanceCounter: Map<Function, number> = new Map(); + + interface Constructor { + new(...arguments_: any[]): any; + } + + // Keep track how many instances of `Constr` constructor have been created. + function getInstance< + Constr extends Constructor, + Arguments extends ConstructorParameters<Constr> + >(constructor: Constr, ...arguments_: Arguments): InstanceType<Constr> { + let count = instanceCounter.get(constructor) || 0; + + const instance = new constructor(...arguments_); + + instanceCounter.set(constructor, count + 1); + + console.log(`Created ${count + 1} instances of ${Constr.name} class`); + + return instance; + } + + + const idleService = getInstance(IdleService); + // Will log: `Created 1 instances of IdleService class` + const newsEntry = getInstance(News, 'New ECMAScript proposals!', 'Last month...'); + // Will log: `Created 1 instances of News class` + ``` + </details> + +- [`Omit<T, K>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys) - Constructs a type by picking all properties from T and then removing K. + <details> + <summary> + Example + </summary> + + [Playground](https://typescript-play.js.org/?target=6#code/JYOwLgpgTgZghgYwgAgIImAWzgG2QbwChlks4BzCAVShwC5kBnMKUcgbmKYAcIFgIjBs1YgOXMpSFMWbANoBdTiW5woFddwAW0kfKWEAvoUIB6U8gDCUCHEiNkICAHdkYAJ69kz4GC3JcPG4oAHteKDABBxCYNAxsPFBIWEQUCAAPJG4wZABySUFcgJAAEzMLXNV1ck0dIuCw6EjBADpy5AB1FAQ4EGQAV0YUP2AHDy8wEOQbUugmBLwtEIA3OcmQnEjuZBgQqE7gAGtgZAhwKHdkHFGwNvGUdDIcAGUliIBJEF3kAF5kAHlML4ADyPBIAGjyBUYRQAPnkqho4NoYQA+TiEGD9EAISIhPozErQMG4AASK2gn2+AApek9pCSXm8wFSQooAJQMUkAFQAsgAZACiOAgmDOOSIJAQ+OYyGl4DgoDmf2QJRCCH6YvALQQNjsEGFovF1NyJWAy1y7OUyHMyE+yRAuFImG4Iq1YDswHxbRINjA-SgfXlHqVUE4xiAA) + + ```ts + interface Animal { + imageUrl: string; + species: string; + images: string[]; + paragraphs: string[]; + } + + // Creates new type with all properties of the `Animal` interface + // except 'images' and 'paragraphs' properties. We can use this + // type to render small hover tooltip for a wiki entry list. + type AnimalShortInfo = Omit<Animal, 'images' | 'paragraphs'>; + + function renderAnimalHoverInfo (animals: AnimalShortInfo[]): HTMLElement { + const container = document.createElement('div'); + // Internal implementation. + return container; + } + ``` + </details> + +- [`Uppercase<S extends string>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#uppercasestringtype) - Transforms every character in a string into uppercase. + <details> + <summary> + Example + </summary> + + ```ts + type T = Uppercase<'hello'>; // 'HELLO' + + type T2 = Uppercase<'foo' | 'bar'>; // 'FOO' | 'BAR' + + type T3<S extends string> = Uppercase<`aB${S}`>; + type T4 = T3<'xYz'>; // 'ABXYZ' + + type T5 = Uppercase<string>; // string + type T6 = Uppercase<any>; // any + type T7 = Uppercase<never>; // never + type T8 = Uppercase<42>; // Error, type 'number' does not satisfy the constraint 'string' + ``` + </details> + +- [`Lowercase<S extends string>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#lowercasestringtype) - Transforms every character in a string into lowercase. + <details> + <summary> + Example + </summary> + + ```ts + type T = Lowercase<'HELLO'>; // 'hello' + + type T2 = Lowercase<'FOO' | 'BAR'>; // 'foo' | 'bar' + + type T3<S extends string> = Lowercase<`aB${S}`>; + type T4 = T3<'xYz'>; // 'abxyz' + + type T5 = Lowercase<string>; // string + type T6 = Lowercase<any>; // any + type T7 = Lowercase<never>; // never + type T8 = Lowercase<42>; // Error, type 'number' does not satisfy the constraint 'string' + ``` + </details> + +- [`Capitalize<S extends string>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#capitalizestringtype) - Transforms the first character in a string into uppercase. + <details> + <summary> + Example + </summary> + + ```ts + type T = Capitalize<'hello'>; // 'Hello' + + type T2 = Capitalize<'foo' | 'bar'>; // 'Foo' | 'Bar' + + type T3<S extends string> = Capitalize<`aB${S}`>; + type T4 = T3<'xYz'>; // 'ABxYz' + + type T5 = Capitalize<string>; // string + type T6 = Capitalize<any>; // any + type T7 = Capitalize<never>; // never + type T8 = Capitalize<42>; // Error, type 'number' does not satisfy the constraint 'string' + ``` + </details> + +- [`Uncapitalize<S extends string>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#uncapitalizestringtype) - Transforms the first character in a string into lowercase. + <details> + <summary> + Example + </summary> + + ```ts + type T = Uncapitalize<'Hello'>; // 'hello' + + type T2 = Uncapitalize<'Foo' | 'Bar'>; // 'foo' | 'bar' + + type T3<S extends string> = Uncapitalize<`AB${S}`>; + type T4 = T3<'xYz'>; // 'aBxYz' + + type T5 = Uncapitalize<string>; // string + type T6 = Uncapitalize<any>; // any + type T7 = Uncapitalize<never>; // never + type T8 = Uncapitalize<42>; // Error, type 'number' does not satisfy the constraint 'string' + ``` + </details> + +You can find some examples in the [TypeScript docs](https://www.typescriptlang.org/docs/handbook/utility-types.html). + +## Maintainers + +- [Sindre Sorhus](https://github.com/sindresorhus) +- [Jarek Radosz](https://github.com/CvX) +- [Dimitri Benin](https://github.com/BendingBender) +- [Pelle Wessman](https://github.com/voxpelli) +- [Sébastien Mischler](https://github.com/skarab42) + +## License + +SPDX-License-Identifier: (MIT OR CC0-1.0) diff --git a/node_modules/type-fest/source/async-return-type.d.ts b/node_modules/type-fest/source/async-return-type.d.ts new file mode 100644 index 0000000..5d9f89c --- /dev/null +++ b/node_modules/type-fest/source/async-return-type.d.ts @@ -0,0 +1,23 @@ +type AsyncFunction = (...arguments_: any[]) => Promise<unknown>; + +/** +Unwrap the return type of a function that returns a `Promise`. + +There has been [discussion](https://github.com/microsoft/TypeScript/pull/35998) about implementing this type in TypeScript. + +@example +```ts +import type {AsyncReturnType} from 'type-fest'; +import {asyncFunction} from 'api'; + +// This type resolves to the unwrapped return type of `asyncFunction`. +type Value = AsyncReturnType<typeof asyncFunction>; + +async function doSomething(value: Value) {} + +asyncFunction().then(value => doSomething(value)); +``` + +@category Async +*/ +export type AsyncReturnType<Target extends AsyncFunction> = Awaited<ReturnType<Target>>; diff --git a/node_modules/type-fest/source/asyncify.d.ts b/node_modules/type-fest/source/asyncify.d.ts new file mode 100644 index 0000000..df3c31d --- /dev/null +++ b/node_modules/type-fest/source/asyncify.d.ts @@ -0,0 +1,32 @@ +import type {SetReturnType} from './set-return-type'; + +/** +Create an async version of the given function type, by boxing the return type in `Promise` while keeping the same parameter types. + +Use-case: You have two functions, one synchronous and one asynchronous that do the same thing. Instead of having to duplicate the type definition, you can use `Asyncify` to reuse the synchronous type. + +@example +``` +import type {Asyncify} from 'type-fest'; + +// Synchronous function. +function getFooSync(someArg: SomeType): Foo { + // … +} + +type AsyncifiedFooGetter = Asyncify<typeof getFooSync>; +//=> type AsyncifiedFooGetter = (someArg: SomeType) => Promise<Foo>; + +// Same as `getFooSync` but asynchronous. +const getFooAsync: AsyncifiedFooGetter = (someArg) => { + // TypeScript now knows that `someArg` is `SomeType` automatically. + // It also knows that this function must return `Promise<Foo>`. + // If you have `@typescript-eslint/promise-function-async` linter rule enabled, it will even report that "Functions that return promises must be async.". + + // … +} +``` + +@category Async +*/ +export type Asyncify<Fn extends (...arguments_: any[]) => any> = SetReturnType<Fn, Promise<Awaited<ReturnType<Fn>>>>; diff --git a/node_modules/type-fest/source/basic.d.ts b/node_modules/type-fest/source/basic.d.ts new file mode 100644 index 0000000..d4d8f98 --- /dev/null +++ b/node_modules/type-fest/source/basic.d.ts @@ -0,0 +1,68 @@ +/** +Matches a [`class`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). + +@category Class +*/ +export type Class<T, Arguments extends unknown[] = any[]> = { + prototype: T; + new(...arguments_: Arguments): T; +}; + +/** +Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). + +@category Class +*/ +export type Constructor<T, Arguments extends unknown[] = any[]> = new(...arguments_: Arguments) => T; + +/** +Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/classes.html#abstract-classes). + +@category Class + +@privateRemarks +We cannot use a `type` here because TypeScript throws: 'abstract' modifier cannot appear on a type member. (1070) +*/ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +export interface AbstractClass<T, Arguments extends unknown[] = any[]> extends AbstractConstructor<T, Arguments> { + prototype: T; +} + +/** +Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-2.html#abstract-construct-signatures) constructor. + +@category Class +*/ +export type AbstractConstructor<T, Arguments extends unknown[] = any[]> = abstract new(...arguments_: Arguments) => T; + +/** +Matches a JSON object. + +This type can be useful to enforce some input to be JSON-compatible or as a super-type to be extended from. Don't use this as a direct return type as the user would have to double-cast it: `jsonObject as unknown as CustomResponse`. Instead, you could extend your CustomResponse type from it to ensure your type only uses JSON-compatible types: `interface CustomResponse extends JsonObject { … }`. + +@category JSON +*/ +export type JsonObject = {[Key in string]: JsonValue} & {[Key in string]?: JsonValue | undefined}; + +/** +Matches a JSON array. + +@category JSON +*/ +export type JsonArray = JsonValue[] | readonly JsonValue[]; + +/** +Matches any valid JSON primitive value. + +@category JSON +*/ +export type JsonPrimitive = string | number | boolean | null; + +/** +Matches any valid JSON value. + +@see `Jsonify` if you need to transform a type to one that is assignable to `JsonValue`. + +@category JSON +*/ +export type JsonValue = JsonPrimitive | JsonObject | JsonArray; diff --git a/node_modules/type-fest/source/camel-case.d.ts b/node_modules/type-fest/source/camel-case.d.ts new file mode 100644 index 0000000..7672286 --- /dev/null +++ b/node_modules/type-fest/source/camel-case.d.ts @@ -0,0 +1,80 @@ +import type {SplitWords} from './split-words'; + +/** +CamelCase options. + +@see {@link CamelCase} +*/ +export type CamelCaseOptions = { + /** + Whether to preserved consecutive uppercase letter. + + @default true + */ + preserveConsecutiveUppercase?: boolean; +}; + +/** +Convert an array of words to camel-case. +*/ +type CamelCaseFromArray< + Words extends string[], + Options extends CamelCaseOptions, + OutputString extends string = '', +> = Words extends [ + infer FirstWord extends string, + ...infer RemainingWords extends string[], +] + ? Options['preserveConsecutiveUppercase'] extends true + ? `${Capitalize<FirstWord>}${CamelCaseFromArray<RemainingWords, Options>}` + : `${Capitalize<Lowercase<FirstWord>>}${CamelCaseFromArray<RemainingWords, Options>}` + : OutputString; + +/** +Convert a string literal to camel-case. + +This can be useful when, for example, converting some kebab-cased command-line flags or a snake-cased database result. + +By default, consecutive uppercase letter are preserved. See {@link CamelCaseOptions.preserveConsecutiveUppercase preserveConsecutiveUppercase} option to change this behaviour. + +@example +``` +import type {CamelCase} from 'type-fest'; + +// Simple + +const someVariable: CamelCase<'foo-bar'> = 'fooBar'; + +// Advanced + +type CamelCasedProperties<T> = { + [K in keyof T as CamelCase<K>]: T[K] +}; + +interface RawOptions { + 'dry-run': boolean; + 'full_family_name': string; + foo: number; + BAR: string; + QUZ_QUX: number; + 'OTHER-FIELD': boolean; +} + +const dbResult: CamelCasedProperties<RawOptions> = { + dryRun: true, + fullFamilyName: 'bar.js', + foo: 123, + bar: 'foo', + quzQux: 6, + otherField: false +}; +``` + +@category Change case +@category Template literal +*/ +export type CamelCase<Type, Options extends CamelCaseOptions = {preserveConsecutiveUppercase: true}> = Type extends string + ? string extends Type + ? Type + : Uncapitalize<CamelCaseFromArray<SplitWords<Type extends Uppercase<Type> ? Lowercase<Type> : Type>, Options>> + : Type; diff --git a/node_modules/type-fest/source/camel-cased-properties-deep.d.ts b/node_modules/type-fest/source/camel-cased-properties-deep.d.ts new file mode 100644 index 0000000..b44482b --- /dev/null +++ b/node_modules/type-fest/source/camel-cased-properties-deep.d.ts @@ -0,0 +1,54 @@ +import type {CamelCase, CamelCaseOptions} from './camel-case'; + +/** +Convert object properties to camel case recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see CamelCasedProperties +@see CamelCase + +@example +``` +import type {CamelCasedPropertiesDeep} from 'type-fest'; + +interface User { + UserId: number; + UserName: string; +} + +interface UserWithFriends { + UserInfo: User; + UserFriends: User[]; +} + +const result: CamelCasedPropertiesDeep<UserWithFriends> = { + userInfo: { + userId: 1, + userName: 'Tom', + }, + userFriends: [ + { + userId: 2, + userName: 'Jerry', + }, + { + userId: 3, + userName: 'Spike', + }, + ], +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type CamelCasedPropertiesDeep<Value, Options extends CamelCaseOptions = {preserveConsecutiveUppercase: true}> = Value extends Function + ? Value + : Value extends Array<infer U> + ? Array<CamelCasedPropertiesDeep<U, Options>> + : Value extends Set<infer U> + ? Set<CamelCasedPropertiesDeep<U, Options>> : { + [K in keyof Value as CamelCase<K, Options>]: CamelCasedPropertiesDeep<Value[K], Options>; + }; diff --git a/node_modules/type-fest/source/camel-cased-properties.d.ts b/node_modules/type-fest/source/camel-cased-properties.d.ts new file mode 100644 index 0000000..99e1481 --- /dev/null +++ b/node_modules/type-fest/source/camel-cased-properties.d.ts @@ -0,0 +1,36 @@ +import type {CamelCase, CamelCaseOptions} from './camel-case'; + +/** +Convert object properties to camel case but not recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see CamelCasedPropertiesDeep +@see CamelCase + +@example +``` +import type {CamelCasedProperties} from 'type-fest'; + +interface User { + UserId: number; + UserName: string; +} + +const result: CamelCasedProperties<User> = { + userId: 1, + userName: 'Tom', +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type CamelCasedProperties<Value, Options extends CamelCaseOptions = {preserveConsecutiveUppercase: true}> = Value extends Function + ? Value + : Value extends Array<infer U> + ? Value + : { + [K in keyof Value as CamelCase<K, Options>]: Value[K]; + }; diff --git a/node_modules/type-fest/source/conditional-except.d.ts b/node_modules/type-fest/source/conditional-except.d.ts new file mode 100644 index 0000000..9b40b34 --- /dev/null +++ b/node_modules/type-fest/source/conditional-except.d.ts @@ -0,0 +1,45 @@ +import type {Except} from './except'; +import type {ConditionalKeys} from './conditional-keys'; + +/** +Exclude keys from a shape that matches the given `Condition`. + +This is useful when you want to create a new type with a specific set of keys from a shape. For example, you might want to exclude all the primitive properties from a class and form a new shape containing everything but the primitive properties. + +@example +``` +import type {Primitive, ConditionalExcept} from 'type-fest'; + +class Awesome { + name: string; + successes: number; + failures: bigint; + + run() {} +} + +type ExceptPrimitivesFromAwesome = ConditionalExcept<Awesome, Primitive>; +//=> {run: () => void} +``` + +@example +``` +import type {ConditionalExcept} from 'type-fest'; + +interface Example { + a: string; + b: string | number; + c: () => void; + d: {}; +} + +type NonStringKeysOnly = ConditionalExcept<Example, string>; +//=> {b: string | number; c: () => void; d: {}} +``` + +@category Object +*/ +export type ConditionalExcept<Base, Condition> = Except< +Base, +ConditionalKeys<Base, Condition> +>; diff --git a/node_modules/type-fest/source/conditional-keys.d.ts b/node_modules/type-fest/source/conditional-keys.d.ts new file mode 100644 index 0000000..64b9593 --- /dev/null +++ b/node_modules/type-fest/source/conditional-keys.d.ts @@ -0,0 +1,47 @@ +/** +Extract the keys from a type where the value type of the key extends the given `Condition`. + +Internally this is used for the `ConditionalPick` and `ConditionalExcept` types. + +@example +``` +import type {ConditionalKeys} from 'type-fest'; + +interface Example { + a: string; + b: string | number; + c?: string; + d: {}; +} + +type StringKeysOnly = ConditionalKeys<Example, string>; +//=> 'a' +``` + +To support partial types, make sure your `Condition` is a union of undefined (for example, `string | undefined`) as demonstrated below. + +@example +``` +import type {ConditionalKeys} from 'type-fest'; + +type StringKeysAndUndefined = ConditionalKeys<Example, string | undefined>; +//=> 'a' | 'c' +``` + +@category Object +*/ +export type ConditionalKeys<Base, Condition> = NonNullable< +// Wrap in `NonNullable` to strip away the `undefined` type from the produced union. +{ + // Map through all the keys of the given base type. + [Key in keyof Base]: + // Pick only keys with types extending the given `Condition` type. + Base[Key] extends Condition + // Retain this key since the condition passes. + ? Key + // Discard this key since the condition fails. + : never; + + // Convert the produced object into a union type of the keys which passed the conditional test. +}[keyof Base] +>; diff --git a/node_modules/type-fest/source/conditional-pick-deep.d.ts b/node_modules/type-fest/source/conditional-pick-deep.d.ts new file mode 100644 index 0000000..30d09e7 --- /dev/null +++ b/node_modules/type-fest/source/conditional-pick-deep.d.ts @@ -0,0 +1,102 @@ +import type {Opaque} from './opaque'; +import type {IsEqual} from './is-equal'; +import type {ConditionalExcept} from './conditional-except'; +import type {ConditionalSimplifyDeep} from './conditional-simplify'; + +/** +Used to mark properties that should be excluded. +*/ +type ConditionalPickDeepSymbol = Opaque<symbol, 'conditional-pick-deep-symbol'>; + +/** +Assert the condition according to the {@link ConditionalPickDeepOptions.condition|condition} option. +*/ +type AssertCondition<Type, Condition, Options extends ConditionalPickDeepOptions> = Options['condition'] extends 'equality' + ? IsEqual<Type, Condition> + : Type extends Condition + ? true + : false; + +/** +ConditionalPickDeep options. + +@see ConditionalPickDeep +*/ +export type ConditionalPickDeepOptions = { + /** + The condition assertion mode. + + @default 'extends' + */ + condition?: 'extends' | 'equality'; +}; + +/** +Pick keys recursively from the shape that matches the given condition. + +@see ConditionalPick + +@example +``` +import type {ConditionalPickDeep} from 'type-fest'; + +interface Example { + a: string; + b: string | boolean; + c: { + d: string; + e: { + f?: string; + g?: boolean; + h: string | boolean; + i: boolean | bigint; + }; + j: boolean; + }; +} + +type StringPick = ConditionalPickDeep<Example, string>; +//=> {a: string; c: {d: string}} + +type StringPickOptional = ConditionalPickDeep<Example, string | undefined>; +//=> {a: string; c: {d: string; e: {f?: string}}} + +type StringPickOptionalOnly = ConditionalPickDeep<Example, string | undefined, {condition: 'equality'}>; +//=> {c: {e: {f?: string}}} + +type BooleanPick = ConditionalPickDeep<Example, boolean | undefined>; +//=> {c: {e: {g?: boolean}; j: boolean}} + +type NumberPick = ConditionalPickDeep<Example, number>; +//=> {} + +type StringOrBooleanPick = ConditionalPickDeep<Example, string | boolean>; +//=> { +// a: string; +// b: string | boolean; +// c: { +// d: string; +// e: { +// h: string | boolean +// }; +// j: boolean; +// }; +// } + +type StringOrBooleanPickOnly = ConditionalPickDeep<Example, string | boolean, {condition: 'equality'}>; +//=> {b: string | boolean; c: {e: {h: string | boolean}}} +``` + +@category Object +*/ +export type ConditionalPickDeep< + Type, + Condition, + Options extends ConditionalPickDeepOptions = {}, +> = ConditionalSimplifyDeep<ConditionalExcept<{ + [Key in keyof Type]: AssertCondition<Type[Key], Condition, Options> extends true + ? Type[Key] + : Type[Key] extends object + ? ConditionalPickDeep<Type[Key], Condition, Options> + : ConditionalPickDeepSymbol; +}, (ConditionalPickDeepSymbol | undefined) | Record<PropertyKey, never>>>; diff --git a/node_modules/type-fest/source/conditional-pick.d.ts b/node_modules/type-fest/source/conditional-pick.d.ts new file mode 100644 index 0000000..2a24cb2 --- /dev/null +++ b/node_modules/type-fest/source/conditional-pick.d.ts @@ -0,0 +1,44 @@ +import type {ConditionalKeys} from './conditional-keys'; + +/** +Pick keys from the shape that matches the given `Condition`. + +This is useful when you want to create a new type from a specific subset of an existing type. For example, you might want to pick all the primitive properties from a class and form a new automatically derived type. + +@example +``` +import type {Primitive, ConditionalPick} from 'type-fest'; + +class Awesome { + name: string; + successes: number; + failures: bigint; + + run() {} +} + +type PickPrimitivesFromAwesome = ConditionalPick<Awesome, Primitive>; +//=> {name: string; successes: number; failures: bigint} +``` + +@example +``` +import type {ConditionalPick} from 'type-fest'; + +interface Example { + a: string; + b: string | number; + c: () => void; + d: {}; +} + +type StringKeysOnly = ConditionalPick<Example, string>; +//=> {a: string} +``` + +@category Object +*/ +export type ConditionalPick<Base, Condition> = Pick< +Base, +ConditionalKeys<Base, Condition> +>; diff --git a/node_modules/type-fest/source/conditional-simplify.d.ts b/node_modules/type-fest/source/conditional-simplify.d.ts new file mode 100644 index 0000000..03cd506 --- /dev/null +++ b/node_modules/type-fest/source/conditional-simplify.d.ts @@ -0,0 +1,32 @@ +/** +Simplifies a type while including and/or excluding certain types from being simplified. Useful to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability. + +This type is **experimental** and was introduced as a result of this {@link https://github.com/sindresorhus/type-fest/issues/436 issue}. It should be used with caution. + +@internal +@experimental +@see Simplify +@category Object +*/ +export type ConditionalSimplify<Type, ExcludeType = never, IncludeType = unknown> = Type extends ExcludeType + ? Type + : Type extends IncludeType + ? {[TypeKey in keyof Type]: Type[TypeKey]} + : Type; + +/** +Recursively simplifies a type while including and/or excluding certain types from being simplified. + +This type is **experimental** and was introduced as a result of this {@link https://github.com/sindresorhus/type-fest/issues/436 issue}. It should be used with caution. + +See {@link ConditionalSimplify} for usages and examples. + +@internal +@experimental +@category Object +*/ +export type ConditionalSimplifyDeep<Type, ExcludeType = never, IncludeType = unknown> = Type extends ExcludeType + ? Type + : Type extends IncludeType + ? {[TypeKey in keyof Type]: ConditionalSimplifyDeep<Type[TypeKey], ExcludeType, IncludeType>} + : Type; diff --git a/node_modules/type-fest/source/delimiter-case.d.ts b/node_modules/type-fest/source/delimiter-case.d.ts new file mode 100644 index 0000000..9a237b7 --- /dev/null +++ b/node_modules/type-fest/source/delimiter-case.d.ts @@ -0,0 +1,99 @@ +import type {UpperCaseCharacters, WordSeparators} from '../source/internal'; + +// Transforms a string that is fully uppercase into a fully lowercase version. Needed to add support for SCREAMING_SNAKE_CASE, see https://github.com/sindresorhus/type-fest/issues/385 +type UpperCaseToLowerCase<T extends string> = T extends Uppercase<T> ? Lowercase<T> : T; + +// This implementation does not support SCREAMING_SNAKE_CASE, it is used internally by `SplitIncludingDelimiters`. +type SplitIncludingDelimiters_<Source extends string, Delimiter extends string> = + Source extends '' ? [] : + Source extends `${infer FirstPart}${Delimiter}${infer SecondPart}` ? + ( + Source extends `${FirstPart}${infer UsedDelimiter}${SecondPart}` + ? UsedDelimiter extends Delimiter + ? Source extends `${infer FirstPart}${UsedDelimiter}${infer SecondPart}` + ? [...SplitIncludingDelimiters<FirstPart, Delimiter>, UsedDelimiter, ...SplitIncludingDelimiters<SecondPart, Delimiter>] + : never + : never + : never + ) : + [Source]; + +/** +Unlike a simpler split, this one includes the delimiter splitted on in the resulting array literal. This is to enable splitting on, for example, upper-case characters. + +@category Template literal +*/ +export type SplitIncludingDelimiters<Source extends string, Delimiter extends string> = SplitIncludingDelimiters_<UpperCaseToLowerCase<Source>, Delimiter>; + +/** +Format a specific part of the splitted string literal that `StringArrayToDelimiterCase<>` fuses together, ensuring desired casing. + +@see StringArrayToDelimiterCase +*/ +type StringPartToDelimiterCase<StringPart extends string, Start extends boolean, UsedWordSeparators extends string, UsedUpperCaseCharacters extends string, Delimiter extends string> = + StringPart extends UsedWordSeparators ? Delimiter : + Start extends true ? Lowercase<StringPart> : + StringPart extends UsedUpperCaseCharacters ? `${Delimiter}${Lowercase<StringPart>}` : + StringPart; + +/** +Takes the result of a splitted string literal and recursively concatenates it together into the desired casing. + +It receives `UsedWordSeparators` and `UsedUpperCaseCharacters` as input to ensure it's fully encapsulated. + +@see SplitIncludingDelimiters +*/ +type StringArrayToDelimiterCase<Parts extends readonly any[], Start extends boolean, UsedWordSeparators extends string, UsedUpperCaseCharacters extends string, Delimiter extends string> = + Parts extends [`${infer FirstPart}`, ...infer RemainingParts] + ? `${StringPartToDelimiterCase<FirstPart, Start, UsedWordSeparators, UsedUpperCaseCharacters, Delimiter>}${StringArrayToDelimiterCase<RemainingParts, false, UsedWordSeparators, UsedUpperCaseCharacters, Delimiter>}` + : Parts extends [string] + ? string + : ''; + +/** +Convert a string literal to a custom string delimiter casing. + +This can be useful when, for example, converting a camel-cased object property to an oddly cased one. + +@see KebabCase +@see SnakeCase + +@example +``` +import type {DelimiterCase} from 'type-fest'; + +// Simple + +const someVariable: DelimiterCase<'fooBar', '#'> = 'foo#bar'; + +// Advanced + +type OddlyCasedProperties<T> = { + [K in keyof T as DelimiterCase<K, '#'>]: T[K] +}; + +interface SomeOptions { + dryRun: boolean; + includeFile: string; + foo: number; +} + +const rawCliOptions: OddlyCasedProperties<SomeOptions> = { + 'dry#run': true, + 'include#file': 'bar.js', + foo: 123 +}; +``` + +@category Change case +@category Template literal +*/ +export type DelimiterCase<Value, Delimiter extends string> = string extends Value ? Value : Value extends string + ? StringArrayToDelimiterCase< + SplitIncludingDelimiters<Value, WordSeparators | UpperCaseCharacters>, + true, + WordSeparators, + UpperCaseCharacters, + Delimiter + > + : Value; diff --git a/node_modules/type-fest/source/delimiter-cased-properties-deep.d.ts b/node_modules/type-fest/source/delimiter-cased-properties-deep.d.ts new file mode 100644 index 0000000..82299c0 --- /dev/null +++ b/node_modules/type-fest/source/delimiter-cased-properties-deep.d.ts @@ -0,0 +1,60 @@ +import type {DelimiterCase} from './delimiter-case'; + +/** +Convert object properties to delimiter case recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see DelimiterCase +@see DelimiterCasedProperties + +@example +``` +import type {DelimiterCasedPropertiesDeep} from 'type-fest'; + +interface User { + userId: number; + userName: string; +} + +interface UserWithFriends { + userInfo: User; + userFriends: User[]; +} + +const result: DelimiterCasedPropertiesDeep<UserWithFriends, '-'> = { + 'user-info': { + 'user-id': 1, + 'user-name': 'Tom', + }, + 'user-friends': [ + { + 'user-id': 2, + 'user-name': 'Jerry', + }, + { + 'user-id': 3, + 'user-name': 'Spike', + }, + ], +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type DelimiterCasedPropertiesDeep< + Value, + Delimiter extends string, +> = Value extends Function | Date | RegExp + ? Value + : Value extends Array<infer U> + ? Array<DelimiterCasedPropertiesDeep<U, Delimiter>> + : Value extends Set<infer U> + ? Set<DelimiterCasedPropertiesDeep<U, Delimiter>> : { + [K in keyof Value as DelimiterCase< + K, + Delimiter + >]: DelimiterCasedPropertiesDeep<Value[K], Delimiter>; + }; diff --git a/node_modules/type-fest/source/delimiter-cased-properties.d.ts b/node_modules/type-fest/source/delimiter-cased-properties.d.ts new file mode 100644 index 0000000..c73e07f --- /dev/null +++ b/node_modules/type-fest/source/delimiter-cased-properties.d.ts @@ -0,0 +1,37 @@ +import type {DelimiterCase} from './delimiter-case'; + +/** +Convert object properties to delimiter case but not recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see DelimiterCase +@see DelimiterCasedPropertiesDeep + +@example +``` +import type {DelimiterCasedProperties} from 'type-fest'; + +interface User { + userId: number; + userName: string; +} + +const result: DelimiterCasedProperties<User, '-'> = { + 'user-id': 1, + 'user-name': 'Tom', +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type DelimiterCasedProperties< + Value, + Delimiter extends string, +> = Value extends Function + ? Value + : Value extends Array<infer U> + ? Value + : {[K in keyof Value as DelimiterCase<K, Delimiter>]: Value[K]}; diff --git a/node_modules/type-fest/source/empty-object.d.ts b/node_modules/type-fest/source/empty-object.d.ts new file mode 100644 index 0000000..ee79118 --- /dev/null +++ b/node_modules/type-fest/source/empty-object.d.ts @@ -0,0 +1,46 @@ +declare const emptyObjectSymbol: unique symbol; + +/** +Represents a strictly empty plain object, the `{}` value. + +When you annotate something as the type `{}`, it can be anything except `null` and `undefined`. This means that you cannot use `{}` to represent an empty plain object ([read more](https://stackoverflow.com/questions/47339869/typescript-empty-object-and-any-difference/52193484#52193484)). + +@example +``` +import type {EmptyObject} from 'type-fest'; + +// The following illustrates the problem with `{}`. +const foo1: {} = {}; // Pass +const foo2: {} = []; // Pass +const foo3: {} = 42; // Pass +const foo4: {} = {a: 1}; // Pass + +// With `EmptyObject` only the first case is valid. +const bar1: EmptyObject = {}; // Pass +const bar2: EmptyObject = 42; // Fail +const bar3: EmptyObject = []; // Fail +const bar4: EmptyObject = {a: 1}; // Fail +``` + +Unfortunately, `Record<string, never>`, `Record<keyof any, never>` and `Record<never, never>` do not work. See {@link https://github.com/sindresorhus/type-fest/issues/395 #395}. + +@category Object +*/ +export type EmptyObject = {[emptyObjectSymbol]?: never}; + +/** +Returns a `boolean` for whether the type is strictly equal to an empty plain object, the `{}` value. + +@example +``` +import type {IsEmptyObject} from 'type-fest'; + +type Pass = IsEmptyObject<{}>; //=> true +type Fail = IsEmptyObject<[]>; //=> false +type Fail = IsEmptyObject<null>; //=> false +``` + +@see EmptyObject +@category Object +*/ +export type IsEmptyObject<T> = T extends EmptyObject ? true : false; diff --git a/node_modules/type-fest/source/enforce-optional.d.ts b/node_modules/type-fest/source/enforce-optional.d.ts new file mode 100644 index 0000000..8b4a9b5 --- /dev/null +++ b/node_modules/type-fest/source/enforce-optional.d.ts @@ -0,0 +1,47 @@ +import type {Simplify} from './simplify'; + +// Returns `never` if the key is optional otherwise return the key type. +type RequiredFilter<Type, Key extends keyof Type> = undefined extends Type[Key] + ? Type[Key] extends undefined + ? Key + : never + : Key; + +// Returns `never` if the key is required otherwise return the key type. +type OptionalFilter<Type, Key extends keyof Type> = undefined extends Type[Key] + ? Type[Key] extends undefined + ? never + : Key + : never; + +/** +Enforce optional keys (by adding the `?` operator) for keys that have a union with `undefined`. + +@example +``` +import type {EnforceOptional} from 'type-fest'; + +type Foo = { + a: string; + b?: string; + c: undefined; + d: number | undefined; +}; + +type FooBar = EnforceOptional<Foo>; +// => { +// a: string; +// b?: string; +// c: undefined; +// d?: number; +// } +``` + +@internal +@category Object +*/ +export type EnforceOptional<ObjectType> = Simplify<{ + [Key in keyof ObjectType as RequiredFilter<ObjectType, Key>]: ObjectType[Key] +} & { + [Key in keyof ObjectType as OptionalFilter<ObjectType, Key>]?: Exclude<ObjectType[Key], undefined> +}>; diff --git a/node_modules/type-fest/source/entries.d.ts b/node_modules/type-fest/source/entries.d.ts new file mode 100644 index 0000000..b5bec7f --- /dev/null +++ b/node_modules/type-fest/source/entries.d.ts @@ -0,0 +1,62 @@ +import type {ArrayEntry, MapEntry, ObjectEntry, SetEntry} from './entry'; + +type ArrayEntries<BaseType extends readonly unknown[]> = Array<ArrayEntry<BaseType>>; +type MapEntries<BaseType> = Array<MapEntry<BaseType>>; +type ObjectEntries<BaseType> = Array<ObjectEntry<BaseType>>; +type SetEntries<BaseType extends Set<unknown>> = Array<SetEntry<BaseType>>; + +/** +Many collections have an `entries` method which returns an array of a given object's own enumerable string-keyed property [key, value] pairs. The `Entries` type will return the type of that collection's entries. + +For example the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries|`Object`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries|`Map`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries|`Array`}, and {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries|`Set`} collections all have this method. Note that `WeakMap` and `WeakSet` do not have this method since their entries are not enumerable. + +@see `Entry` if you want to just access the type of a single entry. + +@example +``` +import type {Entries} from 'type-fest'; + +interface Example { + someKey: number; +} + +const manipulatesEntries = (examples: Entries<Example>) => examples.map(example => [ + // Does some arbitrary processing on the key (with type information available) + example[0].toUpperCase(), + + // Does some arbitrary processing on the value (with type information available) + example[1].toFixed() +]); + +const example: Example = {someKey: 1}; +const entries = Object.entries(example) as Entries<Example>; +const output = manipulatesEntries(entries); + +// Objects +const objectExample = {a: 1}; +const objectEntries: Entries<typeof objectExample> = [['a', 1]]; + +// Arrays +const arrayExample = ['a', 1]; +const arrayEntries: Entries<typeof arrayExample> = [[0, 'a'], [1, 1]]; + +// Maps +const mapExample = new Map([['a', 1]]); +const mapEntries: Entries<typeof map> = [['a', 1]]; + +// Sets +const setExample = new Set(['a', 1]); +const setEntries: Entries<typeof setExample> = [['a', 'a'], [1, 1]]; +``` + +@category Object +@category Map +@category Set +@category Array +*/ +export type Entries<BaseType> = + BaseType extends Map<unknown, unknown> ? MapEntries<BaseType> + : BaseType extends Set<unknown> ? SetEntries<BaseType> + : BaseType extends readonly unknown[] ? ArrayEntries<BaseType> + : BaseType extends object ? ObjectEntries<BaseType> + : never; diff --git a/node_modules/type-fest/source/entry.d.ts b/node_modules/type-fest/source/entry.d.ts new file mode 100644 index 0000000..68e2f9c --- /dev/null +++ b/node_modules/type-fest/source/entry.d.ts @@ -0,0 +1,65 @@ +type MapKey<BaseType> = BaseType extends Map<infer KeyType, unknown> ? KeyType : never; +type MapValue<BaseType> = BaseType extends Map<unknown, infer ValueType> ? ValueType : never; + +export type ArrayEntry<BaseType extends readonly unknown[]> = [number, BaseType[number]]; +export type MapEntry<BaseType> = [MapKey<BaseType>, MapValue<BaseType>]; +export type ObjectEntry<BaseType> = [keyof BaseType, BaseType[keyof BaseType]]; +export type SetEntry<BaseType> = BaseType extends Set<infer ItemType> ? [ItemType, ItemType] : never; + +/** +Many collections have an `entries` method which returns an array of a given object's own enumerable string-keyed property [key, value] pairs. The `Entry` type will return the type of that collection's entry. + +For example the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries|`Object`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries|`Map`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries|`Array`}, and {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries|`Set`} collections all have this method. Note that `WeakMap` and `WeakSet` do not have this method since their entries are not enumerable. + +@see `Entries` if you want to just access the type of the array of entries (which is the return of the `.entries()` method). + +@example +``` +import type {Entry} from 'type-fest'; + +interface Example { + someKey: number; +} + +const manipulatesEntry = (example: Entry<Example>) => [ + // Does some arbitrary processing on the key (with type information available) + example[0].toUpperCase(), + + // Does some arbitrary processing on the value (with type information available) + example[1].toFixed(), +]; + +const example: Example = {someKey: 1}; +const entry = Object.entries(example)[0] as Entry<Example>; +const output = manipulatesEntry(entry); + +// Objects +const objectExample = {a: 1}; +const objectEntry: Entry<typeof objectExample> = ['a', 1]; + +// Arrays +const arrayExample = ['a', 1]; +const arrayEntryString: Entry<typeof arrayExample> = [0, 'a']; +const arrayEntryNumber: Entry<typeof arrayExample> = [1, 1]; + +// Maps +const mapExample = new Map([['a', 1]]); +const mapEntry: Entry<typeof mapExample> = ['a', 1]; + +// Sets +const setExample = new Set(['a', 1]); +const setEntryString: Entry<typeof setExample> = ['a', 'a']; +const setEntryNumber: Entry<typeof setExample> = [1, 1]; +``` + +@category Object +@category Map +@category Array +@category Set +*/ +export type Entry<BaseType> = + BaseType extends Map<unknown, unknown> ? MapEntry<BaseType> + : BaseType extends Set<unknown> ? SetEntry<BaseType> + : BaseType extends readonly unknown[] ? ArrayEntry<BaseType> + : BaseType extends object ? ObjectEntry<BaseType> + : never; diff --git a/node_modules/type-fest/source/exact.d.ts b/node_modules/type-fest/source/exact.d.ts new file mode 100644 index 0000000..6c435eb --- /dev/null +++ b/node_modules/type-fest/source/exact.d.ts @@ -0,0 +1,62 @@ +import type {KeysOfUnion, ArrayElement, ObjectValue} from './internal'; +import type {Opaque} from './opaque'; +import type {IsEqual} from './is-equal'; + +/** +Create a type from `ParameterType` and `InputType` and change keys exclusive to `InputType` to `never`. +- Generate a list of keys that exists in `InputType` but not in `ParameterType`. +- Mark these excess keys as `never`. +*/ +type ExactObject<ParameterType, InputType> = {[Key in keyof ParameterType]: Exact<ParameterType[Key], ObjectValue<InputType, Key>>} +& Record<Exclude<keyof InputType, KeysOfUnion<ParameterType>>, never>; + +/** +Create a type that does not allow extra properties, meaning it only allows properties that are explicitly declared. + +This is useful for function type-guarding to reject arguments with excess properties. Due to the nature of TypeScript, it does not complain if excess properties are provided unless the provided value is an object literal. + +*Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/12936) if you want to have this type as a built-in in TypeScript.* + +@example +``` +type OnlyAcceptName = {name: string}; + +function onlyAcceptName(arguments_: OnlyAcceptName) {} + +// TypeScript complains about excess properties when an object literal is provided. +onlyAcceptName({name: 'name', id: 1}); +//=> `id` is excess + +// TypeScript does not complain about excess properties when the provided value is a variable (not an object literal). +const invalidInput = {name: 'name', id: 1}; +onlyAcceptName(invalidInput); // No errors +``` + +Having `Exact` allows TypeScript to reject excess properties. + +@example +``` +import {Exact} from 'type-fest'; + +type OnlyAcceptName = {name: string}; + +function onlyAcceptNameImproved<T extends Exact<OnlyAcceptName, T>>(arguments_: T) {} + +const invalidInput = {name: 'name', id: 1}; +onlyAcceptNameImproved(invalidInput); // Compilation error +``` + +[Read more](https://stackoverflow.com/questions/49580725/is-it-possible-to-restrict-typescript-object-to-contain-only-properties-defined) + +@category Utilities +*/ +export type Exact<ParameterType, InputType> = + IsEqual<ParameterType, InputType> extends true ? ParameterType + // Convert union of array to array of union: A[] & B[] => (A & B)[] + : ParameterType extends unknown[] ? Array<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>> + // In TypeScript, Array is a subtype of ReadonlyArray, so always test Array before ReadonlyArray. + : ParameterType extends readonly unknown[] ? ReadonlyArray<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>> + // For Opaque types, internal details are hidden from public, so let's leave it as is. + : ParameterType extends Opaque<infer OpaqueType, infer OpaqueToken> ? ParameterType + : ParameterType extends object ? ExactObject<ParameterType, InputType> + : ParameterType; diff --git a/node_modules/type-fest/source/except.d.ts b/node_modules/type-fest/source/except.d.ts new file mode 100644 index 0000000..7abf302 --- /dev/null +++ b/node_modules/type-fest/source/except.d.ts @@ -0,0 +1,80 @@ +import type {IsEqual} from './is-equal'; + +/** +Filter out keys from an object. + +Returns `never` if `Exclude` is strictly equal to `Key`. +Returns `never` if `Key` extends `Exclude`. +Returns `Key` otherwise. + +@example +``` +type Filtered = Filter<'foo', 'foo'>; +//=> never +``` + +@example +``` +type Filtered = Filter<'bar', string>; +//=> never +``` + +@example +``` +type Filtered = Filter<'bar', 'foo'>; +//=> 'bar' +``` + +@see {Except} +*/ +type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ? never : (KeyType extends ExcludeType ? never : KeyType); + +type ExceptOptions = { + /** + Disallow assigning non-specified properties. + + Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`. + + @default false + */ + requireExactProps?: boolean; +}; + +/** +Create a type from an object type without certain keys. + +We recommend setting the `requireExactProps` option to `true`. + +This type is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type). The `Omit` type does not restrict the omitted keys to be keys present on the given type, while `Except` does. The benefits of a stricter type are avoiding typos and allowing the compiler to pick up on rename refactors automatically. + +This type was proposed to the TypeScript team, which declined it, saying they prefer that libraries implement stricter versions of the built-in types ([microsoft/TypeScript#30825](https://github.com/microsoft/TypeScript/issues/30825#issuecomment-523668235)). + +@example +``` +import type {Except} from 'type-fest'; + +type Foo = { + a: number; + b: string; +}; + +type FooWithoutA = Except<Foo, 'a'>; +//=> {b: string} + +const fooWithoutA: FooWithoutA = {a: 1, b: '2'}; +//=> errors: 'a' does not exist in type '{ b: string; }' + +type FooWithoutB = Except<Foo, 'b', {requireExactProps: true}>; +//=> {a: number} & Partial<Record<"b", never>> + +const fooWithoutB: FooWithoutB = {a: 1, b: '2'}; +//=> errors at 'b': Type 'string' is not assignable to type 'undefined'. +``` + +@category Object +*/ +export type Except<ObjectType, KeysType extends keyof ObjectType, Options extends ExceptOptions = {requireExactProps: false}> = { + [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType]; +} & (Options['requireExactProps'] extends true + ? Partial<Record<KeysType, never>> + : {}); diff --git a/node_modules/type-fest/source/fixed-length-array.d.ts b/node_modules/type-fest/source/fixed-length-array.d.ts new file mode 100644 index 0000000..aa71719 --- /dev/null +++ b/node_modules/type-fest/source/fixed-length-array.d.ts @@ -0,0 +1,43 @@ +/** +Methods to exclude. +*/ +type ArrayLengthMutationKeys = 'splice' | 'push' | 'pop' | 'shift' | 'unshift'; + +/** +Create a type that represents an array of the given type and length. The array's length and the `Array` prototype methods that manipulate its length are excluded in the resulting type. + +Please participate in [this issue](https://github.com/microsoft/TypeScript/issues/26223) if you want to have a similar type built into TypeScript. + +Use-cases: +- Declaring fixed-length tuples or arrays with a large number of items. +- Creating a range union (for example, `0 | 1 | 2 | 3 | 4` from the keys of such a type) without having to resort to recursive types. +- Creating an array of coordinates with a static length, for example, length of 3 for a 3D vector. + +Note: This type does not prevent out-of-bounds access. Prefer `ReadonlyTuple` unless you need mutability. + +@example +``` +import type {FixedLengthArray} from 'type-fest'; + +type FencingTeam = FixedLengthArray<string, 3>; + +const guestFencingTeam: FencingTeam = ['Josh', 'Michael', 'Robert']; + +const homeFencingTeam: FencingTeam = ['George', 'John']; +//=> error TS2322: Type string[] is not assignable to type 'FencingTeam' + +guestFencingTeam.push('Sam'); +//=> error TS2339: Property 'push' does not exist on type 'FencingTeam' +``` + +@category Array +@see ReadonlyTuple +*/ +export type FixedLengthArray<Element, Length extends number, ArrayPrototype = [Element, ...Element[]]> = Pick< +ArrayPrototype, +Exclude<keyof ArrayPrototype, ArrayLengthMutationKeys> +> & { + [index: number]: Element; + [Symbol.iterator]: () => IterableIterator<Element>; + readonly length: Length; +}; diff --git a/node_modules/type-fest/source/get.d.ts b/node_modules/type-fest/source/get.d.ts new file mode 100644 index 0000000..9b56fef --- /dev/null +++ b/node_modules/type-fest/source/get.d.ts @@ -0,0 +1,191 @@ +import type {StringDigit} from '../source/internal'; +import type {Split} from './split'; +import type {StringKeyOf} from './string-key-of'; + +type GetOptions = { + /** + Include `undefined` in the return type when accessing properties. + + Setting this to `false` is not recommended. + + @default true + */ + strict?: boolean; +}; + +/** +Like the `Get` type but receives an array of strings as a path parameter. +*/ +type GetWithPath<BaseType, Keys extends readonly string[], Options extends GetOptions = {}> = + Keys extends [] + ? BaseType + : Keys extends readonly [infer Head, ...infer Tail] + ? GetWithPath< + PropertyOf<BaseType, Extract<Head, string>, Options>, + Extract<Tail, string[]>, + Options + > + : never; + +/** +Adds `undefined` to `Type` if `strict` is enabled. +*/ +type Strictify<Type, Options extends GetOptions> = + Options['strict'] extends false ? Type : (Type | undefined); + +/** +If `Options['strict']` is `true`, includes `undefined` in the returned type when accessing properties on `Record<string, any>`. + +Known limitations: +- Does not include `undefined` in the type on object types with an index signature (for example, `{a: string; [key: string]: string}`). +*/ +type StrictPropertyOf<BaseType, Key extends keyof BaseType, Options extends GetOptions> = + Record<string, any> extends BaseType + ? string extends keyof BaseType + ? Strictify<BaseType[Key], Options> // Record<string, any> + : BaseType[Key] // Record<'a' | 'b', any> (Records with a string union as keys have required properties) + : BaseType[Key]; + +/** +Splits a dot-prop style path into a tuple comprised of the properties in the path. Handles square-bracket notation. + +@example +``` +ToPath<'foo.bar.baz'> +//=> ['foo', 'bar', 'baz'] + +ToPath<'foo[0].bar.baz'> +//=> ['foo', '0', 'bar', 'baz'] +``` +*/ +type ToPath<S extends string> = Split<FixPathSquareBrackets<S>, '.'>; + +/** +Replaces square-bracketed dot notation with dots, for example, `foo[0].bar` -> `foo.0.bar`. +*/ +type FixPathSquareBrackets<Path extends string> = + Path extends `[${infer Head}]${infer Tail}` + ? Tail extends `[${string}` + ? `${Head}.${FixPathSquareBrackets<Tail>}` + : `${Head}${FixPathSquareBrackets<Tail>}` + : Path extends `${infer Head}[${infer Middle}]${infer Tail}` + ? `${Head}.${FixPathSquareBrackets<`[${Middle}]${Tail}`>}` + : Path; + +/** +Returns true if `LongString` is made up out of `Substring` repeated 0 or more times. + +@example +``` +ConsistsOnlyOf<'aaa', 'a'> //=> true +ConsistsOnlyOf<'ababab', 'ab'> //=> true +ConsistsOnlyOf<'aBa', 'a'> //=> false +ConsistsOnlyOf<'', 'a'> //=> true +``` +*/ +type ConsistsOnlyOf<LongString extends string, Substring extends string> = + LongString extends '' + ? true + : LongString extends `${Substring}${infer Tail}` + ? ConsistsOnlyOf<Tail, Substring> + : false; + +/** +Convert a type which may have number keys to one with string keys, making it possible to index using strings retrieved from template types. + +@example +``` +type WithNumbers = {foo: string; 0: boolean}; +type WithStrings = WithStringKeys<WithNumbers>; + +type WithNumbersKeys = keyof WithNumbers; +//=> 'foo' | 0 +type WithStringsKeys = keyof WithStrings; +//=> 'foo' | '0' +``` +*/ +type WithStringKeys<BaseType> = { + [Key in StringKeyOf<BaseType>]: UncheckedIndex<BaseType, Key> +}; + +/** +Perform a `T[U]` operation if `T` supports indexing. +*/ +type UncheckedIndex<T, U extends string | number> = [T] extends [Record<string | number, any>] ? T[U] : never; + +/** +Get a property of an object or array. Works when indexing arrays using number-literal-strings, for example, `PropertyOf<number[], '0'> = number`, and when indexing objects with number keys. + +Note: +- Returns `unknown` if `Key` is not a property of `BaseType`, since TypeScript uses structural typing, and it cannot be guaranteed that extra properties unknown to the type system will exist at runtime. +- Returns `undefined` from nullish values, to match the behaviour of most deep-key libraries like `lodash`, `dot-prop`, etc. +*/ +type PropertyOf<BaseType, Key extends string, Options extends GetOptions = {}> = + BaseType extends null | undefined + ? undefined + : Key extends keyof BaseType + ? StrictPropertyOf<BaseType, Key, Options> + : BaseType extends [] | [unknown, ...unknown[]] + ? unknown // It's a tuple, but `Key` did not extend `keyof BaseType`. So the index is out of bounds. + : BaseType extends { + [n: number]: infer Item; + length: number; // Note: This is needed to avoid being too lax with records types using number keys like `{0: string; 1: boolean}`. + } + ? ( + ConsistsOnlyOf<Key, StringDigit> extends true + ? Strictify<Item, Options> + : unknown + ) + : Key extends keyof WithStringKeys<BaseType> + ? StrictPropertyOf<WithStringKeys<BaseType>, Key, Options> + : unknown; + +// This works by first splitting the path based on `.` and `[...]` characters into a tuple of string keys. Then it recursively uses the head key to get the next property of the current object, until there are no keys left. Number keys extract the item type from arrays, or are converted to strings to extract types from tuples and dictionaries with number keys. +/** +Get a deeply-nested property from an object using a key path, like Lodash's `.get()` function. + +Use-case: Retrieve a property from deep inside an API response or some other complex object. + +@example +``` +import type {Get} from 'type-fest'; +import * as lodash from 'lodash'; + +const get = <BaseType, Path extends string | readonly string[]>(object: BaseType, path: Path): Get<BaseType, Path> => + lodash.get(object, path); + +interface ApiResponse { + hits: { + hits: Array<{ + _id: string + _source: { + name: Array<{ + given: string[] + family: string + }> + birthDate: string + } + }> + } +} + +const getName = (apiResponse: ApiResponse) => + get(apiResponse, 'hits.hits[0]._source.name'); + //=> Array<{given: string[]; family: string}> | undefined + +// Path also supports a readonly array of strings +const getNameWithPathArray = (apiResponse: ApiResponse) => + get(apiResponse, ['hits','hits', '0', '_source', 'name'] as const); + //=> Array<{given: string[]; family: string}> | undefined + +// Non-strict mode: +Get<string[], '3', {strict: false}> //=> string +Get<Record<string, string>, 'foo', {strict: true}> // => string +``` + +@category Object +@category Array +@category Template literal +*/ +export type Get<BaseType, Path extends string | readonly string[], Options extends GetOptions = {}> = + GetWithPath<BaseType, Path extends string ? ToPath<Path> : Path, Options>; diff --git a/node_modules/type-fest/source/global-this.d.ts b/node_modules/type-fest/source/global-this.d.ts new file mode 100644 index 0000000..841ab2d --- /dev/null +++ b/node_modules/type-fest/source/global-this.d.ts @@ -0,0 +1,21 @@ +/** +Declare locally scoped properties on `globalThis`. + +When defining a global variable in a declaration file is inappropriate, it can be helpful to define a `type` or `interface` (say `ExtraGlobals`) with the global variable and then cast `globalThis` via code like `globalThis as unknown as ExtraGlobals`. + +Instead of casting through `unknown`, you can update your `type` or `interface` to extend `GlobalThis` and then directly cast `globalThis`. + +@example +``` +import type {GlobalThis} from 'type-fest'; + +type ExtraGlobals = GlobalThis & { + readonly GLOBAL_TOKEN: string; +}; + +(globalThis as ExtraGlobals).GLOBAL_TOKEN; +``` + +@category Type +*/ +export type GlobalThis = typeof globalThis; diff --git a/node_modules/type-fest/source/has-optional-keys.d.ts b/node_modules/type-fest/source/has-optional-keys.d.ts new file mode 100644 index 0000000..5978a71 --- /dev/null +++ b/node_modules/type-fest/source/has-optional-keys.d.ts @@ -0,0 +1,21 @@ +import type {OptionalKeysOf} from './optional-keys-of'; + +/** +Creates a type that represents `true` or `false` depending on whether the given type has any optional fields. + +This is useful when you want to create an API whose behavior depends on the presence or absence of optional fields. + +@example +``` +import type {HasOptionalKeys, OptionalKeysOf} from 'type-fest'; + +type UpdateService<Entity extends object> = { + removeField: HasOptionalKeys<Entity> extends true + ? (field: OptionalKeysOf<Entity>) => Promise<void> + : never +} +``` + +@category Utilities +*/ +export type HasOptionalKeys<BaseType extends object> = OptionalKeysOf<BaseType> extends never ? false : true; diff --git a/node_modules/type-fest/source/has-readonly-keys.d.ts b/node_modules/type-fest/source/has-readonly-keys.d.ts new file mode 100644 index 0000000..722138c --- /dev/null +++ b/node_modules/type-fest/source/has-readonly-keys.d.ts @@ -0,0 +1,21 @@ +import type {ReadonlyKeysOf} from './readonly-keys-of'; + +/** +Creates a type that represents `true` or `false` depending on whether the given type has any readonly fields. + +This is useful when you want to create an API whose behavior depends on the presence or absence of readonly fields. + +@example +``` +import type {HasReadonlyKeys, ReadonlyKeysOf} from 'type-fest'; + +type UpdateService<Entity extends object> = { + removeField: HasReadonlyKeys<Entity> extends true + ? (field: ReadonlyKeysOf<Entity>) => Promise<void> + : never +} +``` + +@category Utilities +*/ +export type HasReadonlyKeys<BaseType extends object> = ReadonlyKeysOf<BaseType> extends never ? false : true; diff --git a/node_modules/type-fest/source/has-required-keys.d.ts b/node_modules/type-fest/source/has-required-keys.d.ts new file mode 100644 index 0000000..6e0d9a7 --- /dev/null +++ b/node_modules/type-fest/source/has-required-keys.d.ts @@ -0,0 +1,59 @@ +import type {RequiredKeysOf} from './required-keys-of'; + +/** +Creates a type that represents `true` or `false` depending on whether the given type has any required fields. + +This is useful when you want to create an API whose behavior depends on the presence or absence of required fields. + +@example +``` +import type {HasRequiredKeys} from 'type-fest'; + +type GeneratorOptions<Template extends object> = { + prop1: number; + prop2: string; +} & (HasRequiredKeys<Template> extends true + ? {template: Template} + : {template?: Template}); + +interface Template1 { + optionalSubParam?: string; +} + +interface Template2 { + requiredSubParam: string; +} + +type Options1 = GeneratorOptions<Template1>; +type Options2 = GeneratorOptions<Template2>; + +const optA: Options1 = { + prop1: 0, + prop2: 'hi' +}; +const optB: Options1 = { + prop1: 0, + prop2: 'hi', + template: {} +}; +const optC: Options1 = { + prop1: 0, + prop2: 'hi', + template: { + optionalSubParam: 'optional value' + } +}; + +const optD: Options2 = { + prop1: 0, + prop2: 'hi', + template: { + requiredSubParam: 'required value' + } +}; + +``` + +@category Utilities +*/ +export type HasRequiredKeys<BaseType extends object> = RequiredKeysOf<BaseType> extends never ? false : true; diff --git a/node_modules/type-fest/source/has-writable-keys.d.ts b/node_modules/type-fest/source/has-writable-keys.d.ts new file mode 100644 index 0000000..388c40a --- /dev/null +++ b/node_modules/type-fest/source/has-writable-keys.d.ts @@ -0,0 +1,21 @@ +import type {WritableKeysOf} from './writable-keys-of'; + +/** +Creates a type that represents `true` or `false` depending on whether the given type has any writable fields. + +This is useful when you want to create an API whose behavior depends on the presence or absence of writable fields. + +@example +``` +import type {HasWritableKeys, WritableKeysOf} from 'type-fest'; + +type UpdateService<Entity extends object> = { + removeField: HasWritableKeys<Entity> extends true + ? (field: WritableKeysOf<Entity>) => Promise<void> + : never +} +``` + +@category Utilities +*/ +export type HasWritableKeys<BaseType extends object> = WritableKeysOf<BaseType> extends never ? false : true; diff --git a/node_modules/type-fest/source/if-any.d.ts b/node_modules/type-fest/source/if-any.d.ts new file mode 100644 index 0000000..1c17b76 --- /dev/null +++ b/node_modules/type-fest/source/if-any.d.ts @@ -0,0 +1,24 @@ +import type {IsAny} from './is-any'; + +/** +An if-else-like type that resolves depending on whether the given type is `any`. + +@see {@link IsAny} + +@example +``` +import type {IfAny} from 'type-fest'; + +type ShouldBeTrue = IfAny<any>; +//=> true + +type ShouldBeBar = IfAny<'not any', 'foo', 'bar'>; +//=> 'bar' +``` + +@category Type Guard +@category Utilities +*/ +export type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = ( + IsAny<T> extends true ? TypeIfAny : TypeIfNotAny +); diff --git a/node_modules/type-fest/source/if-never.d.ts b/node_modules/type-fest/source/if-never.d.ts new file mode 100644 index 0000000..d33af2e --- /dev/null +++ b/node_modules/type-fest/source/if-never.d.ts @@ -0,0 +1,24 @@ +import type {IsNever} from './is-never'; + +/** +An if-else-like type that resolves depending on whether the given type is `never`. + +@see {@link IsNever} + +@example +``` +import type {IfNever} from 'type-fest'; + +type ShouldBeTrue = IfNever<never>; +//=> true + +type ShouldBeBar = IfNever<'not never', 'foo', 'bar'>; +//=> 'bar' +``` + +@category Type Guard +@category Utilities +*/ +export type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = ( + IsNever<T> extends true ? TypeIfNever : TypeIfNotNever +); diff --git a/node_modules/type-fest/source/if-unknown.d.ts b/node_modules/type-fest/source/if-unknown.d.ts new file mode 100644 index 0000000..828268c --- /dev/null +++ b/node_modules/type-fest/source/if-unknown.d.ts @@ -0,0 +1,24 @@ +import type {IsUnknown} from './is-unknown'; + +/** +An if-else-like type that resolves depending on whether the given type is `unknown`. + +@see {@link IsUnknown} + +@example +``` +import type {IfUnknown} from 'type-fest'; + +type ShouldBeTrue = IfUnknown<unknown>; +//=> true + +type ShouldBeBar = IfUnknown<'not unknown', 'foo', 'bar'>; +//=> 'bar' +``` + +@category Type Guard +@category Utilities +*/ +export type IfUnknown<T, TypeIfUnknown = true, TypeIfNotUnknown = false> = ( + IsUnknown<T> extends true ? TypeIfUnknown : TypeIfNotUnknown +); diff --git a/node_modules/type-fest/source/includes.d.ts b/node_modules/type-fest/source/includes.d.ts new file mode 100644 index 0000000..b269dd4 --- /dev/null +++ b/node_modules/type-fest/source/includes.d.ts @@ -0,0 +1,22 @@ +import type {IsEqual} from './is-equal'; + +/** +Returns a boolean for whether the given array includes the given item. + +This can be useful if another type wants to make a decision based on whether the array includes that item. + +@example +``` +import type {Includes} from 'type-fest'; + +type hasRed<array extends any[]> = Includes<array, 'red'>; +``` + +@category Array +*/ +export type Includes<Value extends readonly any[], Item> = + Value extends readonly [Value[0], ...infer rest] + ? IsEqual<Value[0], Item> extends true + ? true + : Includes<rest, Item> + : false; diff --git a/node_modules/type-fest/source/internal.d.ts b/node_modules/type-fest/source/internal.d.ts new file mode 100644 index 0000000..8642f60 --- /dev/null +++ b/node_modules/type-fest/source/internal.d.ts @@ -0,0 +1,253 @@ +import type {Primitive} from './primitive'; +import type {Simplify} from './simplify'; +import type {Trim} from './trim'; +import type {IsAny} from './is-any'; + +/** +Infer the length of the given array `<T>`. + +@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f +*/ +type TupleLength<T extends readonly unknown[]> = T extends {readonly length: infer L} ? L : never; + +/** +Create a tuple type of the given length `<L>`. + +@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f +*/ +type BuildTuple<L extends number, T extends readonly unknown[] = []> = T extends {readonly length: L} + ? T + : BuildTuple<L, [...T, unknown]>; + +/** +Create a tuple of length `A` and a tuple composed of two other tuples, +the inferred tuple `U` and a tuple of length `B`, then extracts the length of tuple `U`. + +@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f +*/ +export type Subtract<A extends number, B extends number> = BuildTuple<A> extends [...(infer U), ...BuildTuple<B>] + ? TupleLength<U> + : never; + +/** +Matches any primitive, `Date`, or `RegExp` value. +*/ +export type BuiltIns = Primitive | Date | RegExp; + +/** +Gets keys from a type. Similar to `keyof` but this one also works for union types. + +The reason a simple `keyof Union` does not work is because `keyof` always returns the accessible keys of a type. In the case of a union, that will only be the common keys. + +@link https://stackoverflow.com/a/49402091 +*/ +export type KeysOfUnion<T> = T extends T ? keyof T : never; + +export type UpperCaseCharacters = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'; + +export type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; + +export type Whitespace = + | '\u{9}' // '\t' + | '\u{A}' // '\n' + | '\u{B}' // '\v' + | '\u{C}' // '\f' + | '\u{D}' // '\r' + | '\u{20}' // ' ' + | '\u{85}' + | '\u{A0}' + | '\u{1680}' + | '\u{2000}' + | '\u{2001}' + | '\u{2002}' + | '\u{2003}' + | '\u{2004}' + | '\u{2005}' + | '\u{2006}' + | '\u{2007}' + | '\u{2008}' + | '\u{2009}' + | '\u{200A}' + | '\u{2028}' + | '\u{2029}' + | '\u{202F}' + | '\u{205F}' + | '\u{3000}' + | '\u{FEFF}'; + +export type WordSeparators = '-' | '_' | Whitespace; + +/** +Matches any unknown record. +*/ +export type UnknownRecord = Record<PropertyKey, unknown>; + +/** +Matches any unknown array or tuple. +*/ +export type UnknownArrayOrTuple = readonly [...unknown[]]; + +/** +Matches any non empty tuple. +*/ +export type NonEmptyTuple = readonly [unknown, ...unknown[]]; + +/** +Returns a boolean for whether the two given types extends the base type. +*/ +export type IsBothExtends<BaseType, FirstType, SecondType> = FirstType extends BaseType + ? SecondType extends BaseType + ? true + : false + : false; + +/** +Extracts the type of the first element of an array or tuple. +*/ +export type FirstArrayElement<TArray extends UnknownArrayOrTuple> = TArray extends readonly [infer THead, ...unknown[]] + ? THead + : never; + +/** +Extracts the type of an array or tuple minus the first element. +*/ +export type ArrayTail<TArray extends UnknownArrayOrTuple> = TArray extends readonly [unknown, ...infer TTail] ? TTail : []; + +/** +Extract the element of an array that also works for array union. + +Returns `never` if T is not an array. + +It creates a type-safe way to access the element type of `unknown` type. +*/ +export type ArrayElement<T> = T extends readonly unknown[] ? T[0] : never; + +/** +Extract the object field type if T is an object and K is a key of T, return `never` otherwise. + +It creates a type-safe way to access the member type of `unknown` type. +*/ +export type ObjectValue<T, K> = K extends keyof T ? T[K] : never; + +/** +Returns a boolean for whether the string is lowercased. +*/ +export type IsLowerCase<T extends string> = T extends Lowercase<T> ? true : false; + +/** +Returns a boolean for whether the string is uppercased. +*/ +export type IsUpperCase<T extends string> = T extends Uppercase<T> ? true : false; + +/** +Returns a boolean for whether a string is whitespace. +*/ +export type IsWhitespace<T extends string> = T extends Whitespace + ? true + : T extends `${Whitespace}${infer Rest}` + ? IsWhitespace<Rest> + : false; + +/** +Returns a boolean for whether the string is numeric. + +This type is a workaround for [Microsoft/TypeScript#46109](https://github.com/microsoft/TypeScript/issues/46109#issuecomment-930307987). +*/ +export type IsNumeric<T extends string> = T extends `${number}` + ? Trim<T> extends T + ? true + : false + : false; + +/** +For an object T, if it has any properties that are a union with `undefined`, make those into optional properties instead. + +@example +``` +type User = { + firstName: string; + lastName: string | undefined; +}; + +type OptionalizedUser = UndefinedToOptional<User>; +//=> { +// firstName: string; +// lastName?: string; +// } +``` +*/ +export type UndefinedToOptional<T extends object> = Simplify< +{ + // Property is not a union with `undefined`, keep it as-is. + [Key in keyof Pick<T, FilterDefinedKeys<T>>]: T[Key]; +} & { + // Property _is_ a union with defined value. Set as optional (via `?`) and remove `undefined` from the union. + [Key in keyof Pick<T, FilterOptionalKeys<T>>]?: Exclude<T[Key], undefined>; +} +>; + +// Returns `never` if the key or property is not jsonable without testing whether the property is required or optional otherwise return the key. +type BaseKeyFilter<Type, Key extends keyof Type> = Key extends symbol + ? never + : Type[Key] extends symbol + ? never + : [(...arguments_: any[]) => any] extends [Type[Key]] + ? never + : Key; + +/** +Returns the required keys. +*/ +type FilterDefinedKeys<T extends object> = Exclude< +{ + [Key in keyof T]: IsAny<T[Key]> extends true + ? Key + : undefined extends T[Key] + ? never + : T[Key] extends undefined + ? never + : BaseKeyFilter<T, Key>; +}[keyof T], +undefined +>; + +/** +Returns the optional keys. +*/ +type FilterOptionalKeys<T extends object> = Exclude< +{ + [Key in keyof T]: IsAny<T[Key]> extends true + ? never + : undefined extends T[Key] + ? T[Key] extends undefined + ? never + : BaseKeyFilter<T, Key> + : never; +}[keyof T], +undefined +>; + +/** +Test if the given function has multiple call signatures. + +Needed to handle the case of a single call signature with properties. + +Multiple call signatures cannot currently be supported due to a TypeScript limitation. +@see https://github.com/microsoft/TypeScript/issues/29732 +*/ +export type HasMultipleCallSignatures<T extends (...arguments_: any[]) => unknown> = + T extends {(...arguments_: infer A): unknown; (...arguments_: any[]): unknown} + ? unknown[] extends A + ? false + : true + : false; + +/** +Returns a boolean for whether the given `boolean` is not `false`. +*/ +export type IsNotFalse<T extends boolean> = [T] extends [false] ? false : true; + +/** +Returns a boolean for whether the given type is `null`. +*/ +export type IsNull<T> = [T] extends [null] ? true : false; diff --git a/node_modules/type-fest/source/invariant-of.d.ts b/node_modules/type-fest/source/invariant-of.d.ts new file mode 100644 index 0000000..6f7ac92 --- /dev/null +++ b/node_modules/type-fest/source/invariant-of.d.ts @@ -0,0 +1,76 @@ +import type {Opaque} from './opaque'; + +/** +Create an [invariant type](https://basarat.gitbook.io/typescript/type-system/type-compatibility#footnote-invariance), which is a type that does not accept supertypes and subtypes. + +Use-case: +- Prevent runtime errors that may occur due to assigning subtypes to supertypes. +- Improve type signature of object methods like [`Object.keys()` or `Object.entries()`](https://github.com/microsoft/TypeScript/pull/12253#issuecomment-263132208) by sealing the object type. + +@example +``` +import type {InvariantOf} from 'type-fest'; + +class Animal { + constructor(public name: string){} +} + +class Cat extends Animal { + meow() {} +} + +let animalArray: Animal[] = [animal]; +let catArray: Cat[] = [cat]; + +animalArray = catArray; // Okay if covariant +animalArray.push(new Animal('another animal')); // Pushed an animal into catArray +catArray.forEach(c => c.meow()); // Allowed but, error at runtime + +let invariantAnimalArray: InvariantOf<Animal>[] = [animal] as InvariantOf<Animal>[]; +let invariantCatArray: InvariantOf<Cat>[] = [cat] as InvariantOf<Cat>[]; + +invariantAnimalArray = invariantCatArray; // Error: Type 'InvariantOf<Cat>[]' is not assignable to type 'InvariantOf<Animal>[]'. +``` + +@example +``` +import type {InvariantOf} from 'type-fest'; + +// In covariance (default) + +interface FooBar { + foo: number; + bar: string +} + +interface FooBarBaz extends FooBar { + baz: boolean +} + +declare const fooBar: FooBar +declare const fooBarBaz: FooBarBaz + +function keyOfFooBar(fooBar: FooBar) { + return Object.keys(fooBar) as (keyof FooBar)[] +} + +keyOfFooBar(fooBar) //=> (keyof FooBar)[] +keyOfFooBar(fooBarBaz) //=> (keyof FooBar)[] but, (keyof FooBarBaz)[] at runtime + +// In invariance + +export function invariantOf<Type>(value: Type): InvariantOf<Type> { + return value as InvariantOf<Type>; +} + +function keyOfInvariantFooBar(fooBar: InvariantOf<FooBar>) { + return Object.keys(fooBar) as (keyof FooBar)[] +} + +keyOfInvariantFooBar(invariantOf(fooBar)); // (keyof FooBar)[] +keyOfInvariantFooBar(invariantOf(fooBarBaz)); // Error: Argument of type 'InvariantOf<FooBarBaz>' is not assignable to parameter of type 'InvariantOf<FooBar>'. +``` + +@category Type +*/ +export type InvariantOf<Type> = Opaque<Type, (argument: Type) => Type>; diff --git a/node_modules/type-fest/source/is-any.d.ts b/node_modules/type-fest/source/is-any.d.ts new file mode 100644 index 0000000..9f1c3ec --- /dev/null +++ b/node_modules/type-fest/source/is-any.d.ts @@ -0,0 +1,29 @@ +/** +Returns a boolean for whether the given type is `any`. + +@link https://stackoverflow.com/a/49928360/1490091 + +Useful in type utilities, such as disallowing `any`s to be passed to a function. + +@example +``` +import type {IsAny} from 'type-fest'; + +const typedObject = {a: 1, b: 2} as const; +const anyObject: any = {a: 1, b: 2}; + +function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(obj: O, key: K) { + return obj[key]; +} + +const typedA = get(typedObject, 'a'); +//=> 1 + +const anyA = get(anyObject, 'a'); +//=> any +``` + +@category Type Guard +@category Utilities +*/ +export type IsAny<T> = 0 extends 1 & T ? true : false; diff --git a/node_modules/type-fest/source/is-equal.d.ts b/node_modules/type-fest/source/is-equal.d.ts new file mode 100644 index 0000000..5a8a39b --- /dev/null +++ b/node_modules/type-fest/source/is-equal.d.ts @@ -0,0 +1,31 @@ +/** +Returns a boolean for whether the two given types are equal. + +@link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650 +@link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796 + +Use-cases: +- If you want to make a conditional branch based on the result of a comparison of two types. + +@example +``` +import type {IsEqual} from 'type-fest'; + +// This type returns a boolean for whether the given array includes the given item. +// `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal. +type Includes<Value extends readonly any[], Item> = + Value extends readonly [Value[0], ...infer rest] + ? IsEqual<Value[0], Item> extends true + ? true + : Includes<rest, Item> + : false; +``` + +@category Type Guard +@category Utilities +*/ +export type IsEqual<A, B> = + (<G>() => G extends A ? 1 : 2) extends + (<G>() => G extends B ? 1 : 2) + ? true + : false; diff --git a/node_modules/type-fest/source/is-literal.d.ts b/node_modules/type-fest/source/is-literal.d.ts new file mode 100644 index 0000000..a9e4c68 --- /dev/null +++ b/node_modules/type-fest/source/is-literal.d.ts @@ -0,0 +1,253 @@ +import type {Primitive} from './primitive'; +import type {Numeric} from './numeric'; +import type {IsNotFalse} from './internal'; +import type {IsNever} from './is-never'; + +/** +Returns a boolean for whether the given type `T` is the specified `LiteralType`. + +@link https://stackoverflow.com/a/52806744/10292952 + +@example +``` +LiteralCheck<1, number> +//=> true + +LiteralCheck<number, number> +//=> false + +LiteralCheck<1, string> +//=> false +``` +*/ +type LiteralCheck<T, LiteralType extends Primitive> = ( + IsNever<T> extends false // Must be wider than `never` + ? [T] extends [LiteralType] // Must be narrower than `LiteralType` + ? [LiteralType] extends [T] // Cannot be wider than `LiteralType` + ? false + : true + : false + : false +); + +/** +Returns a boolean for whether the given type `T` is one of the specified literal types in `LiteralUnionType`. + +@example +``` +LiteralChecks<1, Numeric> +//=> true + +LiteralChecks<1n, Numeric> +//=> true + +LiteralChecks<bigint, Numeric> +//=> false +``` +*/ +type LiteralChecks<T, LiteralUnionType> = ( + // Conditional type to force union distribution. + // If `T` is none of the literal types in the union `LiteralUnionType`, then `LiteralCheck<T, LiteralType>` will evaluate to `false` for the whole union. + // If `T` is one of the literal types in the union, it will evaluate to `boolean` (i.e. `true | false`) + IsNotFalse<LiteralUnionType extends Primitive + ? LiteralCheck<T, LiteralUnionType> + : never + > +); + +/** +Returns a boolean for whether the given type is a `string` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). + +Useful for: + - providing strongly-typed string manipulation functions + - constraining strings to be a string literal + - type utilities, such as when constructing parsers and ASTs + +@example +``` +import type {IsStringLiteral} from 'type-fest'; + +type CapitalizedString<T extends string> = IsStringLiteral<T> extends true ? Capitalize<T> : string; + +// https://github.com/yankeeinlondon/native-dash/blob/master/src/capitalize.ts +function capitalize<T extends Readonly<string>>(input: T): CapitalizedString<T> { + return (input.slice(0, 1).toUpperCase() + input.slice(1)) as CapitalizedString<T>; +} + +const output = capitalize('hello, world!'); +//=> 'Hello, world!' +``` + +@category Type Guard +@category Utilities +*/ +export type IsStringLiteral<T> = LiteralCheck<T, string>; + +/** +Returns a boolean for whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). + +Useful for: + - providing strongly-typed functions when given literal arguments + - type utilities, such as when constructing parsers and ASTs + +@example +``` +import type {IsNumericLiteral} from 'type-fest'; + +// https://github.com/inocan-group/inferred-types/blob/master/src/types/boolean-logic/EndsWith.ts +type EndsWith<TValue, TEndsWith extends string> = + TValue extends string + ? IsStringLiteral<TEndsWith> extends true + ? IsStringLiteral<TValue> extends true + ? TValue extends `${string}${TEndsWith}` + ? true + : false + : boolean + : boolean + : TValue extends number + ? IsNumericLiteral<TValue> extends true + ? EndsWith<`${TValue}`, TEndsWith> + : false + : false; + +function endsWith<Input extends string | number, End extends string>(input: Input, end: End) { + return `${input}`.endsWith(end) as EndsWith<Input, End>; +} + +endsWith('abc', 'c'); +//=> true + +endsWith(123456, '456'); +//=> true + +const end = '123' as string; + +endsWith('abc123', end); +//=> boolean +``` + +@category Type Guard +@category Utilities +*/ +export type IsNumericLiteral<T> = LiteralChecks<T, Numeric>; + +/** +Returns a boolean for whether the given type is a `true` or `false` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). + +Useful for: + - providing strongly-typed functions when given literal arguments + - type utilities, such as when constructing parsers and ASTs + +@example +``` +import type {IsBooleanLiteral} from 'type-fest'; + +const id = 123; + +type GetId<AsString extends boolean> = + IsBooleanLiteral<AsString> extends true + ? AsString extends true + ? `${typeof id}` + : typeof id + : number | string; + +function getId<AsString extends boolean = false>(options?: {asString: AsString}) { + return (options?.asString ? `${id}` : id) as GetId<AsString>; +} + +const numberId = getId(); +//=> 123 + +const stringId = getId({asString: true}); +//=> '123' + +declare const runtimeBoolean: boolean; +const eitherId = getId({asString: runtimeBoolean}); +//=> number | string +``` + +@category Type Guard +@category Utilities +*/ +export type IsBooleanLiteral<T> = LiteralCheck<T, boolean>; + +/** +Returns a boolean for whether the given type is a `symbol` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). + +Useful for: + - providing strongly-typed functions when given literal arguments + - type utilities, such as when constructing parsers and ASTs + +@example +``` +import type {IsSymbolLiteral} from 'type-fest'; + +type Get<Obj extends Record<symbol, number>, Key extends keyof Obj> = + IsSymbolLiteral<Key> extends true + ? Obj[Key] + : number; + +function get<Obj extends Record<symbol, number>, Key extends keyof Obj>(o: Obj, key: Key) { + return o[key] as Get<Obj, Key>; +} + +const symbolLiteral = Symbol('literal'); +const symbolValue: symbol = Symbol('value'); + +get({[symbolLiteral]: 1} as const, symbolLiteral); +//=> 1 + +get({[symbolValue]: 1} as const, symbolValue); +//=> number +``` + +@category Type Guard +@category Utilities +*/ +export type IsSymbolLiteral<T> = LiteralCheck<T, symbol>; + +/** Helper type for `IsLiteral`. */ +type IsLiteralUnion<T> = + | IsStringLiteral<T> + | IsNumericLiteral<T> + | IsBooleanLiteral<T> + | IsSymbolLiteral<T>; + +/** +Returns a boolean for whether the given type is a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). + +Useful for: + - providing strongly-typed functions when given literal arguments + - type utilities, such as when constructing parsers and ASTs + +@example +``` +import type {IsLiteral} from 'type-fest'; + +// https://github.com/inocan-group/inferred-types/blob/master/src/types/string-literals/StripLeading.ts +export type StripLeading<A, B> = + A extends string + ? B extends string + ? IsLiteral<A> extends true + ? string extends B ? never : A extends `${B & string}${infer After}` ? After : A + : string + : A + : A; + +function stripLeading<Input extends string, Strip extends string>(input: Input, strip: Strip) { + return input.replace(`^${strip}`, '') as StripLeading<Input, Strip>; +} + +stripLeading('abc123', 'abc'); +//=> '123' + +const str = 'abc123' as string; + +stripLeading(str, 'abc'); +//=> string +``` + +@category Type Guard +@category Utilities +*/ +export type IsLiteral<T extends Primitive> = IsNotFalse<IsLiteralUnion<T>>; diff --git a/node_modules/type-fest/source/is-never.d.ts b/node_modules/type-fest/source/is-never.d.ts new file mode 100644 index 0000000..740ddc4 --- /dev/null +++ b/node_modules/type-fest/source/is-never.d.ts @@ -0,0 +1,49 @@ +/** +Returns a boolean for whether the given type is `never`. + +@link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919 +@link https://stackoverflow.com/a/53984913/10292952 +@link https://www.zhenghao.io/posts/ts-never + +Useful in type utilities, such as checking if something does not occur. + +@example +``` +import type {IsNever} from 'type-fest'; + +type And<A, B> = + A extends true + ? B extends true + ? true + : false + : false; + +// https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts +type AreStringsEqual<A extends string, B extends string> = + And< + IsNever<Exclude<A, B>> extends true ? true : false, + IsNever<Exclude<B, A>> extends true ? true : false + >; + +type EndIfEqual<I extends string, O extends string> = + AreStringsEqual<I, O> extends true + ? never + : void; + +function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> { + if (input === output) { + process.exit(0); + } +} + +endIfEqual('abc', 'abc'); +//=> never + +endIfEqual('abc', '123'); +//=> void +``` + +@category Type Guard +@category Utilities +*/ +export type IsNever<T> = [T] extends [never] ? true : false; diff --git a/node_modules/type-fest/source/is-unknown.d.ts b/node_modules/type-fest/source/is-unknown.d.ts new file mode 100644 index 0000000..eef4afd --- /dev/null +++ b/node_modules/type-fest/source/is-unknown.d.ts @@ -0,0 +1,52 @@ +import type {IsNull} from './internal'; + +/** +Returns a boolean for whether the given type is `unknown`. + +@link https://github.com/dsherret/conditional-type-checks/pull/16 + +Useful in type utilities, such as when dealing with unknown data from API calls. + +@example +``` +import type {IsUnknown} from 'type-fest'; + +// https://github.com/pajecawav/tiny-global-store/blob/master/src/index.ts +type Action<TState, TPayload = void> = + IsUnknown<TPayload> extends true + ? (state: TState) => TState, + : (state: TState, payload: TPayload) => TState; + +class Store<TState> { + constructor(private state: TState) {} + + execute<TPayload = void>(action: Action<TState, TPayload>, payload?: TPayload): TState { + this.state = action(this.state, payload); + return this.state; + } + + // ... other methods +} + +const store = new Store({value: 1}); +declare const someExternalData: unknown; + +store.execute(state => ({value: state.value + 1})); +//=> `TPayload` is `void` + +store.execute((state, payload) => ({value: state.value + payload}), 5); +//=> `TPayload` is `5` + +store.execute((state, payload) => ({value: state.value + payload}), someExternalData); +//=> Errors: `action` is `(state: TState) => TState` +``` + +@category Utilities +*/ +export type IsUnknown<T> = ( + unknown extends T // `T` can be `unknown` or `any` + ? IsNull<T> extends false // `any` can be `null`, but `unknown` can't be + ? true + : false + : false +); diff --git a/node_modules/type-fest/source/iterable-element.d.ts b/node_modules/type-fest/source/iterable-element.d.ts new file mode 100644 index 0000000..57261fa --- /dev/null +++ b/node_modules/type-fest/source/iterable-element.d.ts @@ -0,0 +1,54 @@ +/** +Get the element type of an `Iterable`/`AsyncIterable`. For example, an array or a generator. + +This can be useful, for example, if you want to get the type that is yielded in a generator function. Often the return type of those functions are not specified. + +This type works with both `Iterable`s and `AsyncIterable`s, so it can be use with synchronous and asynchronous generators. + +Here is an example of `IterableElement` in action with a generator function: + +@example +``` +import type {IterableElement} from 'type-fest'; + +function * iAmGenerator() { + yield 1; + yield 2; +} + +type MeNumber = IterableElement<ReturnType<typeof iAmGenerator>> +``` + +And here is an example with an async generator: + +@example +``` +import type {IterableElement} from 'type-fest'; + +async function * iAmGeneratorAsync() { + yield 'hi'; + yield true; +} + +type MeStringOrBoolean = IterableElement<ReturnType<typeof iAmGeneratorAsync>> +``` + +Many types in JavaScript/TypeScript are iterables. This type works on all types that implement those interfaces. For example, `Array`, `Set`, `Map`, `stream.Readable`, etc. + +An example with an array of strings: + +@example +``` +import type {IterableElement} from 'type-fest'; + +type MeString = IterableElement<string[]> +``` + +@category Iterable +*/ +export type IterableElement<TargetIterable> = + TargetIterable extends Iterable<infer ElementType> ? + ElementType : + TargetIterable extends AsyncIterable<infer ElementType> ? + ElementType : + never; diff --git a/node_modules/type-fest/source/join.d.ts b/node_modules/type-fest/source/join.d.ts new file mode 100644 index 0000000..3418362 --- /dev/null +++ b/node_modules/type-fest/source/join.d.ts @@ -0,0 +1,68 @@ +// The builtin `join` method supports all these natively in the same way that typescript handles them so we can safely accept all of them. +type JoinableItem = string | number | bigint | boolean | undefined | null; + +// `null` and `undefined` are treated uniquely in the built-in join method, in a way that differs from the default `toString` that would result in the type `${undefined}`. That's why we need to handle it specifically with this helper. +// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join#description +type NullishCoalesce< + Value extends JoinableItem, + Fallback extends string, +> = Value extends undefined | null ? NonNullable<Value> | Fallback : Value; + +/** +Join an array of strings and/or numbers using the given string as a delimiter. + +Use-case: Defining key paths in a nested object. For example, for dot-notation fields in MongoDB queries. + +@example +``` +import type {Join} from 'type-fest'; + +// Mixed (strings & numbers) items; result is: 'foo.0.baz' +const path: Join<['foo', 0, 'baz'], '.'> = ['foo', 0, 'baz'].join('.'); + +// Only string items; result is: 'foo.bar.baz' +const path: Join<['foo', 'bar', 'baz'], '.'> = ['foo', 'bar', 'baz'].join('.'); + +// Only number items; result is: '1.2.3' +const path: Join<[1, 2, 3], '.'> = [1, 2, 3].join('.'); + +// Only bigint items; result is '1.2.3' +const path: Join<[1n, 2n, 3n], '.'> = [1n, 2n, 3n].join('.'); + +// Only boolean items; result is: 'true.false.true' +const path: Join<[true, false, true], '.'> = [true, false, true].join('.'); + +// Contains nullish items; result is: 'foo..baz..xyz' +const path: Join<['foo', undefined, 'baz', null, 'xyz'], '.'> = ['foo', undefined, 'baz', null, 'xyz'].join('.'); + +// Partial tuple shapes (rest param last); result is: `prefix.${string}` +const path: Join<['prefix', ...string[]], '.'> = ['prefix'].join('.'); + +// Partial tuple shapes (rest param first); result is: `${string}.suffix` +const path: Join<[...string[], 'suffix'], '.'> = ['suffix'].join('.'); + +// Tuples items with nullish unions; result is '.' | 'hello.' | '.world' | 'hello.world' +const path: Join<['hello' | undefined, 'world' | null], '.'> = ['hello', 'world'].join('.'); +``` + +@category Array +@category Template literal +*/ +export type Join< + Items extends readonly JoinableItem[], + Delimiter extends string, +> = Items extends [] + ? '' + : Items extends readonly [JoinableItem?] + ? `${NullishCoalesce<Items[0], ''>}` + : Items extends readonly [ + infer First extends JoinableItem, + ...infer Tail extends readonly JoinableItem[], + ] + ? `${NullishCoalesce<First, ''>}${Delimiter}${Join<Tail, Delimiter>}` + : Items extends readonly [ + ...infer Head extends readonly JoinableItem[], + infer Last extends JoinableItem, + ] + ? `${Join<Head, Delimiter>}${Delimiter}${NullishCoalesce<Last, ''>}` + : string; diff --git a/node_modules/type-fest/source/jsonifiable.d.ts b/node_modules/type-fest/source/jsonifiable.d.ts new file mode 100644 index 0000000..49e7b1a --- /dev/null +++ b/node_modules/type-fest/source/jsonifiable.d.ts @@ -0,0 +1,37 @@ +import type {JsonPrimitive, JsonValue} from './basic'; + +type JsonifiableObject = {[Key in string]?: Jsonifiable} | {toJSON: () => Jsonifiable}; +type JsonifiableArray = readonly Jsonifiable[]; + +/** +Matches a value that can be losslessly converted to JSON. + +Can be used to type values that you expect to pass to `JSON.stringify`. + +`undefined` is allowed in object fields (for example, `{a?: number}`) as a special case even though `JSON.stringify({a: undefined})` is `{}` because it makes this class more widely useful and checking for undefined-but-present values is likely an anti-pattern. + +@example +``` +import type {Jsonifiable} from 'type-fest'; + +// @ts-expect-error +const error: Jsonifiable = { + map: new Map([['a', 1]]), +}; + +JSON.stringify(error); +//=> {"map": {}} + +const good: Jsonifiable = { + number: 3, + date: new Date(), + missing: undefined, +} + +JSON.stringify(good); +//=> {"number": 3, "date": "2022-10-17T22:22:35.920Z"} +``` + +@category JSON +*/ +export type Jsonifiable = JsonPrimitive | JsonifiableObject | JsonifiableArray; diff --git a/node_modules/type-fest/source/jsonify.d.ts b/node_modules/type-fest/source/jsonify.d.ts new file mode 100644 index 0000000..a903905 --- /dev/null +++ b/node_modules/type-fest/source/jsonify.d.ts @@ -0,0 +1,115 @@ +import type {JsonPrimitive, JsonValue} from './basic'; +import type {EmptyObject} from './empty-object'; +import type {UndefinedToOptional} from './internal'; +import type {NegativeInfinity, PositiveInfinity} from './numeric'; +import type {TypedArray} from './typed-array'; +import type {IsAny} from './is-any'; + +// Note: The return value has to be `any` and not `unknown` so it can match `void`. +type NotJsonable = ((...arguments_: any[]) => any) | undefined | symbol; + +type JsonifyTuple<T extends [unknown, ...unknown[]]> = { + [Key in keyof T]: T[Key] extends NotJsonable ? null : Jsonify<T[Key]>; +}; + +type FilterJsonableKeys<T extends object> = { + [Key in keyof T]: T[Key] extends NotJsonable ? never : Key; +}[keyof T]; + +/** +JSON serialize objects (not including arrays) and classes. +*/ +type JsonifyObject<T extends object> = { + [Key in keyof Pick<T, FilterJsonableKeys<T>>]: Jsonify<T[Key]>; +}; + +/** +Transform a type to one that is assignable to the `JsonValue` type. + +This includes: +1. Transforming JSON `interface` to a `type` that is assignable to `JsonValue`. +2. Transforming non-JSON value that is *jsonable* to a type that is assignable to `JsonValue`, where *jsonable* means the non-JSON value implements the `.toJSON()` method that returns a value that is assignable to `JsonValue`. + +@remarks + +An interface cannot be structurally compared to `JsonValue` because an interface can be re-opened to add properties that may not be satisfy `JsonValue`. + +@example +``` +import type {Jsonify, JsonValue} from 'type-fest'; + +interface Geometry { + type: 'Point' | 'Polygon'; + coordinates: [number, number]; +} + +const point: Geometry = { + type: 'Point', + coordinates: [1, 1] +}; + +const problemFn = (data: JsonValue) => { + // Does something with data +}; + +problemFn(point); // Error: type Geometry is not assignable to parameter of type JsonValue because it is an interface + +const fixedFn = <T>(data: Jsonify<T>) => { + // Does something with data +}; + +fixedFn(point); // Good: point is assignable. Jsonify<T> transforms Geometry into value assignable to JsonValue +fixedFn(new Date()); // Error: As expected, Date is not assignable. Jsonify<T> cannot transforms Date into value assignable to JsonValue +``` + +Non-JSON values such as `Date` implement `.toJSON()`, so they can be transformed to a value assignable to `JsonValue`: + +@example +``` +import type {Jsonify} from 'type-fest'; + +const time = { + timeValue: new Date() +}; + +// `Jsonify<typeof time>` is equivalent to `{timeValue: string}` +const timeJson = JSON.parse(JSON.stringify(time)) as Jsonify<typeof time>; +``` + +@link https://github.com/Microsoft/TypeScript/issues/1897#issuecomment-710744173 + +@category JSON +*/ +export type Jsonify<T> = IsAny<T> extends true + ? any + : T extends PositiveInfinity | NegativeInfinity + ? null + : T extends JsonPrimitive + ? T + : // Instanced primitives are objects + T extends Number + ? number + : T extends String + ? string + : T extends Boolean + ? boolean + : T extends Map<any, any> | Set<any> + ? EmptyObject + : T extends TypedArray + ? Record<string, number> + : T extends NotJsonable + ? never // Non-JSONable type union was found not empty + : // Any object with toJSON is special case + T extends {toJSON(): infer J} + ? (() => J) extends () => JsonValue // Is J assignable to JsonValue? + ? J // Then T is Jsonable and its Jsonable value is J + : Jsonify<J> // Maybe if we look a level deeper we'll find a JsonValue + : T extends [] + ? [] + : T extends [unknown, ...unknown[]] + ? JsonifyTuple<T> + : T extends ReadonlyArray<infer U> + ? Array<U extends NotJsonable ? null : Jsonify<U>> + : T extends object + ? JsonifyObject<UndefinedToOptional<T>> // JsonifyObject recursive call for its children + : never; // Otherwise any other non-object is removed diff --git a/node_modules/type-fest/source/kebab-case.d.ts b/node_modules/type-fest/source/kebab-case.d.ts new file mode 100644 index 0000000..f6dc6cc --- /dev/null +++ b/node_modules/type-fest/source/kebab-case.d.ts @@ -0,0 +1,38 @@ +import type {DelimiterCase} from './delimiter-case'; + +/** +Convert a string literal to kebab-case. + +This can be useful when, for example, converting a camel-cased object property to a kebab-cased CSS class name or a command-line flag. + +@example +``` +import type {KebabCase} from 'type-fest'; + +// Simple + +const someVariable: KebabCase<'fooBar'> = 'foo-bar'; + +// Advanced + +type KebabCasedProperties<T> = { + [K in keyof T as KebabCase<K>]: T[K] +}; + +interface CliOptions { + dryRun: boolean; + includeFile: string; + foo: number; +} + +const rawCliOptions: KebabCasedProperties<CliOptions> = { + 'dry-run': true, + 'include-file': 'bar.js', + foo: 123 +}; +``` + +@category Change case +@category Template literal +*/ +export type KebabCase<Value> = DelimiterCase<Value, '-'>; diff --git a/node_modules/type-fest/source/kebab-cased-properties-deep.d.ts b/node_modules/type-fest/source/kebab-cased-properties-deep.d.ts new file mode 100644 index 0000000..d524c52 --- /dev/null +++ b/node_modules/type-fest/source/kebab-cased-properties-deep.d.ts @@ -0,0 +1,47 @@ +import type {DelimiterCasedPropertiesDeep} from './delimiter-cased-properties-deep'; + +/** +Convert object properties to kebab case recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see KebabCase +@see KebabCasedProperties + +@example +``` +import type [KebabCasedPropertiesDeep] from 'type-fest'; + +interface User { + userId: number; + userName: string; +} + +interface UserWithFriends { + userInfo: User; + userFriends: User[]; +} + +const result: KebabCasedPropertiesDeep<UserWithFriends> = { + 'user-info': { + 'user-id': 1, + 'user-name': 'Tom', + }, + 'user-friends': [ + { + 'user-id': 2, + 'user-name': 'Jerry', + }, + { + 'user-id': 3, + 'user-name': 'Spike', + }, + ], +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type KebabCasedPropertiesDeep<Value> = DelimiterCasedPropertiesDeep<Value, '-'>; diff --git a/node_modules/type-fest/source/kebab-cased-properties.d.ts b/node_modules/type-fest/source/kebab-cased-properties.d.ts new file mode 100644 index 0000000..2260ace --- /dev/null +++ b/node_modules/type-fest/source/kebab-cased-properties.d.ts @@ -0,0 +1,30 @@ +import type {DelimiterCasedProperties} from './delimiter-cased-properties'; + +/** +Convert object properties to kebab case but not recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see KebabCase +@see KebabCasedPropertiesDeep + +@example +``` +import type {KebabCasedProperties} from 'type-fest'; + +interface User { + userId: number; + userName: string; +} + +const result: KebabCasedProperties<User> = { + 'user-id': 1, + 'user-name': 'Tom', +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type KebabCasedProperties<Value> = DelimiterCasedProperties<Value, '-'>; diff --git a/node_modules/type-fest/source/last-array-element.d.ts b/node_modules/type-fest/source/last-array-element.d.ts new file mode 100644 index 0000000..3110ee2 --- /dev/null +++ b/node_modules/type-fest/source/last-array-element.d.ts @@ -0,0 +1,28 @@ +/** +Extracts the type of the last element of an array. + +Use-case: Defining the return type of functions that extract the last element of an array, for example [`lodash.last`](https://lodash.com/docs/4.17.15#last). + +@example +``` +import type {LastArrayElement} from 'type-fest'; + +declare function lastOf<V extends readonly any[]>(array: V): LastArrayElement<V>; + +const array = ['foo', 2]; + +typeof lastOf(array); +//=> number +``` + +@category Array +@category Template literal +*/ +export type LastArrayElement<ValueType extends readonly unknown[]> = + ValueType extends readonly [infer ElementType] + ? ElementType + : ValueType extends readonly [infer _, ...infer Tail] + ? LastArrayElement<Tail> + : ValueType extends ReadonlyArray<infer ElementType> + ? ElementType + : never; diff --git a/node_modules/type-fest/source/literal-to-primitive-deep.d.ts b/node_modules/type-fest/source/literal-to-primitive-deep.d.ts new file mode 100644 index 0000000..e36ff04 --- /dev/null +++ b/node_modules/type-fest/source/literal-to-primitive-deep.d.ts @@ -0,0 +1,36 @@ +import type {LiteralToPrimitive} from './literal-to-primitive'; +import type {OmitIndexSignature} from './omit-index-signature'; + +/** +Like `LiteralToPrimitive` except it converts literal types inside an object or array deeply. + +For example, given a constant object, it returns a new object type with the same keys but with all the values converted to primitives. + +@see LiteralToPrimitive + +Use-case: Deal with data that is imported from a JSON file. + +@example +``` +import type {LiteralToPrimitiveDeep, TsConfigJson} from 'type-fest'; +import tsconfig from 'path/to/tsconfig.json'; + +function doSomethingWithTSConfig(config: LiteralToPrimitiveDeep<TsConfigJson>) { ... } + +// No casting is needed to pass the type check +doSomethingWithTSConfig(tsconfig); + +// If LiteralToPrimitiveDeep is not used, you need to cast the imported data like this: +doSomethingWithTSConfig(tsconfig as TsConfigJson); +``` + +@category Type +@category Object +*/ +export type LiteralToPrimitiveDeep<T> = T extends object + ? T extends Array<infer U> + ? Array<LiteralToPrimitiveDeep<U>> + : { + [K in keyof OmitIndexSignature<T>]: LiteralToPrimitiveDeep<T[K]>; + } + : LiteralToPrimitive<T>; diff --git a/node_modules/type-fest/source/literal-to-primitive.d.ts b/node_modules/type-fest/source/literal-to-primitive.d.ts new file mode 100644 index 0000000..7e037ec --- /dev/null +++ b/node_modules/type-fest/source/literal-to-primitive.d.ts @@ -0,0 +1,36 @@ +/** +Given a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) return the {@link Primitive | primitive type} it belongs to, or `never` if it's not a primitive. + +Use-case: Working with generic types that may be literal types. + +@example +``` +import type {LiteralToPrimitive} from 'type-fest'; + +// No overloads needed to get the correct return type +function plus<T extends number | bigint | string>(x: T, y: T): LiteralToPrimitive<T> { + return x + (y as any); +} + +plus('a', 'b'); // string +plus(1, 2); // number +plus(1n, 2n); // bigint +``` + +@category Type +*/ +export type LiteralToPrimitive<T> = T extends number + ? number + : T extends bigint + ? bigint + : T extends string + ? string + : T extends boolean + ? boolean + : T extends symbol + ? symbol + : T extends null + ? null + : T extends undefined + ? undefined + : never; diff --git a/node_modules/type-fest/source/literal-union.d.ts b/node_modules/type-fest/source/literal-union.d.ts new file mode 100644 index 0000000..ffd6b90 --- /dev/null +++ b/node_modules/type-fest/source/literal-union.d.ts @@ -0,0 +1,35 @@ +import type {Primitive} from './primitive'; + +/** +Allows creating a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union. + +Currently, when a union type of a primitive type is combined with literal types, TypeScript loses all information about the combined literals. Thus, when such type is used in an IDE with autocompletion, no suggestions are made for the declared literals. + +This type is a workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729). It will be removed as soon as it's not needed anymore. + +@example +``` +import type {LiteralUnion} from 'type-fest'; + +// Before + +type Pet = 'dog' | 'cat' | string; + +const pet: Pet = ''; +// Start typing in your TypeScript-enabled IDE. +// You **will not** get auto-completion for `dog` and `cat` literals. + +// After + +type Pet2 = LiteralUnion<'dog' | 'cat', string>; + +const pet: Pet2 = ''; +// You **will** get auto-completion for `dog` and `cat` literals. +``` + +@category Type +*/ +export type LiteralUnion< + LiteralType, + BaseType extends Primitive, +> = LiteralType | (BaseType & Record<never, never>); diff --git a/node_modules/type-fest/source/merge-deep.d.ts b/node_modules/type-fest/source/merge-deep.d.ts new file mode 100644 index 0000000..19e2684 --- /dev/null +++ b/node_modules/type-fest/source/merge-deep.d.ts @@ -0,0 +1,470 @@ +import type {ConditionalSimplifyDeep} from './conditional-simplify'; +import type {OmitIndexSignature} from './omit-index-signature'; +import type {PickIndexSignature} from './pick-index-signature'; +import type {EnforceOptional} from './enforce-optional'; +import type {Merge} from './merge'; +import type { + ArrayTail, + FirstArrayElement, + IsBothExtends, + NonEmptyTuple, + UnknownArrayOrTuple, + UnknownRecord, +} from './internal'; + +/** +Deeply simplifies an object excluding iterables and functions. Used internally to improve the UX and accept both interfaces and type aliases as inputs. +*/ +type SimplifyDeep<Type> = ConditionalSimplifyDeep<Type, Function | Iterable<unknown>, object>; + +/** +Try to merge two record properties or return the source property value, preserving `undefined` properties values in both cases. +*/ +type MergeDeepRecordProperty< + Destination, + Source, + Options extends MergeDeepInternalOptions, +> = undefined extends Source + ? MergeDeepOrReturn<Source, Exclude<Destination, undefined>, Exclude<Source, undefined>, Options> | undefined + : MergeDeepOrReturn<Source, Destination, Source, Options>; + +/** +Walk through the union of the keys of the two objects and test in which object the properties are defined. +- If the source does not contain the key, the value of the destination is returned. +- If the source contains the key and the destination does not contain the key, the value of the source is returned. +- If both contain the key, try to merge according to the chosen {@link MergeDeepOptions options} or return the source if unable to merge. +*/ +type DoMergeDeepRecord< + Destination extends UnknownRecord, + Source extends UnknownRecord, + Options extends MergeDeepInternalOptions, +> = EnforceOptional<{ + [Key in keyof Destination | keyof Source]: Key extends keyof Source + ? Key extends keyof Destination + ? MergeDeepRecordProperty<Destination[Key], Source[Key], Options> + : Source[Key] + : Key extends keyof Destination + ? Destination[Key] + : never; +}>; + +/** +Wrapper around {@link DoMergeDeepRecord} which preserves index signatures. +*/ +type MergeDeepRecord< + Destination extends UnknownRecord, + Source extends UnknownRecord, + Options extends MergeDeepInternalOptions, +> = DoMergeDeepRecord<OmitIndexSignature<Destination>, OmitIndexSignature<Source>, Options> +& Merge<PickIndexSignature<Destination>, PickIndexSignature<Source>>; + +/** +Pick the rest type. + +@example +``` +type Rest1 = PickRestType<[]>; // => [] +type Rest2 = PickRestType<[string]>; // => [] +type Rest3 = PickRestType<[...number[]]>; // => number[] +type Rest4 = PickRestType<[string, ...number[]]>; // => number[] +type Rest5 = PickRestType<string[]>; // => string[] +``` +*/ +type PickRestType<Type extends UnknownArrayOrTuple> = number extends Type['length'] + ? ArrayTail<Type> extends [] ? Type : PickRestType<ArrayTail<Type>> + : []; + +/** +Omit the rest type. + +@example +``` +type Tuple1 = OmitRestType<[]>; // => [] +type Tuple2 = OmitRestType<[string]>; // => [string] +type Tuple3 = OmitRestType<[...number[]]>; // => [] +type Tuple4 = OmitRestType<[string, ...number[]]>; // => [string] +type Tuple5 = OmitRestType<[string, boolean[], ...number[]]>; // => [string, boolean[]] +type Tuple6 = OmitRestType<string[]>; // => [] +``` +*/ +type OmitRestType<Type extends UnknownArrayOrTuple, Result extends UnknownArrayOrTuple = []> = number extends Type['length'] + ? ArrayTail<Type> extends [] ? Result : OmitRestType<ArrayTail<Type>, [...Result, FirstArrayElement<Type>]> + : Type; + +// Utility to avoid picking two times the type. +type TypeNumberOrType<Type extends UnknownArrayOrTuple> = Type[number] extends never ? Type : Type[number]; + +// Pick the rest type (array) and try to get the intrinsic type or return the provided type. +type PickRestTypeFlat<Type extends UnknownArrayOrTuple> = TypeNumberOrType<PickRestType<Type>>; + +/** +Try to merge two array/tuple elements or return the source element if the end of the destination is reached or vis-versa. +*/ +type MergeDeepArrayOrTupleElements< + Destination, + Source, + Options extends MergeDeepInternalOptions, +> = Source extends [] + ? Destination + : Destination extends [] + ? Source + : MergeDeepOrReturn<Source, Destination, Source, Options>; + +/** +Merge two tuples recursively. +*/ +type DoMergeDeepTupleAndTupleRecursive< + Destination extends UnknownArrayOrTuple, + Source extends UnknownArrayOrTuple, + DestinationRestType, + SourceRestType, + Options extends MergeDeepInternalOptions, +> = Destination extends [] + ? Source extends [] + ? [] + : MergeArrayTypeAndTuple<DestinationRestType, Source, Options> + : Source extends [] + ? MergeTupleAndArrayType<Destination, SourceRestType, Options> + : [ + MergeDeepArrayOrTupleElements<FirstArrayElement<Destination>, FirstArrayElement<Source>, Options>, + ...DoMergeDeepTupleAndTupleRecursive<ArrayTail<Destination>, ArrayTail<Source>, DestinationRestType, SourceRestType, Options>, + ]; + +/** +Merge two tuples recursively taking into account a possible rest element. +*/ +type MergeDeepTupleAndTupleRecursive< + Destination extends UnknownArrayOrTuple, + Source extends UnknownArrayOrTuple, + Options extends MergeDeepInternalOptions, +> = [ + ...DoMergeDeepTupleAndTupleRecursive<OmitRestType<Destination>, OmitRestType<Source>, PickRestTypeFlat<Destination>, PickRestTypeFlat<Source>, Options>, + ...MergeDeepArrayOrTupleElements<PickRestType<Destination>, PickRestType<Source>, Options>, +]; + +/** +Merge an array type with a tuple recursively. +*/ +type MergeTupleAndArrayType< + Tuple extends UnknownArrayOrTuple, + ArrayType, + Options extends MergeDeepInternalOptions, +> = Tuple extends [] + ? Tuple + : [ + MergeDeepArrayOrTupleElements<FirstArrayElement<Tuple>, ArrayType, Options>, + ...MergeTupleAndArrayType<ArrayTail<Tuple>, ArrayType, Options>, + ]; + +/** +Merge an array into a tuple recursively taking into account a possible rest element. +*/ +type MergeDeepTupleAndArrayRecursive< + Destination extends UnknownArrayOrTuple, + Source extends UnknownArrayOrTuple, + Options extends MergeDeepInternalOptions, +> = [ + ...MergeTupleAndArrayType<OmitRestType<Destination>, Source[number], Options>, + ...MergeDeepArrayOrTupleElements<PickRestType<Destination>, PickRestType<Source>, Options>, +]; + +/** +Merge a tuple with an array type recursively. +*/ +type MergeArrayTypeAndTuple< + ArrayType, + Tuple extends UnknownArrayOrTuple, + Options extends MergeDeepInternalOptions, +> = Tuple extends [] + ? Tuple + : [ + MergeDeepArrayOrTupleElements<ArrayType, FirstArrayElement<Tuple>, Options>, + ...MergeArrayTypeAndTuple<ArrayType, ArrayTail<Tuple>, Options>, + ]; + +/** +Merge a tuple into an array recursively taking into account a possible rest element. +*/ +type MergeDeepArrayAndTupleRecursive< + Destination extends UnknownArrayOrTuple, + Source extends UnknownArrayOrTuple, + Options extends MergeDeepInternalOptions, +> = [ + ...MergeArrayTypeAndTuple<Destination[number], OmitRestType<Source>, Options>, + ...MergeDeepArrayOrTupleElements<PickRestType<Destination>, PickRestType<Source>, Options>, +]; + +/** +Merge mode for array/tuple elements. +*/ +type ArrayMergeMode = 'spread' | 'replace'; + +/** +Test if it should spread top-level arrays. +*/ +type ShouldSpread<Options extends MergeDeepInternalOptions> = Options['spreadTopLevelArrays'] extends false + ? Options['arrayMergeMode'] extends 'spread' ? true : false + : true; + +/** +Merge two arrays/tuples according to the chosen {@link MergeDeepOptions.arrayMergeMode arrayMergeMode} option. +*/ +type DoMergeArrayOrTuple< + Destination extends UnknownArrayOrTuple, + Source extends UnknownArrayOrTuple, + Options extends MergeDeepInternalOptions, +> = ShouldSpread<Options> extends true + ? Array<Exclude<Destination, undefined>[number] | Exclude<Source, undefined>[number]> + : Source; // 'replace' + +/** +Merge two arrays recursively. + +If the two arrays are multi-level, we merge deeply, otherwise we merge the first level only. + +Note: The `[number]` accessor is used to test the type of the second level. +*/ +type MergeDeepArrayRecursive< + Destination extends UnknownArrayOrTuple, + Source extends UnknownArrayOrTuple, + Options extends MergeDeepInternalOptions, +> = Destination[number] extends UnknownArrayOrTuple + ? Source[number] extends UnknownArrayOrTuple + ? Array<MergeDeepArrayOrTupleRecursive<Destination[number], Source[number], Options>> + : DoMergeArrayOrTuple<Destination, Source, Options> + : Destination[number] extends UnknownRecord + ? Source[number] extends UnknownRecord + ? Array<SimplifyDeep<MergeDeepRecord<Destination[number], Source[number], Options>>> + : DoMergeArrayOrTuple<Destination, Source, Options> + : DoMergeArrayOrTuple<Destination, Source, Options>; + +/** +Merge two array/tuple recursively by selecting one of the four strategies according to the type of inputs. + +- tuple/tuple +- tuple/array +- array/tuple +- array/array +*/ +type MergeDeepArrayOrTupleRecursive< + Destination extends UnknownArrayOrTuple, + Source extends UnknownArrayOrTuple, + Options extends MergeDeepInternalOptions, +> = IsBothExtends<NonEmptyTuple, Destination, Source> extends true + ? MergeDeepTupleAndTupleRecursive<Destination, Source, Options> + : Destination extends NonEmptyTuple + ? MergeDeepTupleAndArrayRecursive<Destination, Source, Options> + : Source extends NonEmptyTuple + ? MergeDeepArrayAndTupleRecursive<Destination, Source, Options> + : MergeDeepArrayRecursive<Destination, Source, Options>; + +/** +Merge two array/tuple according to {@link MergeDeepOptions.recurseIntoArrays recurseIntoArrays} option. +*/ +type MergeDeepArrayOrTuple< + Destination extends UnknownArrayOrTuple, + Source extends UnknownArrayOrTuple, + Options extends MergeDeepInternalOptions, +> = Options['recurseIntoArrays'] extends true + ? MergeDeepArrayOrTupleRecursive<Destination, Source, Options> + : DoMergeArrayOrTuple<Destination, Source, Options>; + +/** +Try to merge two objects or two arrays/tuples recursively into a new type or return the default value. +*/ +type MergeDeepOrReturn< + DefaultType, + Destination, + Source, + Options extends MergeDeepInternalOptions, +> = SimplifyDeep<[undefined] extends [Destination | Source] + ? DefaultType + : Destination extends UnknownRecord + ? Source extends UnknownRecord + ? MergeDeepRecord<Destination, Source, Options> + : DefaultType + : Destination extends UnknownArrayOrTuple + ? Source extends UnknownArrayOrTuple + ? MergeDeepArrayOrTuple<Destination, Source, Merge<Options, {spreadTopLevelArrays: false}>> + : DefaultType + : DefaultType>; + +/** +MergeDeep options. + +@see {@link MergeDeep} +*/ +export type MergeDeepOptions = { + /** + Merge mode for array and tuple. + + When we walk through the properties of the objects and the same key is found and both are array or tuple, a merge mode must be chosen: + - `replace`: Replaces the destination value by the source value. This is the default mode. + - `spread`: Spreads the destination and the source values. + + See {@link MergeDeep} for usages and examples. + + Note: Top-level arrays and tuples are always spread. + + @default 'spread' + */ + arrayMergeMode?: ArrayMergeMode; + + /** + Whether to affect the individual elements of arrays and tuples. + + If this option is set to `true` the following rules are applied: + - If the source does not contain the key, the value of the destination is returned. + - If the source contains the key and the destination does not contain the key, the value of the source is returned. + - If both contain the key, try to merge according to the chosen {@link MergeDeepOptions.arrayMergeMode arrayMergeMode} or return the source if unable to merge. + + @default false + */ + recurseIntoArrays?: boolean; +}; + +/** +Internal options. +*/ +type MergeDeepInternalOptions = Merge<MergeDeepOptions, {spreadTopLevelArrays?: boolean}>; + +/** +Merge default and internal options with user provided options. +*/ +type DefaultMergeDeepOptions<Options extends MergeDeepOptions> = Merge<{ + arrayMergeMode: 'replace'; + recurseIntoArrays: false; + spreadTopLevelArrays: true; +}, Options>; + +/** +This utility selects the correct entry point with the corresponding default options. This avoids re-merging the options at each iteration. +*/ +type MergeDeepWithDefaultOptions<Destination, Source, Options extends MergeDeepOptions> = SimplifyDeep< +[undefined] extends [Destination | Source] + ? never + : Destination extends UnknownRecord + ? Source extends UnknownRecord + ? MergeDeepRecord<Destination, Source, DefaultMergeDeepOptions<Options>> + : never + : Destination extends UnknownArrayOrTuple + ? Source extends UnknownArrayOrTuple + ? MergeDeepArrayOrTuple<Destination, Source, DefaultMergeDeepOptions<Options>> + : never + : never +>; + +/** +Merge two objects or two arrays/tuples recursively into a new type. + +- Properties that only exist in one object are copied into the new object. +- Properties that exist in both objects are merged if possible or replaced by the one of the source if not. +- Top-level arrays and tuples are always spread. +- By default, inner arrays and tuples are replaced. See {@link MergeDeepOptions.arrayMergeMode arrayMergeMode} option to change this behaviour. +- By default, individual array/tuple elements are not affected. See {@link MergeDeepOptions.recurseIntoArrays recurseIntoArrays} option to change this behaviour. + +@example +``` +import type {MergeDeep} from 'type-fest'; + +type Foo = { + life: number; + items: string[]; + a: {b: string; c: boolean; d: number[]}; +}; + +interface Bar { + name: string; + items: number[]; + a: {b: number; d: boolean[]}; +} + +type FooBar = MergeDeep<Foo, Bar>; +// { +// life: number; +// name: string; +// items: number[]; +// a: {b: number; c: boolean; d: boolean[]}; +// } + +type FooBar = MergeDeep<Foo, Bar, {arrayMergeMode: 'spread'}>; +// { +// life: number; +// name: string; +// items: (string | number)[]; +// a: {b: number; c: boolean; d: (number | boolean)[]}; +// } +``` + +@example +``` +import type {MergeDeep} from 'type-fest'; + +// Merge two arrays +type ArrayMerge = MergeDeep<string[], number[]>; // => (string | number)[] + +// Merge two tuples +type TupleMerge = MergeDeep<[1, 2, 3], ['a', 'b']>; // => (1 | 2 | 3 | 'a' | 'b')[] + +// Merge an array into a tuple +type TupleArrayMerge = MergeDeep<[1, 2, 3], string[]>; // => (string | 1 | 2 | 3)[] + +// Merge a tuple into an array +type ArrayTupleMerge = MergeDeep<number[], ['a', 'b']>; // => (number | 'b' | 'a')[] +``` + +@example +``` +import type {MergeDeep, MergeDeepOptions} from 'type-fest'; + +type Foo = {foo: 'foo'; fooBar: string[]}; +type Bar = {bar: 'bar'; fooBar: number[]}; + +type FooBar = MergeDeep<Foo, Bar>; +// { foo: "foo"; bar: "bar"; fooBar: number[]} + +type FooBarSpread = MergeDeep<Foo, Bar, {arrayMergeMode: 'spread'}>; +// { foo: "foo"; bar: "bar"; fooBar: (string | number)[]} + +type FooBarArray = MergeDeep<Foo[], Bar[]>; +// (Foo | Bar)[] + +type FooBarArrayDeep = MergeDeep<Foo[], Bar[], {recurseIntoArrays: true}>; +// FooBar[] + +type FooBarArraySpreadDeep = MergeDeep<Foo[], Bar[], {recurseIntoArrays: true; arrayMergeMode: 'spread'}>; +// FooBarSpread[] + +type FooBarTupleDeep = MergeDeep<[Foo, true, 42], [Bar, 'life'], {recurseIntoArrays: true}>; +// [FooBar, 'life', 42] + +type FooBarTupleWithArrayDeep = MergeDeep<[Foo[], true], [Bar[], 'life', 42], {recurseIntoArrays: true}>; +// [FooBar[], 'life', 42] +``` + +@example +``` +import type {MergeDeep, MergeDeepOptions} from 'type-fest'; + +function mergeDeep<Destination, Source, Options extends MergeDeepOptions = {}>( + destination: Destination, + source: Source, + options?: Options, +): MergeDeep<Destination, Source, Options> { + // Make your implementation ... +} +``` + +@experimental This type is marked as experimental because it depends on {@link ConditionalSimplifyDeep} which itself is experimental. + +@see {@link MergeDeepOptions} + +@category Array +@category Object +@category Utilities +*/ +export type MergeDeep<Destination, Source, Options extends MergeDeepOptions = {}> = MergeDeepWithDefaultOptions< +SimplifyDeep<Destination>, +SimplifyDeep<Source>, +Options +>; diff --git a/node_modules/type-fest/source/merge-exclusive.d.ts b/node_modules/type-fest/source/merge-exclusive.d.ts new file mode 100644 index 0000000..d183d67 --- /dev/null +++ b/node_modules/type-fest/source/merge-exclusive.d.ts @@ -0,0 +1,41 @@ +// Helper type. Not useful on its own. +type Without<FirstType, SecondType> = {[KeyType in Exclude<keyof FirstType, keyof SecondType>]?: never}; + +/** +Create a type that has mutually exclusive keys. + +This type was inspired by [this comment](https://github.com/Microsoft/TypeScript/issues/14094#issuecomment-373782604). + +This type works with a helper type, called `Without`. `Without<FirstType, SecondType>` produces a type that has only keys from `FirstType` which are not present on `SecondType` and sets the value type for these keys to `never`. This helper type is then used in `MergeExclusive` to remove keys from either `FirstType` or `SecondType`. + +@example +``` +import type {MergeExclusive} from 'type-fest'; + +interface ExclusiveVariation1 { + exclusive1: boolean; +} + +interface ExclusiveVariation2 { + exclusive2: string; +} + +type ExclusiveOptions = MergeExclusive<ExclusiveVariation1, ExclusiveVariation2>; + +let exclusiveOptions: ExclusiveOptions; + +exclusiveOptions = {exclusive1: true}; +//=> Works +exclusiveOptions = {exclusive2: 'hi'}; +//=> Works +exclusiveOptions = {exclusive1: true, exclusive2: 'hi'}; +//=> Error +``` + +@category Object +*/ +export type MergeExclusive<FirstType, SecondType> = + (FirstType | SecondType) extends object ? + (Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType) : + FirstType | SecondType; + diff --git a/node_modules/type-fest/source/merge.d.ts b/node_modules/type-fest/source/merge.d.ts new file mode 100644 index 0000000..bed0256 --- /dev/null +++ b/node_modules/type-fest/source/merge.d.ts @@ -0,0 +1,46 @@ +import type {OmitIndexSignature} from './omit-index-signature'; +import type {PickIndexSignature} from './pick-index-signature'; +import type {EnforceOptional} from './enforce-optional'; + +// Merges two objects without worrying about index signatures. +type SimpleMerge<Destination, Source> = { + [Key in keyof Destination as Key extends keyof Source ? never : Key]: Destination[Key]; +} & Source; + +/** +Merge two types into a new type. Keys of the second type overrides keys of the first type. + +@example +``` +import type {Merge} from 'type-fest'; + +interface Foo { + [x: string]: unknown; + [x: number]: unknown; + foo: string; + bar: symbol; +} + +type Bar = { + [x: number]: number; + [x: symbol]: unknown; + bar: Date; + baz: boolean; +}; + +export type FooBar = Merge<Foo, Bar>; +// => { +// [x: string]: unknown; +// [x: number]: number; +// [x: symbol]: unknown; +// foo: string; +// bar: Date; +// baz: boolean; +// } +``` + +@category Object +*/ +export type Merge<Destination, Source> = EnforceOptional< +SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>> +& SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>; diff --git a/node_modules/type-fest/source/multidimensional-array.d.ts b/node_modules/type-fest/source/multidimensional-array.d.ts new file mode 100644 index 0000000..f2f5539 --- /dev/null +++ b/node_modules/type-fest/source/multidimensional-array.d.ts @@ -0,0 +1,44 @@ +import type {Subtract} from './internal'; +import type {IsEqual} from './is-equal'; + +type Recursive<T> = Array<Recursive<T>>; + +/** +Creates a type that represents a multidimensional array of the given type and dimension. + +Use-cases: +- Return a n-dimensional array from functions. +- Declare a n-dimensional array by defining its dimensions rather than declaring `[]` repetitively. +- Infer the dimensions of a n-dimensional array automatically from function arguments. +- Avoid the need to know in advance the dimensions of a n-dimensional array allowing them to be dynamic. + +@example +``` +import type {MultidimensionalArray} from 'type-fest'; + +function emptyMatrix<T extends number>(dimensions: T): MultidimensionalArray<unknown, T> { + const matrix: unknown[] = []; + + let subMatrix = matrix; + for (let dimension = 1; dimension < dimensions; ++dimension) { + console.log(`Initializing dimension #${dimension}`); + + subMatrix[0] = []; + subMatrix = subMatrix[0] as unknown[]; + } + + return matrix as MultidimensionalArray<unknown, T>; +} + +const matrix = emptyMatrix(3); + +matrix[0][0][0] = 42; +``` + +@category Array +*/ +export type MultidimensionalArray<Element, Dimensions extends number> = number extends Dimensions + ? Recursive<Element> + : IsEqual<Dimensions, 0> extends true + ? Element + : Array<MultidimensionalArray<Element, Subtract<Dimensions, 1>>>; diff --git a/node_modules/type-fest/source/multidimensional-readonly-array.d.ts b/node_modules/type-fest/source/multidimensional-readonly-array.d.ts new file mode 100644 index 0000000..5896cd2 --- /dev/null +++ b/node_modules/type-fest/source/multidimensional-readonly-array.d.ts @@ -0,0 +1,48 @@ +import type {Subtract} from './internal'; +import type {IsEqual} from './is-equal'; + +type Recursive<T> = ReadonlyArray<Recursive<T>>; + +/** +Creates a type that represents a multidimensional readonly array that of the given type and dimension. + +Use-cases: +- Return a n-dimensional array from functions. +- Declare a n-dimensional array by defining its dimensions rather than declaring `[]` repetitively. +- Infer the dimensions of a n-dimensional array automatically from function arguments. +- Avoid the need to know in advance the dimensions of a n-dimensional array allowing them to be dynamic. + +@example +``` +import type {MultidimensionalReadonlyArray} from 'type-fest'; + +function emptyMatrix<T extends number>(dimensions: T): MultidimensionalReadonlyArray<unknown, T> { + const matrix: unknown[] = []; + + let subMatrix = matrix; + for (let dimension = 1; dimension < dimensions; ++dimension) { + console.log(`Initializing dimension #${dimension}`); + + subMatrix[0] = []; + if (dimension < dimensions - 1) { + subMatrix = subMatrix[0] as unknown[]; + } else { + subMatrix[0] = 42; + } + } + + return matrix as MultidimensionalReadonlyArray<unknown, T>; +} + +const matrix = emptyMatrix(3); + +const answer = matrix[0][0][0]; // 42 +``` + +@category Array +*/ +export type MultidimensionalReadonlyArray<Element, Dimensions extends number> = number extends Dimensions + ? Recursive<Element> + : IsEqual<Dimensions, 0> extends true + ? Element + : ReadonlyArray<MultidimensionalReadonlyArray<Element, Subtract<Dimensions, 1>>>; diff --git a/node_modules/type-fest/source/numeric.d.ts b/node_modules/type-fest/source/numeric.d.ts new file mode 100644 index 0000000..2818ce3 --- /dev/null +++ b/node_modules/type-fest/source/numeric.d.ts @@ -0,0 +1,170 @@ +export type Numeric = number | bigint; + +type Zero = 0 | 0n; + +/** +Matches the hidden `Infinity` type. + +Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript. + +@see NegativeInfinity + +@category Numeric +*/ +// See https://github.com/microsoft/TypeScript/issues/31752 +// eslint-disable-next-line @typescript-eslint/no-loss-of-precision +export type PositiveInfinity = 1e999; + +/** +Matches the hidden `-Infinity` type. + +Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript. + +@see PositiveInfinity + +@category Numeric +*/ +// See https://github.com/microsoft/TypeScript/issues/31752 +// eslint-disable-next-line @typescript-eslint/no-loss-of-precision +export type NegativeInfinity = -1e999; + +/** +A finite `number`. +You can't pass a `bigint` as they are already guaranteed to be finite. + +Use-case: Validating and documenting parameters. + +Note: This can't detect `NaN`, please upvote [this issue](https://github.com/microsoft/TypeScript/issues/28682) if you want to have this type as a built-in in TypeScript. + +@example +``` +import type {Finite} from 'type-fest'; + +declare function setScore<T extends number>(length: Finite<T>): void; +``` + +@category Numeric +*/ +export type Finite<T extends number> = T extends PositiveInfinity | NegativeInfinity ? never : T; + +/** +A `number` that is an integer. +You can't pass a `bigint` as they are already guaranteed to be integers. + +Use-case: Validating and documenting parameters. + +@example +``` +import type {Integer} from 'type-fest'; + +declare function setYear<T extends number>(length: Integer<T>): void; +``` + +@see NegativeInteger +@see NonNegativeInteger + +@category Numeric +*/ +// `${bigint}` is a type that matches a valid bigint literal without the `n` (ex. 1, 0b1, 0o1, 0x1) +// Because T is a number and not a string we can effectively use this to filter out any numbers containing decimal points +export type Integer<T extends number> = `${T}` extends `${bigint}` ? T : never; + +/** +A `number` that is not an integer. +You can't pass a `bigint` as they are already guaranteed to be integers. + +Use-case: Validating and documenting parameters. + +@example +``` +import type {Float} from 'type-fest'; + +declare function setPercentage<T extends number>(length: Float<T>): void; +``` + +@see Integer + +@category Numeric +*/ +export type Float<T extends number> = T extends Integer<T> ? never : T; + +/** +A negative (`-∞ < x < 0`) `number` that is not an integer. +Equivalent to `Negative<Float<T>>`. + +Use-case: Validating and documenting parameters. + +@see Negative +@see Float + +@category Numeric +*/ +export type NegativeFloat<T extends number> = Negative<Float<T>>; + +/** +A negative `number`/`bigint` (`-∞ < x < 0`) + +Use-case: Validating and documenting parameters. + +@see NegativeInteger +@see NonNegative + +@category Numeric +*/ +export type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never; + +/** +A negative (`-∞ < x < 0`) `number` that is an integer. +Equivalent to `Negative<Integer<T>>`. + +You can't pass a `bigint` as they are already guaranteed to be integers, instead use `Negative<T>`. + +Use-case: Validating and documenting parameters. + +@see Negative +@see Integer + +@category Numeric +*/ +export type NegativeInteger<T extends number> = Negative<Integer<T>>; + +/** +A non-negative `number`/`bigint` (`0 <= x < ∞`). + +Use-case: Validating and documenting parameters. + +@see NonNegativeInteger +@see Negative + +@example +``` +import type {NonNegative} from 'type-fest'; + +declare function setLength<T extends number>(length: NonNegative<T>): void; +``` + +@category Numeric +*/ +export type NonNegative<T extends Numeric> = T extends Zero ? T : Negative<T> extends never ? T : never; + +/** +A non-negative (`0 <= x < ∞`) `number` that is an integer. +Equivalent to `NonNegative<Integer<T>>`. + +You can't pass a `bigint` as they are already guaranteed to be integers, instead use `NonNegative<T>`. + +Use-case: Validating and documenting parameters. + +@see NonNegative +@see Integer + +@example +``` +import type {NonNegativeInteger} from 'type-fest'; + +declare function setLength<T extends number>(length: NonNegativeInteger<T>): void; +``` + +@category Numeric +*/ +export type NonNegativeInteger<T extends number> = NonNegative<Integer<T>>; diff --git a/node_modules/type-fest/source/observable-like.d.ts b/node_modules/type-fest/source/observable-like.d.ts new file mode 100644 index 0000000..078b340 --- /dev/null +++ b/node_modules/type-fest/source/observable-like.d.ts @@ -0,0 +1,63 @@ +declare global { + // eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged. + interface SymbolConstructor { + readonly observable: symbol; + } +} + +/** +@remarks +The TC39 observable proposal defines a `closed` property, but some implementations (such as xstream) do not as of 10/08/2021. +As well, some guidance on making an `Observable` to not include `closed` property. +@see https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L129-L130 +@see https://github.com/staltz/xstream/blob/6c22580c1d84d69773ee4b0905df44ad464955b3/src/index.ts#L79-L85 +@see https://github.com/benlesh/symbol-observable#making-an-object-observable + +@category Observable +*/ +export type Unsubscribable = { + unsubscribe(): void; +}; + +/** +@category Observable +*/ +type OnNext<ValueType> = (value: ValueType) => void; +/** +@category Observable +*/ +type OnError = (error: unknown) => void; +/** +@category Observable +*/ +type OnComplete = () => void; + +/** +@category Observable +*/ +export type Observer<ValueType> = { + next: OnNext<ValueType>; + error: OnError; + complete: OnComplete; +}; + +/** +Matches a value that is like an [Observable](https://github.com/tc39/proposal-observable). + +@remarks +The TC39 Observable proposal defines 2 forms of `subscribe()`: +1. Three callback arguments: `subscribe(observer: OnNext<ValueType>, onError?: OnError, onComplete?: OnComplete): Unsubscribable;` +2. A single `observer` argument: (as defined below) + +But `Observable` implementations have evolved to preferring case 2 and some implementations choose not to implement case 1. Therefore, an `ObservableLike` cannot be trusted to implement the first case. (xstream and hand built observerables often do not implement case 1) + +@see https://github.com/tc39/proposal-observable#observable +@see https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L246-L259 +@see https://benlesh.com/posts/learning-observable-by-building-observable/ + +@category Observable +*/ +export type ObservableLike<ValueType = unknown> = { + subscribe(observer?: Partial<Observer<ValueType>>): Unsubscribable; + [Symbol.observable](): ObservableLike<ValueType>; +}; diff --git a/node_modules/type-fest/source/omit-index-signature.d.ts b/node_modules/type-fest/source/omit-index-signature.d.ts new file mode 100644 index 0000000..8c71655 --- /dev/null +++ b/node_modules/type-fest/source/omit-index-signature.d.ts @@ -0,0 +1,107 @@ +/** +Omit any index signatures from the given object type, leaving only explicitly defined properties. + +This is the counterpart of `PickIndexSignature`. + +Use-cases: +- Remove overly permissive signatures from third-party types. + +This type was taken from this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747). + +It relies on the fact that an empty object (`{}`) is assignable to an object with just an index signature, like `Record<string, unknown>`, but not to an object with explicitly defined keys, like `Record<'foo' | 'bar', unknown>`. + +(The actual value type, `unknown`, is irrelevant and could be any type. Only the key type matters.) + +``` +const indexed: Record<string, unknown> = {}; // Allowed + +const keyed: Record<'foo', unknown> = {}; // Error +// => TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, bar +``` + +Instead of causing a type error like the above, you can also use a [conditional type](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html) to test whether a type is assignable to another: + +``` +type Indexed = {} extends Record<string, unknown> + ? '✅ `{}` is assignable to `Record<string, unknown>`' + : '❌ `{}` is NOT assignable to `Record<string, unknown>`'; +// => '✅ `{}` is assignable to `Record<string, unknown>`' + +type Keyed = {} extends Record<'foo' | 'bar', unknown> + ? "✅ `{}` is assignable to `Record<'foo' | 'bar', unknown>`" + : "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`"; +// => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`" +``` + +Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each `KeyType` of `ObjectType`... + +``` +import type {OmitIndexSignature} from 'type-fest'; + +type OmitIndexSignature<ObjectType> = { + [KeyType in keyof ObjectType // Map each key of `ObjectType`... + ]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature<Foo> == Foo`. +}; +``` + +...whether an empty object (`{}`) would be assignable to an object with that `KeyType` (`Record<KeyType, unknown>`)... + +``` +import type {OmitIndexSignature} from 'type-fest'; + +type OmitIndexSignature<ObjectType> = { + [KeyType in keyof ObjectType + // Is `{}` assignable to `Record<KeyType, unknown>`? + as {} extends Record<KeyType, unknown> + ? ... // ✅ `{}` is assignable to `Record<KeyType, unknown>` + : ... // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>` + ]: ObjectType[KeyType]; +}; +``` + +If `{}` is assignable, it means that `KeyType` is an index signature and we want to remove it. If it is not assignable, `KeyType` is a "real" key and we want to keep it. + +``` +import type {OmitIndexSignature} from 'type-fest'; + +type OmitIndexSignature<ObjectType> = { + [KeyType in keyof ObjectType + as {} extends Record<KeyType, unknown> + ? never // => Remove this `KeyType`. + : KeyType // => Keep this `KeyType` as it is. + ]: ObjectType[KeyType]; +}; +``` + +@example +``` +import type {OmitIndexSignature} from 'type-fest'; + +interface Example { + // These index signatures will be removed. + [x: string]: any + [x: number]: any + [x: symbol]: any + [x: `head-${string}`]: string + [x: `${string}-tail`]: string + [x: `head-${string}-tail`]: string + [x: `${bigint}`]: string + [x: `embedded-${number}`]: string + + // These explicitly defined keys will remain. + foo: 'bar'; + qux?: 'baz'; +} + +type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>; +// => { foo: 'bar'; qux?: 'baz' | undefined; } +``` + +@see PickIndexSignature +@category Object +*/ +export type OmitIndexSignature<ObjectType> = { + [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> + ? never + : KeyType]: ObjectType[KeyType]; +}; diff --git a/node_modules/type-fest/source/opaque.d.ts b/node_modules/type-fest/source/opaque.d.ts new file mode 100644 index 0000000..aafbca5 --- /dev/null +++ b/node_modules/type-fest/source/opaque.d.ts @@ -0,0 +1,107 @@ +declare const tag: unique symbol; + +declare type Tagged<Token> = { + readonly [tag]: Token; +}; + +/** +Create an opaque type, which hides its internal details from the public, and can only be created by being used explicitly. + +The generic type parameter can be anything. It doesn't have to be an object. + +[Read more about opaque types.](https://codemix.com/opaque-types-in-javascript/) + +There have been several discussions about adding this feature to TypeScript via the `opaque type` operator, similar to how Flow does it. Unfortunately, nothing has (yet) moved forward: + - [Microsoft/TypeScript#202](https://github.com/microsoft/TypeScript/issues/202) + - [Microsoft/TypeScript#15408](https://github.com/Microsoft/TypeScript/issues/15408) + - [Microsoft/TypeScript#15807](https://github.com/Microsoft/TypeScript/issues/15807) + +@example +``` +import type {Opaque} from 'type-fest'; + +type AccountNumber = Opaque<number, 'AccountNumber'>; +type AccountBalance = Opaque<number, 'AccountBalance'>; + +// The `Token` parameter allows the compiler to differentiate between types, whereas "unknown" will not. For example, consider the following structures: +type ThingOne = Opaque<string>; +type ThingTwo = Opaque<string>; + +// To the compiler, these types are allowed to be cast to each other as they have the same underlying type. They are both `string & { __opaque__: unknown }`. +// To avoid this behaviour, you would instead pass the "Token" parameter, like so. +type NewThingOne = Opaque<string, 'ThingOne'>; +type NewThingTwo = Opaque<string, 'ThingTwo'>; + +// Now they're completely separate types, so the following will fail to compile. +function createNewThingOne (): NewThingOne { + // As you can see, casting from a string is still allowed. However, you may not cast NewThingOne to NewThingTwo, and vice versa. + return 'new thing one' as NewThingOne; +} + +// This will fail to compile, as they are fundamentally different types. +const thingTwo = createNewThingOne() as NewThingTwo; + +// Here's another example of opaque typing. +function createAccountNumber(): AccountNumber { + return 2 as AccountNumber; +} + +function getMoneyForAccount(accountNumber: AccountNumber): AccountBalance { + return 4 as AccountBalance; +} + +// This will compile successfully. +getMoneyForAccount(createAccountNumber()); + +// But this won't, because it has to be explicitly passed as an `AccountNumber` type. +getMoneyForAccount(2); + +// You can use opaque values like they aren't opaque too. +const accountNumber = createAccountNumber(); + +// This will not compile successfully. +const newAccountNumber = accountNumber + 2; + +// As a side note, you can (and should) use recursive types for your opaque types to make them stronger and hopefully easier to type. +type Person = { + id: Opaque<number, Person>; + name: string; +}; +``` + +@category Type +*/ +export type Opaque<Type, Token = unknown> = Type & Tagged<Token>; + +/** +Revert an opaque type back to its original type by removing the readonly `[tag]`. + +Why is this necessary? + +1. Use an `Opaque` type as object keys +2. Prevent TS4058 error: "Return type of exported function has or is using name X from external module Y but cannot be named" + +@example +``` +import type {Opaque, UnwrapOpaque} from 'type-fest'; + +type AccountType = Opaque<'SAVINGS' | 'CHECKING', 'AccountType'>; + +const moneyByAccountType: Record<UnwrapOpaque<AccountType>, number> = { + SAVINGS: 99, + CHECKING: 0.1 +}; + +// Without UnwrapOpaque, the following expression would throw a type error. +const money = moneyByAccountType.SAVINGS; // TS error: Property 'SAVINGS' does not exist + +// Attempting to pass an non-Opaque type to UnwrapOpaque will raise a type error. +type WontWork = UnwrapOpaque<string>; +``` + +@category Type +*/ +export type UnwrapOpaque<OpaqueType extends Tagged<unknown>> = + OpaqueType extends Opaque<infer Type, OpaqueType[typeof tag]> + ? Type + : OpaqueType; diff --git a/node_modules/type-fest/source/optional-keys-of.d.ts b/node_modules/type-fest/source/optional-keys-of.d.ts new file mode 100644 index 0000000..c1b8193 --- /dev/null +++ b/node_modules/type-fest/source/optional-keys-of.d.ts @@ -0,0 +1,38 @@ +/** +Extract all optional keys from the given type. + +This is useful when you want to create a new type that contains different type values for the optional keys only. + +@example +``` +import type {OptionalKeysOf, Except} from 'type-fest'; + +interface User { + name: string; + surname: string; + + luckyNumber?: number; +} + +const REMOVE_FIELD = Symbol('remove field symbol'); +type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & { + [Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD; +}; + +const update1: UpdateOperation<User> = { + name: 'Alice' +}; + +const update2: UpdateOperation<User> = { + name: 'Bob', + luckyNumber: REMOVE_FIELD +}; +``` + +@category Utilities +*/ +export type OptionalKeysOf<BaseType extends object> = Exclude<{ + [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]> + ? never + : Key +}[keyof BaseType], undefined>; diff --git a/node_modules/type-fest/source/override-properties.d.ts b/node_modules/type-fest/source/override-properties.d.ts new file mode 100644 index 0000000..1cbc054 --- /dev/null +++ b/node_modules/type-fest/source/override-properties.d.ts @@ -0,0 +1,29 @@ +import type {Merge} from './merge'; + +/** +Override existing properties of the given type. Similar to `Merge`, but enforces that the original type has the properties you want to override. + +This is useful when you want to override existing properties with a different type and make sure that these properties really exist in the original. + +@example +``` +type Foo = { + a: string + b: string +} +type Bar = OverrideProperties<Foo, {b: number}> +//=> {a: string, b: number} + +type Baz = OverrideProperties<Foo, {c: number}> +// Error, type '{ c: number; }' does not satisfy the constraint '{ c: never; }' + +type Fizz = OverrideProperties<Foo, {b: number; c: number}> +// Error, type '{ b: number; c: number; }' does not satisfy the constraint '{ b: number; c: never; }' +``` + +@category Object +*/ +export type OverrideProperties< + TOriginal, + TOverride extends {[Key in keyof TOverride]: Key extends keyof TOriginal ? TOverride[Key] : never}, +> = Merge<TOriginal, TOverride>; diff --git a/node_modules/type-fest/source/package-json.d.ts b/node_modules/type-fest/source/package-json.d.ts new file mode 100644 index 0000000..7d2b809 --- /dev/null +++ b/node_modules/type-fest/source/package-json.d.ts @@ -0,0 +1,676 @@ +import type {LiteralUnion} from './literal-union'; +import type {JsonObject, JsonValue} from './basic'; + +declare namespace PackageJson { + /** + A person who has been involved in creating or maintaining the package. + */ + export type Person = + | string + | { + name: string; + url?: string; + email?: string; + }; + + export type BugsLocation = + | string + | { + /** + The URL to the package's issue tracker. + */ + url?: string; + + /** + The email address to which issues should be reported. + */ + email?: string; + }; + + export type DirectoryLocations = { + [directoryType: string]: JsonValue | undefined; + + /** + Location for executable scripts. Sugar to generate entries in the `bin` property by walking the folder. + */ + bin?: string; + + /** + Location for Markdown files. + */ + doc?: string; + + /** + Location for example scripts. + */ + example?: string; + + /** + Location for the bulk of the library. + */ + lib?: string; + + /** + Location for man pages. Sugar to generate a `man` array by walking the folder. + */ + man?: string; + + /** + Location for test files. + */ + test?: string; + }; + + export type Scripts = { + /** + Run **before** the package is published (Also run on local `npm install` without any arguments). + */ + prepublish?: string; + + /** + Run both **before** the package is packed and published, and on local `npm install` without any arguments. This is run **after** `prepublish`, but **before** `prepublishOnly`. + */ + prepare?: string; + + /** + Run **before** the package is prepared and packed, **only** on `npm publish`. + */ + prepublishOnly?: string; + + /** + Run **before** a tarball is packed (on `npm pack`, `npm publish`, and when installing git dependencies). + */ + prepack?: string; + + /** + Run **after** the tarball has been generated and moved to its final destination. + */ + postpack?: string; + + /** + Run **after** the package is published. + */ + publish?: string; + + /** + Run **after** the package is published. + */ + postpublish?: string; + + /** + Run **before** the package is installed. + */ + preinstall?: string; + + /** + Run **after** the package is installed. + */ + install?: string; + + /** + Run **after** the package is installed and after `install`. + */ + postinstall?: string; + + /** + Run **before** the package is uninstalled and before `uninstall`. + */ + preuninstall?: string; + + /** + Run **before** the package is uninstalled. + */ + uninstall?: string; + + /** + Run **after** the package is uninstalled. + */ + postuninstall?: string; + + /** + Run **before** bump the package version and before `version`. + */ + preversion?: string; + + /** + Run **before** bump the package version. + */ + version?: string; + + /** + Run **after** bump the package version. + */ + postversion?: string; + + /** + Run with the `npm test` command, before `test`. + */ + pretest?: string; + + /** + Run with the `npm test` command. + */ + test?: string; + + /** + Run with the `npm test` command, after `test`. + */ + posttest?: string; + + /** + Run with the `npm stop` command, before `stop`. + */ + prestop?: string; + + /** + Run with the `npm stop` command. + */ + stop?: string; + + /** + Run with the `npm stop` command, after `stop`. + */ + poststop?: string; + + /** + Run with the `npm start` command, before `start`. + */ + prestart?: string; + + /** + Run with the `npm start` command. + */ + start?: string; + + /** + Run with the `npm start` command, after `start`. + */ + poststart?: string; + + /** + Run with the `npm restart` command, before `restart`. Note: `npm restart` will run the `stop` and `start` scripts if no `restart` script is provided. + */ + prerestart?: string; + + /** + Run with the `npm restart` command. Note: `npm restart` will run the `stop` and `start` scripts if no `restart` script is provided. + */ + restart?: string; + + /** + Run with the `npm restart` command, after `restart`. Note: `npm restart` will run the `stop` and `start` scripts if no `restart` script is provided. + */ + postrestart?: string; + } & Partial<Record<string, string>>; + + /** + Dependencies of the package. The version range is a string which has one or more space-separated descriptors. Dependencies can also be identified with a tarball or Git URL. + */ + export type Dependency = Partial<Record<string, string>>; + + /** + A mapping of conditions and the paths to which they resolve. + */ + type ExportConditions = { // eslint-disable-line @typescript-eslint/consistent-indexed-object-style + [condition: string]: Exports; + }; + + /** + Entry points of a module, optionally with conditions and subpath exports. + */ + export type Exports = + | null + | string + | Array<string | ExportConditions> + | ExportConditions; + + /** + Import map entries of a module, optionally with conditions and subpath imports. + */ + export type Imports = { // eslint-disable-line @typescript-eslint/consistent-indexed-object-style + [key: `#${string}`]: Exports; + }; + + // eslint-disable-next-line @typescript-eslint/consistent-type-definitions + export interface NonStandardEntryPoints { + /** + An ECMAScript module ID that is the primary entry point to the program. + */ + module?: string; + + /** + A module ID with untranspiled code that is the primary entry point to the program. + */ + esnext?: + | string + | { + [moduleName: string]: string | undefined; + main?: string; + browser?: string; + }; + + /** + A hint to JavaScript bundlers or component tools when packaging modules for client side use. + */ + browser?: + | string + | Partial<Record<string, string | false>>; + + /** + Denote which files in your project are "pure" and therefore safe for Webpack to prune if unused. + + [Read more.](https://webpack.js.org/guides/tree-shaking/) + */ + sideEffects?: boolean | string[]; + } + + export type TypeScriptConfiguration = { + /** + Location of the bundled TypeScript declaration file. + */ + types?: string; + + /** + Version selection map of TypeScript. + */ + typesVersions?: Partial<Record<string, Partial<Record<string, string[]>>>>; + + /** + Location of the bundled TypeScript declaration file. Alias of `types`. + */ + typings?: string; + }; + + /** + An alternative configuration for workspaces. + */ + export type WorkspaceConfig = { + /** + An array of workspace pattern strings which contain the workspace packages. + */ + packages?: WorkspacePattern[]; + + /** + Designed to solve the problem of packages which break when their `node_modules` are moved to the root workspace directory - a process known as hoisting. For these packages, both within your workspace, and also some that have been installed via `node_modules`, it is important to have a mechanism for preventing the default Yarn workspace behavior. By adding workspace pattern strings here, Yarn will resume non-workspace behavior for any package which matches the defined patterns. + + [Supported](https://classic.yarnpkg.com/blog/2018/02/15/nohoist/) by Yarn. + [Not supported](https://github.com/npm/rfcs/issues/287) by npm. + */ + nohoist?: WorkspacePattern[]; + }; + + /** + A workspace pattern points to a directory or group of directories which contain packages that should be included in the workspace installation process. + + The patterns are handled with [minimatch](https://github.com/isaacs/minimatch). + + @example + `docs` → Include the docs directory and install its dependencies. + `packages/*` → Include all nested directories within the packages directory, like `packages/cli` and `packages/core`. + */ + type WorkspacePattern = string; + + export type YarnConfiguration = { + /** + If your package only allows one version of a given dependency, and you’d like to enforce the same behavior as `yarn install --flat` on the command-line, set this to `true`. + + Note that if your `package.json` contains `"flat": true` and other packages depend on yours (e.g. you are building a library rather than an app), those other packages will also need `"flat": true` in their `package.json` or be installed with `yarn install --flat` on the command-line. + */ + flat?: boolean; + + /** + Selective version resolutions. Allows the definition of custom package versions inside dependencies without manual edits in the `yarn.lock` file. + */ + resolutions?: Dependency; + }; + + export type JSPMConfiguration = { + /** + JSPM configuration. + */ + jspm?: PackageJson; + }; + + /** + Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file). Containing standard npm properties. + */ + // eslint-disable-next-line @typescript-eslint/consistent-type-definitions + export interface PackageJsonStandard { + /** + The name of the package. + */ + name?: string; + + /** + Package version, parseable by [`node-semver`](https://github.com/npm/node-semver). + */ + version?: string; + + /** + Package description, listed in `npm search`. + */ + description?: string; + + /** + Keywords associated with package, listed in `npm search`. + */ + keywords?: string[]; + + /** + The URL to the package's homepage. + */ + homepage?: LiteralUnion<'.', string>; + + /** + The URL to the package's issue tracker and/or the email address to which issues should be reported. + */ + bugs?: BugsLocation; + + /** + The license for the package. + */ + license?: string; + + /** + The licenses for the package. + */ + licenses?: Array<{ + type?: string; + url?: string; + }>; + + author?: Person; + + /** + A list of people who contributed to the package. + */ + contributors?: Person[]; + + /** + A list of people who maintain the package. + */ + maintainers?: Person[]; + + /** + The files included in the package. + */ + files?: string[]; + + /** + Resolution algorithm for importing ".js" files from the package's scope. + + [Read more.](https://nodejs.org/api/esm.html#esm_package_json_type_field) + */ + type?: 'module' | 'commonjs'; + + /** + The module ID that is the primary entry point to the program. + */ + main?: string; + + /** + Subpath exports to define entry points of the package. + + [Read more.](https://nodejs.org/api/packages.html#subpath-exports) + */ + exports?: Exports; + + /** + Subpath imports to define internal package import maps that only apply to import specifiers from within the package itself. + + [Read more.](https://nodejs.org/api/packages.html#subpath-imports) + */ + imports?: Imports; + + /** + The executable files that should be installed into the `PATH`. + */ + bin?: + | string + | Partial<Record<string, string>>; + + /** + Filenames to put in place for the `man` program to find. + */ + man?: string | string[]; + + /** + Indicates the structure of the package. + */ + directories?: DirectoryLocations; + + /** + Location for the code repository. + */ + repository?: + | string + | { + type: string; + url: string; + + /** + Relative path to package.json if it is placed in non-root directory (for example if it is part of a monorepo). + + [Read more.](https://github.com/npm/rfcs/blob/latest/implemented/0010-monorepo-subdirectory-declaration.md) + */ + directory?: string; + }; + + /** + Script commands that are run at various times in the lifecycle of the package. The key is the lifecycle event, and the value is the command to run at that point. + */ + scripts?: Scripts; + + /** + Is used to set configuration parameters used in package scripts that persist across upgrades. + */ + config?: JsonObject; + + /** + The dependencies of the package. + */ + dependencies?: Dependency; + + /** + Additional tooling dependencies that are not required for the package to work. Usually test, build, or documentation tooling. + */ + devDependencies?: Dependency; + + /** + Dependencies that are skipped if they fail to install. + */ + optionalDependencies?: Dependency; + + /** + Dependencies that will usually be required by the package user directly or via another dependency. + */ + peerDependencies?: Dependency; + + /** + Indicate peer dependencies that are optional. + */ + peerDependenciesMeta?: Partial<Record<string, {optional: true}>>; + + /** + Package names that are bundled when the package is published. + */ + bundledDependencies?: string[]; + + /** + Alias of `bundledDependencies`. + */ + bundleDependencies?: string[]; + + /** + Engines that this package runs on. + */ + engines?: { + [EngineName in 'npm' | 'node' | string]?: string; // eslint-disable-line @typescript-eslint/no-redundant-type-constituents + }; + + /** + @deprecated + */ + engineStrict?: boolean; + + /** + Operating systems the module runs on. + */ + os?: Array<LiteralUnion< + | 'aix' + | 'darwin' + | 'freebsd' + | 'linux' + | 'openbsd' + | 'sunos' + | 'win32' + | '!aix' + | '!darwin' + | '!freebsd' + | '!linux' + | '!openbsd' + | '!sunos' + | '!win32', + string + >>; + + /** + CPU architectures the module runs on. + */ + cpu?: Array<LiteralUnion< + | 'arm' + | 'arm64' + | 'ia32' + | 'mips' + | 'mipsel' + | 'ppc' + | 'ppc64' + | 's390' + | 's390x' + | 'x32' + | 'x64' + | '!arm' + | '!arm64' + | '!ia32' + | '!mips' + | '!mipsel' + | '!ppc' + | '!ppc64' + | '!s390' + | '!s390x' + | '!x32' + | '!x64', + string + >>; + + /** + If set to `true`, a warning will be shown if package is installed locally. Useful if the package is primarily a command-line application that should be installed globally. + + @deprecated + */ + preferGlobal?: boolean; + + /** + If set to `true`, then npm will refuse to publish it. + */ + private?: boolean; + + /** + A set of config values that will be used at publish-time. It's especially handy to set the tag, registry or access, to ensure that a given package is not tagged with 'latest', published to the global public registry or that a scoped module is private by default. + */ + publishConfig?: PublishConfig; + + /** + Describes and notifies consumers of a package's monetary support information. + + [Read more.](https://github.com/npm/rfcs/blob/latest/accepted/0017-add-funding-support.md) + */ + funding?: string | { + /** + The type of funding. + */ + type?: LiteralUnion< + | 'github' + | 'opencollective' + | 'patreon' + | 'individual' + | 'foundation' + | 'corporation', + string + >; + + /** + The URL to the funding page. + */ + url: string; + }; + + /** + Used to configure [npm workspaces](https://docs.npmjs.com/cli/using-npm/workspaces) / [Yarn workspaces](https://classic.yarnpkg.com/docs/workspaces/). + + Workspaces allow you to manage multiple packages within the same repository in such a way that you only need to run your install command once in order to install all of them in a single pass. + + Please note that the top-level `private` property of `package.json` **must** be set to `true` in order to use workspaces. + */ + workspaces?: WorkspacePattern[] | WorkspaceConfig; + } + + /** + Type for [`package.json` file used by the Node.js runtime](https://nodejs.org/api/packages.html#nodejs-packagejson-field-definitions). + */ + export type NodeJsStandard = { + /** + Defines which package manager is expected to be used when working on the current project. It can set to any of the [supported package managers](https://nodejs.org/api/corepack.html#supported-package-managers), and will ensure that your teams use the exact same package manager versions without having to install anything else than Node.js. + + __This field is currently experimental and needs to be opted-in; check the [Corepack](https://nodejs.org/api/corepack.html) page for details about the procedure.__ + + @example + ```json + { + "packageManager": "<package manager name>@<version>" + } + ``` + */ + packageManager?: string; + }; + + export type PublishConfig = { + /** + Additional, less common properties from the [npm docs on `publishConfig`](https://docs.npmjs.com/cli/v7/configuring-npm/package-json#publishconfig). + */ + [additionalProperties: string]: JsonValue | undefined; + + /** + When publishing scoped packages, the access level defaults to restricted. If you want your scoped package to be publicly viewable (and installable) set `--access=public`. The only valid values for access are public and restricted. Unscoped packages always have an access level of public. + */ + access?: 'public' | 'restricted'; + + /** + The base URL of the npm registry. + + Default: `'https://registry.npmjs.org/'` + */ + registry?: string; + + /** + The tag to publish the package under. + + Default: `'latest'` + */ + tag?: string; + }; +} + +/** +Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file). Also includes types for fields used by other popular projects, like TypeScript and Yarn. + +@category File +*/ +export type PackageJson = +JsonObject & +PackageJson.NodeJsStandard & +PackageJson.PackageJsonStandard & +PackageJson.NonStandardEntryPoints & +PackageJson.TypeScriptConfiguration & +PackageJson.YarnConfiguration & +PackageJson.JSPMConfiguration; diff --git a/node_modules/type-fest/source/partial-deep.d.ts b/node_modules/type-fest/source/partial-deep.d.ts new file mode 100644 index 0000000..14eb2d4 --- /dev/null +++ b/node_modules/type-fest/source/partial-deep.d.ts @@ -0,0 +1,111 @@ +import type {BuiltIns} from './internal'; + +/** +@see PartialDeep +*/ +export type PartialDeepOptions = { + /** + Whether to affect the individual elements of arrays and tuples. + + @default false + */ + readonly recurseIntoArrays?: boolean; +}; + +/** +Create a type from another type with all keys and nested keys set to optional. + +Use-cases: +- Merging a default settings/config object with another object, the second object would be a deep partial of the default object. +- Mocking and testing complex entities, where populating an entire object with its keys would be redundant in terms of the mock or test. + +@example +``` +import type {PartialDeep} from 'type-fest'; + +const settings: Settings = { + textEditor: { + fontSize: 14; + fontColor: '#000000'; + fontWeight: 400; + } + autocomplete: false; + autosave: true; +}; + +const applySavedSettings = (savedSettings: PartialDeep<Settings>) => { + return {...settings, ...savedSettings}; +} + +settings = applySavedSettings({textEditor: {fontWeight: 500}}); +``` + +By default, this does not affect elements in array and tuple types. You can change this by passing `{recurseIntoArrays: true}` as the second type argument: + +``` +import type {PartialDeep} from 'type-fest'; + +interface Settings { + languages: string[]; +} + +const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true}> = { + languages: [undefined] +}; +``` + +@category Object +@category Array +@category Set +@category Map +*/ +export type PartialDeep<T, Options extends PartialDeepOptions = {}> = T extends BuiltIns + ? T + : T extends Map<infer KeyType, infer ValueType> + ? PartialMapDeep<KeyType, ValueType, Options> + : T extends Set<infer ItemType> + ? PartialSetDeep<ItemType, Options> + : T extends ReadonlyMap<infer KeyType, infer ValueType> + ? PartialReadonlyMapDeep<KeyType, ValueType, Options> + : T extends ReadonlySet<infer ItemType> + ? PartialReadonlySetDeep<ItemType, Options> + : T extends ((...arguments_: any[]) => unknown) + ? T | undefined + : T extends object + ? T extends ReadonlyArray<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156 + ? Options['recurseIntoArrays'] extends true + ? ItemType[] extends T // Test for arrays (non-tuples) specifically + ? readonly ItemType[] extends T // Differentiate readonly and mutable arrays + ? ReadonlyArray<PartialDeep<ItemType | undefined, Options>> + : Array<PartialDeep<ItemType | undefined, Options>> + : PartialObjectDeep<T, Options> // Tuples behave properly + : T // If they don't opt into array testing, just use the original type + : PartialObjectDeep<T, Options> + : unknown; + +/** +Same as `PartialDeep`, but accepts only `Map`s and as inputs. Internal helper for `PartialDeep`. +*/ +type PartialMapDeep<KeyType, ValueType, Options extends PartialDeepOptions> = {} & Map<PartialDeep<KeyType, Options>, PartialDeep<ValueType, Options>>; + +/** +Same as `PartialDeep`, but accepts only `Set`s as inputs. Internal helper for `PartialDeep`. +*/ +type PartialSetDeep<T, Options extends PartialDeepOptions> = {} & Set<PartialDeep<T, Options>>; + +/** +Same as `PartialDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `PartialDeep`. +*/ +type PartialReadonlyMapDeep<KeyType, ValueType, Options extends PartialDeepOptions> = {} & ReadonlyMap<PartialDeep<KeyType, Options>, PartialDeep<ValueType, Options>>; + +/** +Same as `PartialDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `PartialDeep`. +*/ +type PartialReadonlySetDeep<T, Options extends PartialDeepOptions> = {} & ReadonlySet<PartialDeep<T, Options>>; + +/** +Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`. +*/ +type PartialObjectDeep<ObjectType extends object, Options extends PartialDeepOptions> = { + [KeyType in keyof ObjectType]?: PartialDeep<ObjectType[KeyType], Options> +}; diff --git a/node_modules/type-fest/source/partial-on-undefined-deep.d.ts b/node_modules/type-fest/source/partial-on-undefined-deep.d.ts new file mode 100644 index 0000000..a0428d6 --- /dev/null +++ b/node_modules/type-fest/source/partial-on-undefined-deep.d.ts @@ -0,0 +1,70 @@ +import type {BuiltIns} from './internal'; +import type {Merge} from './merge'; + +/** +@see PartialOnUndefinedDeep +*/ +export type PartialOnUndefinedDeepOptions = { + /** + Whether to affect the individual elements of arrays and tuples. + + @default false + */ + readonly recurseIntoArrays?: boolean; +}; + +/** +Create a deep version of another type where all keys accepting `undefined` type are set to optional. + +This utility type is recursive, transforming at any level deep. By default, it does not affect arrays and tuples items unless you explicitly pass `{recurseIntoArrays: true}` as the second type argument. + +Use-cases: +- Make all properties of a type that can be undefined optional to not have to specify keys with undefined value. + +@example +``` +import type {PartialOnUndefinedDeep} from 'type-fest'; + +interface Settings { + optionA: string; + optionB: number | undefined; + subOption: { + subOptionA: boolean; + subOptionB: boolean | undefined; + } +}; + +const testSettings: PartialOnUndefinedDeep<Settings> = { + optionA: 'foo', + // 👉 optionB is now optional and can be omitted + subOption: { + subOptionA: true, + // 👉 subOptionB is now optional as well and can be omitted + }, +}; +``` + +@category Object +*/ +export type PartialOnUndefinedDeep<T, Options extends PartialOnUndefinedDeepOptions = {}> = T extends Record<any, any> | undefined + ? {[KeyType in keyof T as undefined extends T[KeyType] ? KeyType : never]?: PartialOnUndefinedDeepValue<T[KeyType], Options>} extends infer U // Make a partial type with all value types accepting undefined (and set them optional) + ? Merge<{[KeyType in keyof T as KeyType extends keyof U ? never : KeyType]: PartialOnUndefinedDeepValue<T[KeyType], Options>}, U> // Join all remaining keys not treated in U + : never // Should not happen + : T; + +/** +Utility type to get the value type by key and recursively call `PartialOnUndefinedDeep` to transform sub-objects. +*/ +type PartialOnUndefinedDeepValue<T, Options extends PartialOnUndefinedDeepOptions> = T extends BuiltIns | ((...arguments_: any[]) => unknown) + ? T + : T extends ReadonlyArray<infer U> // Test if type is array or tuple + ? Options['recurseIntoArrays'] extends true // Check if option is activated + ? U[] extends T // Check if array not tuple + ? readonly U[] extends T + ? ReadonlyArray<PartialOnUndefinedDeep<U, Options>> // Readonly array treatment + : Array<PartialOnUndefinedDeep<U, Options>> // Mutable array treatment + : PartialOnUndefinedDeep<{[Key in keyof T]: PartialOnUndefinedDeep<T[Key], Options>}, Options> // Tuple treatment + : T + : T extends Record<any, any> | undefined + ? PartialOnUndefinedDeep<T, Options> + : unknown; diff --git a/node_modules/type-fest/source/pascal-case.d.ts b/node_modules/type-fest/source/pascal-case.d.ts new file mode 100644 index 0000000..9ce8843 --- /dev/null +++ b/node_modules/type-fest/source/pascal-case.d.ts @@ -0,0 +1,38 @@ +import type {CamelCase} from './camel-case'; + +/** +Converts a string literal to pascal-case. + +@example +``` +import type {PascalCase} from 'type-fest'; + +// Simple + +const someVariable: PascalCase<'foo-bar'> = 'FooBar'; + +// Advanced + +type PascalCaseProps<T> = { + [K in keyof T as PascalCase<K>]: T[K] +}; + +interface RawOptions { + 'dry-run': boolean; + 'full_family_name': string; + foo: number; +} + +const dbResult: CamelCasedProperties<ModelProps> = { + DryRun: true, + FullFamilyName: 'bar.js', + Foo: 123 +}; +``` + +@category Change case +@category Template literal +*/ +export type PascalCase<Value> = CamelCase<Value> extends string + ? Capitalize<CamelCase<Value>> + : CamelCase<Value>; diff --git a/node_modules/type-fest/source/pascal-cased-properties-deep.d.ts b/node_modules/type-fest/source/pascal-cased-properties-deep.d.ts new file mode 100644 index 0000000..3b9bc5f --- /dev/null +++ b/node_modules/type-fest/source/pascal-cased-properties-deep.d.ts @@ -0,0 +1,54 @@ +import type {PascalCase} from './pascal-case'; + +/** +Convert object properties to pascal case recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see PascalCase +@see PascalCasedProperties + +@example +``` +import type {PascalCasedPropertiesDeep} from 'type-fest'; + +interface User { + userId: number; + userName: string; +} + +interface UserWithFriends { + userInfo: User; + userFriends: User[]; +} + +const result: PascalCasedPropertiesDeep<UserWithFriends> = { + UserInfo: { + UserId: 1, + UserName: 'Tom', + }, + UserFriends: [ + { + UserId: 2, + UserName: 'Jerry', + }, + { + UserId: 3, + UserName: 'Spike', + }, + ], +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type PascalCasedPropertiesDeep<Value> = Value extends Function | Date | RegExp + ? Value + : Value extends Array<infer U> + ? Array<PascalCasedPropertiesDeep<U>> + : Value extends Set<infer U> + ? Set<PascalCasedPropertiesDeep<U>> : { + [K in keyof Value as PascalCase<K>]: PascalCasedPropertiesDeep<Value[K]>; + }; diff --git a/node_modules/type-fest/source/pascal-cased-properties.d.ts b/node_modules/type-fest/source/pascal-cased-properties.d.ts new file mode 100644 index 0000000..c4748d0 --- /dev/null +++ b/node_modules/type-fest/source/pascal-cased-properties.d.ts @@ -0,0 +1,34 @@ +import type {PascalCase} from './pascal-case'; + +/** +Convert object properties to pascal case but not recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see PascalCase +@see PascalCasedPropertiesDeep + +@example +``` +import type {PascalCasedProperties} from 'type-fest'; + +interface User { + userId: number; + userName: string; +} + +const result: PascalCasedProperties<User> = { + UserId: 1, + UserName: 'Tom', +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type PascalCasedProperties<Value> = Value extends Function + ? Value + : Value extends Array<infer U> + ? Value + : {[K in keyof Value as PascalCase<K>]: Value[K]}; diff --git a/node_modules/type-fest/source/pick-index-signature.d.ts b/node_modules/type-fest/source/pick-index-signature.d.ts new file mode 100644 index 0000000..1271257 --- /dev/null +++ b/node_modules/type-fest/source/pick-index-signature.d.ts @@ -0,0 +1,102 @@ +/** +Pick only index signatures from the given object type, leaving out all explicitly defined properties. + +This is the counterpart of `OmitIndexSignature`. + +When you use a type that will iterate through an object that has indexed keys and explicitly defined keys you end up with a type where only the indexed keys are kept. This is because `keyof` of an indexed type always returns `string | number | symbol`, because every key is possible in that object. With this type, you can save the indexed keys and reinject them later, like in the second example below. + +@example +``` +import type {PickIndexSignature} from 'type-fest'; + +declare const symbolKey: unique symbol; + +type Example = { + // These index signatures will remain. + [x: string]: unknown; + [x: number]: unknown; + [x: symbol]: unknown; + [x: `head-${string}`]: string; + [x: `${string}-tail`]: string; + [x: `head-${string}-tail`]: string; + [x: `${bigint}`]: string; + [x: `embedded-${number}`]: string; + + // These explicitly defined keys will be removed. + ['snake-case-key']: string; + [symbolKey]: string; + foo: 'bar'; + qux?: 'baz'; +}; + +type ExampleIndexSignature = PickIndexSignature<Example>; +// { +// [x: string]: unknown; +// [x: number]: unknown; +// [x: symbol]: unknown; +// [x: `head-${string}`]: string; +// [x: `${string}-tail`]: string; +// [x: `head-${string}-tail`]: string; +// [x: `${bigint}`]: string; +// [x: `embedded-${number}`]: string; +// } +``` + +@example +``` +import type {OmitIndexSignature, PickIndexSignature, Simplify} from 'type-fest'; + +type Foo = { + [x: string]: string; + foo: string; + bar: number; +}; + +// Imagine that you want a new type `Bar` that comes from `Foo`. +// => { +// [x: string]: string; +// bar: number; +// }; + +type Bar = Omit<Foo, 'foo'>; +// This is not working because `Omit` returns only indexed keys. +// => { +// [x: string]: string; +// [x: number]: string; +// } + +// One solution is to save the indexed signatures to new type. +type FooIndexSignature = PickIndexSignature<Foo>; +// => { +// [x: string]: string; +// } + +// Get a new type without index signatures. +type FooWithoutIndexSignature = OmitIndexSignature<Foo>; +// => { +// foo: string; +// bar: number; +// } + +// At this point we can use Omit to get our new type. +type BarWithoutIndexSignature = Omit<FooWithoutIndexSignature, 'foo'>; +// => { +// bar: number; +// } + +// And finally we can merge back the indexed signatures. +type BarWithIndexSignature = Simplify<BarWithoutIndexSignature & FooIndexSignature>; +// => { +// [x: string]: string; +// bar: number; +// } +``` + +@see OmitIndexSignature +@category Object +*/ +export type PickIndexSignature<ObjectType> = { + [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> + ? KeyType + : never]: ObjectType[KeyType]; +}; diff --git a/node_modules/type-fest/source/primitive.d.ts b/node_modules/type-fest/source/primitive.d.ts new file mode 100644 index 0000000..71f9b8e --- /dev/null +++ b/node_modules/type-fest/source/primitive.d.ts @@ -0,0 +1,13 @@ +/** +Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive). + +@category Type +*/ +export type Primitive = + | null + | undefined + | string + | number + | boolean + | symbol + | bigint; diff --git a/node_modules/type-fest/source/promisable.d.ts b/node_modules/type-fest/source/promisable.d.ts new file mode 100644 index 0000000..9f3d6aa --- /dev/null +++ b/node_modules/type-fest/source/promisable.d.ts @@ -0,0 +1,25 @@ +/** +Create a type that represents either the value or the value wrapped in `PromiseLike`. + +Use-cases: +- A function accepts a callback that may either return a value synchronously or may return a promised value. +- This type could be the return type of `Promise#then()`, `Promise#catch()`, and `Promise#finally()` callbacks. + +Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/31394) if you want to have this type as a built-in in TypeScript. + +@example +``` +import type {Promisable} from 'type-fest'; + +async function logger(getLogEntry: () => Promisable<string>): Promise<void> { + const entry = await getLogEntry(); + console.log(entry); +} + +logger(() => 'foo'); +logger(() => Promise.resolve('bar')); +``` + +@category Async +*/ +export type Promisable<T> = T | PromiseLike<T>; diff --git a/node_modules/type-fest/source/readonly-deep.d.ts b/node_modules/type-fest/source/readonly-deep.d.ts new file mode 100644 index 0000000..a4f0c72 --- /dev/null +++ b/node_modules/type-fest/source/readonly-deep.d.ts @@ -0,0 +1,70 @@ +import type {BuiltIns, HasMultipleCallSignatures} from './internal'; + +/** +Convert `object`s, `Map`s, `Set`s, and `Array`s and all of their keys/elements into immutable structures recursively. + +This is useful when a deeply nested structure needs to be exposed as completely immutable, for example, an imported JSON module or when receiving an API response that is passed around. + +Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/13923) if you want to have this type as a built-in in TypeScript. + +@example +``` +// data.json +{ + "foo": ["bar"] +} + +// main.ts +import type {ReadonlyDeep} from 'type-fest'; +import dataJson = require('./data.json'); + +const data: ReadonlyDeep<typeof dataJson> = dataJson; + +export default data; + +// test.ts +import data from './main'; + +data.foo.push('bar'); +//=> error TS2339: Property 'push' does not exist on type 'readonly string[]' +``` + +Note that types containing overloaded functions are not made deeply readonly due to a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/29732). + +@category Object +@category Array +@category Set +@category Map +*/ +export type ReadonlyDeep<T> = T extends BuiltIns + ? T + : T extends (...arguments_: any[]) => unknown + ? {} extends ReadonlyObjectDeep<T> + ? T + : HasMultipleCallSignatures<T> extends true + ? T + : ((...arguments_: Parameters<T>) => ReturnType<T>) & ReadonlyObjectDeep<T> + : T extends Readonly<ReadonlyMap<infer KeyType, infer ValueType>> + ? ReadonlyMapDeep<KeyType, ValueType> + : T extends Readonly<ReadonlySet<infer ItemType>> + ? ReadonlySetDeep<ItemType> + : T extends object + ? ReadonlyObjectDeep<T> + : unknown; + +/** +Same as `ReadonlyDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `ReadonlyDeep`. +*/ +type ReadonlyMapDeep<KeyType, ValueType> = {} & Readonly<ReadonlyMap<ReadonlyDeep<KeyType>, ReadonlyDeep<ValueType>>>; + +/** +Same as `ReadonlyDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `ReadonlyDeep`. +*/ +type ReadonlySetDeep<ItemType> = {} & Readonly<ReadonlySet<ReadonlyDeep<ItemType>>>; + +/** +Same as `ReadonlyDeep`, but accepts only `object`s as inputs. Internal helper for `ReadonlyDeep`. +*/ +type ReadonlyObjectDeep<ObjectType extends object> = { + readonly [KeyType in keyof ObjectType]: ReadonlyDeep<ObjectType[KeyType]> +}; diff --git a/node_modules/type-fest/source/readonly-keys-of.d.ts b/node_modules/type-fest/source/readonly-keys-of.d.ts new file mode 100644 index 0000000..f7c31f4 --- /dev/null +++ b/node_modules/type-fest/source/readonly-keys-of.d.ts @@ -0,0 +1,29 @@ +import type {IsEqual} from './is-equal'; + +/** +Extract all readonly keys from the given type. + +This is useful when you want to create a new type that contains readonly keys only. + +@example +``` +import type {ReadonlyKeysOf} from 'type-fest'; + +interface User { + name: string; + surname: string; + readonly id: number; +} + +type UpdateResponse<Entity extends object> = Pick<Entity, ReadonlyKeysOf<Entity>>; + +const update1: UpdateResponse<User> = { + id: 123, +}; +``` + +@category Utilities +*/ +export type ReadonlyKeysOf<T> = NonNullable<{ + [P in keyof T]: IsEqual<{[Q in P]: T[P]}, {readonly [Q in P]: T[P]}> extends true ? P : never +}[keyof T]>; diff --git a/node_modules/type-fest/source/readonly-tuple.d.ts b/node_modules/type-fest/source/readonly-tuple.d.ts new file mode 100644 index 0000000..fd11073 --- /dev/null +++ b/node_modules/type-fest/source/readonly-tuple.d.ts @@ -0,0 +1,41 @@ +/** +Creates a read-only tuple of type `Element` and with the length of `Length`. + +@private +@see `ReadonlyTuple` which is safer because it tests if `Length` is a specific finite number. +*/ +type BuildTupleHelper<Element, Length extends number, Rest extends Element[]> = + Rest['length'] extends Length ? + readonly [...Rest] : // Terminate with readonly array (aka tuple) + BuildTupleHelper<Element, Length, [Element, ...Rest]>; + +/** +Create a type that represents a read-only tuple of the given type and length. + +Use-cases: +- Declaring fixed-length tuples with a large number of items. +- Creating a range union (for example, `0 | 1 | 2 | 3 | 4` from the keys of such a type) without having to resort to recursive types. +- Creating a tuple of coordinates with a static length, for example, length of 3 for a 3D vector. + +@example +``` +import {ReadonlyTuple} from 'type-fest'; + +type FencingTeam = ReadonlyTuple<string, 3>; + +const guestFencingTeam: FencingTeam = ['Josh', 'Michael', 'Robert']; + +const homeFencingTeam: FencingTeam = ['George', 'John']; +//=> error TS2322: Type string[] is not assignable to type 'FencingTeam' + +guestFencingTeam.push('Sam'); +//=> error TS2339: Property 'push' does not exist on type 'FencingTeam' +``` + +@category Utilities +*/ +export type ReadonlyTuple<Element, Length extends number> = + number extends Length + // Because `Length extends number` and `number extends Length`, then `Length` is not a specific finite number. + ? readonly Element[] // It's not fixed length. + : BuildTupleHelper<Element, Length, []>; // Otherwise it is a fixed length tuple. diff --git a/node_modules/type-fest/source/replace.d.ts b/node_modules/type-fest/source/replace.d.ts new file mode 100644 index 0000000..56c4876 --- /dev/null +++ b/node_modules/type-fest/source/replace.d.ts @@ -0,0 +1,67 @@ +type ReplaceOptions = { + all?: boolean; +}; + +/** +Represents a string with some or all matches replaced by a replacement. + +Use-case: +- `snake-case-path` to `dotted.path.notation` +- Changing date/time format: `01-08-2042` → `01/08/2042` +- Manipulation of type properties, for example, removal of prefixes + +@example +``` +import {Replace} from 'type-fest'; + +declare function replace< + Input extends string, + Search extends string, + Replacement extends string +>( + input: Input, + search: Search, + replacement: Replacement +): Replace<Input, Search, Replacement>; + +declare function replaceAll< + Input extends string, + Search extends string, + Replacement extends string +>( + input: Input, + search: Search, + replacement: Replacement +): Replace<Input, Search, Replacement, {all: true}>; + +// The return type is the exact string literal, not just `string`. + +replace('hello ?', '?', '🦄'); +//=> 'hello 🦄' + +replace('hello ??', '?', '❓'); +//=> 'hello ❓?' + +replaceAll('10:42:00', ':', '-'); +//=> '10-42-00' + +replaceAll('__userName__', '__', ''); +//=> 'userName' + +replaceAll('My Cool Title', ' ', ''); +//=> 'MyCoolTitle' +``` + +@category String +@category Template literal +*/ +export type Replace< + Input extends string, + Search extends string, + Replacement extends string, + Options extends ReplaceOptions = {}, +> = Input extends `${infer Head}${Search}${infer Tail}` + ? Options['all'] extends true + ? `${Head}${Replacement}${Replace<Tail, Search, Replacement, Options>}` + : `${Head}${Replacement}${Tail}` + : Input; diff --git a/node_modules/type-fest/source/require-all-or-none.d.ts b/node_modules/type-fest/source/require-all-or-none.d.ts new file mode 100644 index 0000000..4b50c2a --- /dev/null +++ b/node_modules/type-fest/source/require-all-or-none.d.ts @@ -0,0 +1,36 @@ +/** +Create a type that requires all of the given keys or none of the given keys. The remaining keys are kept as is. + +Use-cases: +- Creating interfaces for components with mutually-inclusive keys. + +The caveat with `RequireAllOrNone` is that TypeScript doesn't always know at compile time every key that will exist at runtime. Therefore `RequireAllOrNone` can't do anything to prevent extra keys it doesn't know about. + +@example +``` +import type {RequireAllOrNone} from 'type-fest'; + +type Responder = { + text?: () => string; + json?: () => string; + secure: boolean; +}; + +const responder1: RequireAllOrNone<Responder, 'text' | 'json'> = { + secure: true +}; + +const responder2: RequireAllOrNone<Responder, 'text' | 'json'> = { + text: () => '{"message": "hi"}', + json: () => '{"message": "ok"}', + secure: true +}; +``` + +@category Object +*/ +export type RequireAllOrNone<ObjectType, KeysType extends keyof ObjectType = never> = ( + | Required<Pick<ObjectType, KeysType>> // Require all of the given keys. + | Partial<Record<KeysType, never>> // Require none of the given keys. +) & +Omit<ObjectType, KeysType>; // The rest of the keys. diff --git a/node_modules/type-fest/source/require-at-least-one.d.ts b/node_modules/type-fest/source/require-at-least-one.d.ts new file mode 100644 index 0000000..c52e204 --- /dev/null +++ b/node_modules/type-fest/source/require-at-least-one.d.ts @@ -0,0 +1,34 @@ +import type {Except} from './except'; + +/** +Create a type that requires at least one of the given keys. The remaining keys are kept as is. + +@example +``` +import type {RequireAtLeastOne} from 'type-fest'; + +type Responder = { + text?: () => string; + json?: () => string; + secure?: boolean; +}; + +const responder: RequireAtLeastOne<Responder, 'text' | 'json'> = { + json: () => '{"message": "ok"}', + secure: true +}; +``` + +@category Object +*/ +export type RequireAtLeastOne< + ObjectType, + KeysType extends keyof ObjectType = keyof ObjectType, +> = { + // For each `Key` in `KeysType` make a mapped type: + [Key in KeysType]-?: Required<Pick<ObjectType, Key>> & // 1. Make `Key`'s type required + // 2. Make all other keys in `KeysType` optional + Partial<Pick<ObjectType, Exclude<KeysType, Key>>>; +}[KeysType] & +// 3. Add the remaining keys not in `KeysType` +Except<ObjectType, KeysType>; diff --git a/node_modules/type-fest/source/require-exactly-one.d.ts b/node_modules/type-fest/source/require-exactly-one.d.ts new file mode 100644 index 0000000..57a1a98 --- /dev/null +++ b/node_modules/type-fest/source/require-exactly-one.d.ts @@ -0,0 +1,34 @@ +/** +Create a type that requires exactly one of the given keys and disallows more. The remaining keys are kept as is. + +Use-cases: +- Creating interfaces for components that only need one of the keys to display properly. +- Declaring generic keys in a single place for a single use-case that gets narrowed down via `RequireExactlyOne`. + +The caveat with `RequireExactlyOne` is that TypeScript doesn't always know at compile time every key that will exist at runtime. Therefore `RequireExactlyOne` can't do anything to prevent extra keys it doesn't know about. + +@example +``` +import type {RequireExactlyOne} from 'type-fest'; + +type Responder = { + text: () => string; + json: () => string; + secure: boolean; +}; + +const responder: RequireExactlyOne<Responder, 'text' | 'json'> = { + // Adding a `text` key here would cause a compile error. + + json: () => '{"message": "ok"}', + secure: true +}; +``` + +@category Object +*/ +export type RequireExactlyOne<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> = + {[Key in KeysType]: ( + Required<Pick<ObjectType, Key>> & + Partial<Record<Exclude<KeysType, Key>, never>> + )}[KeysType] & Omit<ObjectType, KeysType>; diff --git a/node_modules/type-fest/source/required-deep.d.ts b/node_modules/type-fest/source/required-deep.d.ts new file mode 100644 index 0000000..75c959c --- /dev/null +++ b/node_modules/type-fest/source/required-deep.d.ts @@ -0,0 +1,78 @@ +import type {BuiltIns, HasMultipleCallSignatures} from './internal'; + +type ExcludeUndefined<T> = Exclude<T, undefined>; + +/** +Create a type from another type with all keys and nested keys set to required. + +Use-cases: +- Creating optional configuration interfaces where the underlying implementation still requires all options to be fully specified. +- Modeling the resulting type after a deep merge with a set of defaults. + +@example +``` +import type {RequiredDeep} from 'type-fest'; + +type Settings = { + textEditor?: { + fontSize?: number | undefined; + fontColor?: string | undefined; + fontWeight?: number | undefined; + } + autocomplete?: boolean | undefined; + autosave?: boolean | undefined; +}; + +type RequiredSettings = RequiredDeep<Settings>; +// type RequiredSettings = { +// textEditor: { +// fontSize: number; +// fontColor: string; +// fontWeight: number; +// } +// autocomplete: boolean; +// autosave: boolean; +// } +``` + +Note that types containing overloaded functions are not made deeply required due to a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/29732). + +@category Utilities +@category Object +@category Array +@category Set +@category Map +*/ +export type RequiredDeep<T, E extends ExcludeUndefined<T> = ExcludeUndefined<T>> = E extends BuiltIns + ? E + : E extends Map<infer KeyType, infer ValueType> + ? Map<RequiredDeep<KeyType>, RequiredDeep<ValueType>> + : E extends Set<infer ItemType> + ? Set<RequiredDeep<ItemType>> + : E extends ReadonlyMap<infer KeyType, infer ValueType> + ? ReadonlyMap<RequiredDeep<KeyType>, RequiredDeep<ValueType>> + : E extends ReadonlySet<infer ItemType> + ? ReadonlySet<RequiredDeep<ItemType>> + : E extends WeakMap<infer KeyType, infer ValueType> + ? WeakMap<RequiredDeep<KeyType>, RequiredDeep<ValueType>> + : E extends WeakSet<infer ItemType> + ? WeakSet<RequiredDeep<ItemType>> + : E extends Promise<infer ValueType> + ? Promise<RequiredDeep<ValueType>> + : E extends (...arguments_: any[]) => unknown + ? {} extends RequiredObjectDeep<E> + ? E + : HasMultipleCallSignatures<E> extends true + ? E + : ((...arguments_: Parameters<E>) => ReturnType<E>) & RequiredObjectDeep<E> + : E extends object + ? E extends Array<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156 + ? ItemType[] extends E // Test for arrays (non-tuples) specifically + ? Array<RequiredDeep<ItemType>> // Recreate relevant array type to prevent eager evaluation of circular reference + : RequiredObjectDeep<E> // Tuples behave properly + : RequiredObjectDeep<E> + : unknown; + +type RequiredObjectDeep<ObjectType extends object> = { + [KeyType in keyof ObjectType]-?: RequiredDeep<ObjectType[KeyType]> +}; diff --git a/node_modules/type-fest/source/required-keys-of.d.ts b/node_modules/type-fest/source/required-keys-of.d.ts new file mode 100644 index 0000000..6e66b15 --- /dev/null +++ b/node_modules/type-fest/source/required-keys-of.d.ts @@ -0,0 +1,29 @@ +/** +Extract all required keys from the given type. + +This is useful when you want to create a new type that contains different type values for the required keys only or use the list of keys for validation purposes, etc... + +@example +``` +import type {RequiredKeysOf} from 'type-fest'; + +declare function createValidation<Entity extends object, Key extends RequiredKeysOf<Entity> = RequiredKeysOf<Entity>>(field: Key, validator: (value: Entity[Key]) => boolean): ValidatorFn; + +interface User { + name: string; + surname: string; + + luckyNumber?: number; +} + +const validator1 = createValidation<User>('name', value => value.length < 25); +const validator2 = createValidation<User>('surname', value => value.length < 25); +``` + +@category Utilities +*/ +export type RequiredKeysOf<BaseType extends object> = Exclude<{ + [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]> + ? Key + : never +}[keyof BaseType], undefined>; diff --git a/node_modules/type-fest/source/schema.d.ts b/node_modules/type-fest/source/schema.d.ts new file mode 100644 index 0000000..364192f --- /dev/null +++ b/node_modules/type-fest/source/schema.d.ts @@ -0,0 +1,71 @@ +/** +Create a deep version of another object type where property values are recursively replaced into a given value type. + +Use-cases: +- Form validation: Define how each field should be validated. +- Form settings: Define configuration for input fields. +- Parsing: Define types that specify special behavior for specific fields. + +@example +``` +import type {Schema} from 'type-fest'; + +interface User { + id: string; + name: { + firstname: string; + lastname: string; + }; + created: Date; + active: boolean; + passwordHash: string; +} + +type UserMask = Schema<User, 'mask' | 'hide' | 'show'>; + +const userMaskSettings: UserMask = { + id: 'show', + name: { + firstname: 'show', + lastname: 'mask', + }, + created: 'show', + active: 'show', + passwordHash: 'hide', +} +``` + +@category Object +*/ +export type Schema<ObjectType, ValueType> = ObjectType extends string + ? ValueType + : ObjectType extends Map<unknown, unknown> + ? ValueType + : ObjectType extends Set<unknown> + ? ValueType + : ObjectType extends ReadonlyMap<unknown, unknown> + ? ValueType + : ObjectType extends ReadonlySet<unknown> + ? ValueType + : ObjectType extends readonly unknown[] + ? ValueType + : ObjectType extends unknown[] + ? ValueType + : ObjectType extends (...arguments_: unknown[]) => unknown + ? ValueType + : ObjectType extends Date + ? ValueType + : ObjectType extends Function + ? ValueType + : ObjectType extends RegExp + ? ValueType + : ObjectType extends object + ? SchemaObject<ObjectType, ValueType> + : ValueType; + +/** +Same as `Schema`, but accepts only `object`s as inputs. Internal helper for `Schema`. +*/ +type SchemaObject<ObjectType extends object, K> = { + [KeyType in keyof ObjectType]: Schema<ObjectType[KeyType], K> | K; +}; diff --git a/node_modules/type-fest/source/screaming-snake-case.d.ts b/node_modules/type-fest/source/screaming-snake-case.d.ts new file mode 100644 index 0000000..9359962 --- /dev/null +++ b/node_modules/type-fest/source/screaming-snake-case.d.ts @@ -0,0 +1,33 @@ +import type {SplitIncludingDelimiters} from './delimiter-case'; +import type {SnakeCase} from './snake-case'; +import type {Includes} from './includes'; + +/** +Returns a boolean for whether the string is screaming snake case. +*/ +type IsScreamingSnakeCase<Value extends string> = Value extends Uppercase<Value> + ? Includes<SplitIncludingDelimiters<Lowercase<Value>, '_'>, '_'> extends true + ? true + : false + : false; + +/** +Convert a string literal to screaming-snake-case. + +This can be useful when, for example, converting a camel-cased object property to a screaming-snake-cased SQL column name. + +@example +``` +import type {ScreamingSnakeCase} from 'type-fest'; + +const someVariable: ScreamingSnakeCase<'fooBar'> = 'FOO_BAR'; +``` + +@category Change case +@category Template literal +*/ +export type ScreamingSnakeCase<Value> = Value extends string + ? IsScreamingSnakeCase<Value> extends true + ? Value + : Uppercase<SnakeCase<Value>> + : Value; diff --git a/node_modules/type-fest/source/set-non-nullable.d.ts b/node_modules/type-fest/source/set-non-nullable.d.ts new file mode 100644 index 0000000..2064411 --- /dev/null +++ b/node_modules/type-fest/source/set-non-nullable.d.ts @@ -0,0 +1,39 @@ +/** +Create a type that makes the given keys non-nullable, where the remaining keys are kept as is. + +If no keys are given, all keys will be made non-nullable. + +Use-case: You want to define a single model where the only thing that changes is whether or not some or all of the keys are non-nullable. + +@example +``` +import type {SetNonNullable} from 'type-fest'; + +type Foo = { + a: number | null; + b: string | undefined; + c?: boolean | null; +} + +type SomeNonNullable = SetNonNullable<Foo, 'b' | 'c'>; +// type SomeNonNullable = { +// a: number | null; +// b: string; // Can no longer be undefined. +// c?: boolean; // Can no longer be null, but is still optional. +// } + +type AllNonNullable = SetNonNullable<Foo>; +// type AllNonNullable = { +// a: number; // Can no longer be null. +// b: string; // Can no longer be undefined. +// c?: boolean; // Can no longer be null, but is still optional. +// } +``` + +@category Object +*/ +export type SetNonNullable<BaseType, Keys extends keyof BaseType = keyof BaseType> = { + [Key in keyof BaseType]: Key extends Keys + ? NonNullable<BaseType[Key]> + : BaseType[Key]; +}; diff --git a/node_modules/type-fest/source/set-optional.d.ts b/node_modules/type-fest/source/set-optional.d.ts new file mode 100644 index 0000000..224004d --- /dev/null +++ b/node_modules/type-fest/source/set-optional.d.ts @@ -0,0 +1,35 @@ +import type {Except} from './except'; +import type {Simplify} from './simplify'; + +/** +Create a type that makes the given keys optional. The remaining keys are kept as is. The sister of the `SetRequired` type. + +Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are optional. + +@example +``` +import type {SetOptional} from 'type-fest'; + +type Foo = { + a: number; + b?: string; + c: boolean; +} + +type SomeOptional = SetOptional<Foo, 'b' | 'c'>; +// type SomeOptional = { +// a: number; +// b?: string; // Was already optional and still is. +// c?: boolean; // Is now optional. +// } +``` + +@category Object +*/ +export type SetOptional<BaseType, Keys extends keyof BaseType> = + Simplify< + // Pick just the keys that are readonly from the base type. + Except<BaseType, Keys> & + // Pick the keys that should be mutable from the base type and make them mutable. + Partial<Pick<BaseType, Keys>> + >; diff --git a/node_modules/type-fest/source/set-readonly.d.ts b/node_modules/type-fest/source/set-readonly.d.ts new file mode 100644 index 0000000..f8f4aa9 --- /dev/null +++ b/node_modules/type-fest/source/set-readonly.d.ts @@ -0,0 +1,38 @@ +import type {Except} from './except'; +import type {Simplify} from './simplify'; + +/** +Create a type that makes the given keys readonly. The remaining keys are kept as is. + +Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are readonly. + +@example +``` +import type {SetReadonly} from 'type-fest'; + +type Foo = { + a: number; + readonly b: string; + c: boolean; +} + +type SomeReadonly = SetReadonly<Foo, 'b' | 'c'>; +// type SomeReadonly = { +// a: number; +// readonly b: string; // Was already readonly and still is. +// readonly c: boolean; // Is now readonly. +// } +``` + +@category Object +*/ +export type SetReadonly<BaseType, Keys extends keyof BaseType> = + // `extends unknown` is always going to be the case and is used to convert any + // union into a [distributive conditional + // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). + BaseType extends unknown + ? Simplify< + Except<BaseType, Keys> & + Readonly<Pick<BaseType, Keys>> + > + : never; diff --git a/node_modules/type-fest/source/set-required.d.ts b/node_modules/type-fest/source/set-required.d.ts new file mode 100644 index 0000000..735c227 --- /dev/null +++ b/node_modules/type-fest/source/set-required.d.ts @@ -0,0 +1,40 @@ +import type {Except} from './except'; +import type {Simplify} from './simplify'; + +/** +Create a type that makes the given keys required. The remaining keys are kept as is. The sister of the `SetOptional` type. + +Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required. + +@example +``` +import type {SetRequired} from 'type-fest'; + +type Foo = { + a?: number; + b: string; + c?: boolean; +} + +type SomeRequired = SetRequired<Foo, 'b' | 'c'>; +// type SomeRequired = { +// a?: number; +// b: string; // Was already required and still is. +// c: boolean; // Is now required. +// } +``` + +@category Object +*/ +export type SetRequired<BaseType, Keys extends keyof BaseType> = + // `extends unknown` is always going to be the case and is used to convert any + // union into a [distributive conditional + // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). + BaseType extends unknown + ? Simplify< + // Pick just the keys that are optional from the base type. + Except<BaseType, Keys> & + // Pick the keys that should be required from the base type and make them required. + Required<Pick<BaseType, Keys>> + > + : never; diff --git a/node_modules/type-fest/source/set-return-type.d.ts b/node_modules/type-fest/source/set-return-type.d.ts new file mode 100644 index 0000000..3081a84 --- /dev/null +++ b/node_modules/type-fest/source/set-return-type.d.ts @@ -0,0 +1,29 @@ +import type {IsUnknown} from './is-unknown'; + +/** +Create a function type with a return type of your choice and the same parameters as the given function type. + +Use-case: You want to define a wrapped function that returns something different while receiving the same parameters. For example, you might want to wrap a function that can throw an error into one that will return `undefined` instead. + +@example +``` +import type {SetReturnType} from 'type-fest'; + +type MyFunctionThatCanThrow = (foo: SomeType, bar: unknown) => SomeOtherType; + +type MyWrappedFunction = SetReturnType<MyFunctionThatCanThrow, SomeOtherType | undefined>; +//=> type MyWrappedFunction = (foo: SomeType, bar: unknown) => SomeOtherType | undefined; +``` + +@category Function +*/ +export type SetReturnType<Fn extends (...arguments_: any[]) => any, TypeToReturn> = + // Just using `Parameters<Fn>` isn't ideal because it doesn't handle the `this` fake parameter. + Fn extends (this: infer ThisArg, ...arguments_: infer Arguments) => any ? ( + // If a function did not specify the `this` fake parameter, it will be inferred to `unknown`. + // We want to detect this situation just to display a friendlier type upon hovering on an IntelliSense-powered IDE. + IsUnknown<ThisArg> extends true ? (...arguments_: Arguments) => TypeToReturn : (this: ThisArg, ...arguments_: Arguments) => TypeToReturn + ) : ( + // This part should be unreachable, but we make it meaningful just in case… + (...arguments_: Parameters<Fn>) => TypeToReturn + ); diff --git a/node_modules/type-fest/source/simplify.d.ts b/node_modules/type-fest/source/simplify.d.ts new file mode 100644 index 0000000..a456364 --- /dev/null +++ b/node_modules/type-fest/source/simplify.d.ts @@ -0,0 +1,58 @@ +/** +Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability. + +@example +``` +import type {Simplify} from 'type-fest'; + +type PositionProps = { + top: number; + left: number; +}; + +type SizeProps = { + width: number; + height: number; +}; + +// In your editor, hovering over `Props` will show a flattened object with all the properties. +type Props = Simplify<PositionProps & SizeProps>; +``` + +Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record<string, unknown>`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface. + +If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify<SomeInterface> = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify<SomeInterface>` if you can't re-declare the `value`. + +@example +``` +import type {Simplify} from 'type-fest'; + +interface SomeInterface { + foo: number; + bar?: string; + baz: number | undefined; +} + +type SomeType = { + foo: number; + bar?: string; + baz: number | undefined; +}; + +const literal = {foo: 123, bar: 'hello', baz: 456}; +const someType: SomeType = literal; +const someInterface: SomeInterface = literal; + +function fn(object: Record<string, unknown>): void {} + +fn(literal); // Good: literal object type is sealed +fn(someType); // Good: type is sealed +fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened +fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type` +``` + +@link https://github.com/microsoft/TypeScript/issues/15300 + +@category Object +*/ +export type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {}; diff --git a/node_modules/type-fest/source/snake-case.d.ts b/node_modules/type-fest/source/snake-case.d.ts new file mode 100644 index 0000000..5a0674c --- /dev/null +++ b/node_modules/type-fest/source/snake-case.d.ts @@ -0,0 +1,38 @@ +import type {DelimiterCase} from './delimiter-case'; + +/** +Convert a string literal to snake-case. + +This can be useful when, for example, converting a camel-cased object property to a snake-cased SQL column name. + +@example +``` +import type {SnakeCase} from 'type-fest'; + +// Simple + +const someVariable: SnakeCase<'fooBar'> = 'foo_bar'; + +// Advanced + +type SnakeCasedProperties<T> = { + [K in keyof T as SnakeCase<K>]: T[K] +}; + +interface ModelProps { + isHappy: boolean; + fullFamilyName: string; + foo: number; +} + +const dbResult: SnakeCasedProperties<ModelProps> = { + 'is_happy': true, + 'full_family_name': 'Carla Smith', + foo: 123 +}; +``` + +@category Change case +@category Template literal +*/ +export type SnakeCase<Value> = DelimiterCase<Value, '_'>; diff --git a/node_modules/type-fest/source/snake-cased-properties-deep.d.ts b/node_modules/type-fest/source/snake-cased-properties-deep.d.ts new file mode 100644 index 0000000..9e7ee3d --- /dev/null +++ b/node_modules/type-fest/source/snake-cased-properties-deep.d.ts @@ -0,0 +1,47 @@ +import type {DelimiterCasedPropertiesDeep} from './delimiter-cased-properties-deep'; + +/** +Convert object properties to snake case recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see SnakeCase +@see SnakeCasedProperties + +@example +``` +import type {SnakeCasedPropertiesDeep} from 'type-fest'; + +interface User { + userId: number; + userName: string; +} + +interface UserWithFriends { + userInfo: User; + userFriends: User[]; +} + +const result: SnakeCasedPropertiesDeep<UserWithFriends> = { + user_info: { + user_id: 1, + user_name: 'Tom', + }, + user_friends: [ + { + user_id: 2, + user_name: 'Jerry', + }, + { + user_id: 3, + user_name: 'Spike', + }, + ], +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type SnakeCasedPropertiesDeep<Value> = DelimiterCasedPropertiesDeep<Value, '_'>; diff --git a/node_modules/type-fest/source/snake-cased-properties.d.ts b/node_modules/type-fest/source/snake-cased-properties.d.ts new file mode 100644 index 0000000..a1c3660 --- /dev/null +++ b/node_modules/type-fest/source/snake-cased-properties.d.ts @@ -0,0 +1,30 @@ +import type {DelimiterCasedProperties} from './delimiter-cased-properties'; + +/** +Convert object properties to snake case but not recursively. + +This can be useful when, for example, converting some API types from a different style. + +@see SnakeCase +@see SnakeCasedPropertiesDeep + +@example +``` +import type {SnakeCasedProperties} from 'type-fest'; + +interface User { + userId: number; + userName: string; +} + +const result: SnakeCasedProperties<User> = { + user_id: 1, + user_name: 'Tom', +}; +``` + +@category Change case +@category Template literal +@category Object +*/ +export type SnakeCasedProperties<Value> = DelimiterCasedProperties<Value, '_'>; diff --git a/node_modules/type-fest/source/split-words.d.ts b/node_modules/type-fest/source/split-words.d.ts new file mode 100644 index 0000000..dd9ca2b --- /dev/null +++ b/node_modules/type-fest/source/split-words.d.ts @@ -0,0 +1,57 @@ +import type {IsLowerCase, IsNumeric, IsUpperCase, WordSeparators} from './internal'; + +type SkipEmptyWord<Word extends string> = Word extends '' ? [] : [Word]; + +type RemoveLastCharacter<Sentence extends string, Character extends string> = Sentence extends `${infer LeftSide}${Character}` + ? SkipEmptyWord<LeftSide> + : never; + +/** +Split a string (almost) like Lodash's `_.words()` function. + +- Split on each word that begins with a capital letter. +- Split on each {@link WordSeparators}. +- Split on numeric sequence. + +@example +``` +type Words0 = SplitWords<'helloWorld'>; // ['hello', 'World'] +type Words1 = SplitWords<'helloWORLD'>; // ['hello', 'WORLD'] +type Words2 = SplitWords<'hello-world'>; // ['hello', 'world'] +type Words3 = SplitWords<'--hello the_world'>; // ['hello', 'the', 'world'] +type Words4 = SplitWords<'lifeIs42'>; // ['life', 'Is', '42'] +``` + +@internal +@category Change case +@category Template literal +*/ +export type SplitWords< + Sentence extends string, + LastCharacter extends string = '', + CurrentWord extends string = '', +> = Sentence extends `${infer FirstCharacter}${infer RemainingCharacters}` + ? FirstCharacter extends WordSeparators + // Skip word separator + ? [...SkipEmptyWord<CurrentWord>, ...SplitWords<RemainingCharacters>] + : LastCharacter extends '' + // Fist char of word + ? SplitWords<RemainingCharacters, FirstCharacter, FirstCharacter> + // Case change: non-numeric to numeric, push word + : [false, true] extends [IsNumeric<LastCharacter>, IsNumeric<FirstCharacter>] + ? [...SkipEmptyWord<CurrentWord>, ...SplitWords<RemainingCharacters, FirstCharacter, FirstCharacter>] + // Case change: numeric to non-numeric, push word + : [true, false] extends [IsNumeric<LastCharacter>, IsNumeric<FirstCharacter>] + ? [...SkipEmptyWord<CurrentWord>, ...SplitWords<RemainingCharacters, FirstCharacter, FirstCharacter>] + // No case change: concat word + : [true, true] extends [IsNumeric<LastCharacter>, IsNumeric<FirstCharacter>] + ? SplitWords<RemainingCharacters, FirstCharacter, `${CurrentWord}${FirstCharacter}`> + // Case change: lower to upper, push word + : [true, true] extends [IsLowerCase<LastCharacter>, IsUpperCase<FirstCharacter>] + ? [...SkipEmptyWord<CurrentWord>, ...SplitWords<RemainingCharacters, FirstCharacter, FirstCharacter>] + // Case change: upper to lower, brings back the last character, push word + : [true, true] extends [IsUpperCase<LastCharacter>, IsLowerCase<FirstCharacter>] + ? [...RemoveLastCharacter<CurrentWord, LastCharacter>, ...SplitWords<RemainingCharacters, FirstCharacter, `${LastCharacter}${FirstCharacter}`>] + // No case change: concat word + : SplitWords<RemainingCharacters, FirstCharacter, `${CurrentWord}${FirstCharacter}`> + : [...SkipEmptyWord<CurrentWord>]; diff --git a/node_modules/type-fest/source/split.d.ts b/node_modules/type-fest/source/split.d.ts new file mode 100644 index 0000000..d7b5d71 --- /dev/null +++ b/node_modules/type-fest/source/split.d.ts @@ -0,0 +1,29 @@ +/** +Represents an array of strings split using a given character or character set. + +Use-case: Defining the return type of a method like `String.prototype.split`. + +@example +``` +import type {Split} from 'type-fest'; + +declare function split<S extends string, D extends string>(string: S, separator: D): Split<S, D>; + +type Item = 'foo' | 'bar' | 'baz' | 'waldo'; +const items = 'foo,bar,baz,waldo'; +let array: Item[]; + +array = split(items, ','); +``` + +@category String +@category Template literal +*/ +export type Split< + S extends string, + Delimiter extends string, +> = S extends `${infer Head}${Delimiter}${infer Tail}` + ? [Head, ...Split<Tail, Delimiter>] + : S extends Delimiter + ? [] + : [S]; diff --git a/node_modules/type-fest/source/spread.d.ts b/node_modules/type-fest/source/spread.d.ts new file mode 100644 index 0000000..b182611 --- /dev/null +++ b/node_modules/type-fest/source/spread.d.ts @@ -0,0 +1,85 @@ +import type {Except} from './except'; +import type {RequiredKeysOf} from './required-keys-of'; +import type {Simplify} from './simplify'; + +type SpreadObject<FirstType extends object, SecondType extends object> = { + [Key in keyof FirstType]: Key extends keyof SecondType + ? FirstType[Key] | Required<SecondType>[Key] + : FirstType[Key]; +} & Pick< +SecondType, +RequiredKeysOf<SecondType> | Exclude<keyof SecondType, keyof FirstType> +>; + +type TupleOrArray = readonly [...unknown[]]; + +type SpreadTupleOrArray< + FirstType extends TupleOrArray, + SecondType extends TupleOrArray, +> = Array<FirstType[number] | SecondType[number]>; + +type Spreadable = object | TupleOrArray; + +/** +Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax. + +@example +``` +import type {Spread} from 'type-fest'; + +type Foo = { + a: number; + b?: string; +}; + +type Bar = { + b?: number; + c: boolean; +}; + +const foo = {a: 1, b: '2'}; +const bar = {c: false}; +const fooBar = {...foo, ...bar}; + +type FooBar = Spread<Foo, Bar>; +// type FooBar = { +// a: number; +// b?: string | number | undefined; +// c: boolean; +// } + +const baz = (argument: FooBar) => { + // Do something +} + +baz(fooBar); +``` + +@example +``` +import type {Spread} from 'type-fest'; + +const foo = [1, 2, 3]; +const bar = ['4', '5', '6']; + +const fooBar = [...foo, ...bar]; +type FooBar = Spread<typeof foo, typeof bar>; +// FooBar = (string | number)[] + +const baz = (argument: FooBar) => { + // Do something +}; + +baz(fooBar); +``` + +@category Object +*/ +export type Spread< + FirstType extends Spreadable, + SecondType extends Spreadable, +> = FirstType extends TupleOrArray + ? SecondType extends TupleOrArray + ? SpreadTupleOrArray<FirstType, SecondType> + : Simplify<SpreadObject<FirstType, SecondType>> + : Simplify<SpreadObject<FirstType, SecondType>>; diff --git a/node_modules/type-fest/source/string-key-of.d.ts b/node_modules/type-fest/source/string-key-of.d.ts new file mode 100644 index 0000000..25342d7 --- /dev/null +++ b/node_modules/type-fest/source/string-key-of.d.ts @@ -0,0 +1,25 @@ +/** +Get keys of the given type as strings. + +Number keys are converted to strings. + +Use-cases: +- Get string keys from a type which may have number keys. +- Makes it possible to index using strings retrieved from template types. + +@example +``` +import type {StringKeyOf} from 'type-fest'; + +type Foo = { + 1: number, + stringKey: string, +}; + +type StringKeysOfFoo = StringKeyOf<Foo>; +//=> '1' | 'stringKey' +``` + +@category Object +*/ +export type StringKeyOf<BaseType> = `${Extract<keyof BaseType, string | number>}`; diff --git a/node_modules/type-fest/source/stringified.d.ts b/node_modules/type-fest/source/stringified.d.ts new file mode 100644 index 0000000..fd6370c --- /dev/null +++ b/node_modules/type-fest/source/stringified.d.ts @@ -0,0 +1,23 @@ +/** +Create a type with the keys of the given type changed to `string` type. + +Use-case: Changing interface values to strings in order to use them in a form model. + +@example +``` +import type {Stringified} from 'type-fest'; + +type Car = { + model: string; + speed: number; +} + +const carForm: Stringified<Car> = { + model: 'Foo', + speed: '101' +}; +``` + +@category Object +*/ +export type Stringified<ObjectType> = {[KeyType in keyof ObjectType]: string}; diff --git a/node_modules/type-fest/source/tagged-union.d.ts b/node_modules/type-fest/source/tagged-union.d.ts new file mode 100644 index 0000000..57ae530 --- /dev/null +++ b/node_modules/type-fest/source/tagged-union.d.ts @@ -0,0 +1,51 @@ +/** +Create a union of types that share a common discriminant property. + +Use-case: A shorter way to declare tagged unions with multiple members. + +@example +``` +import type {TaggedUnion} from 'type-fest'; + +type Tagged<Fields extends Record<string, unknown> = TaggedUnion<'type', Fields> + +// The TaggedUnion utility reduces the amount of boilerplate needed to create a tagged union with multiple members, making the code more concise. +type EventMessage = Tagged<{ + OpenExternalUrl: { + url: string; + id: number; + language: string; + }; + ToggleBackButtonVisibility: { + visible: boolean; + }; + PurchaseButtonPressed: { + price: number; + time: Date; + }; + NavigationStateChanged: { + navigation?: string; + }; +}>; + +// Here is the same type created without this utility. +type EventMessage = + | { + type: 'OpenExternalUrl'; + url: string; + id: number; + language: string; + } + | {type: 'ToggleBackButtonVisibility'; visible: boolean} + | {type: 'PurchaseButtonPressed'; price: number; time: Date} + | {type: 'NavigationStateChanged'; navigation?: string}; +``` + +@category Utilities +*/ +export type TaggedUnion< + TagKey extends string, + UnionMembers extends Record<string, Record<string, unknown>>, +> = { + [Name in keyof UnionMembers]: {[Key in TagKey]: Name} & UnionMembers[Name]; +}[keyof UnionMembers]; diff --git a/node_modules/type-fest/source/trim.d.ts b/node_modules/type-fest/source/trim.d.ts new file mode 100644 index 0000000..d4bf483 --- /dev/null +++ b/node_modules/type-fest/source/trim.d.ts @@ -0,0 +1,27 @@ +import type {Whitespace} from './internal'; + +/** +Remove spaces from the left side. +*/ +type TrimLeft<V extends string> = V extends `${Whitespace}${infer R}` ? TrimLeft<R> : V; + +/** +Remove spaces from the right side. +*/ +type TrimRight<V extends string> = V extends `${infer R}${Whitespace}` ? TrimRight<R> : V; + +/** +Remove leading and trailing spaces from a string. + +@example +``` +import type {Trim} from 'type-fest'; + +Trim<' foo '> +//=> 'foo' +``` + +@category String +@category Template literal +*/ +export type Trim<V extends string> = TrimLeft<TrimRight<V>>; diff --git a/node_modules/type-fest/source/tsconfig-json.d.ts b/node_modules/type-fest/source/tsconfig-json.d.ts new file mode 100644 index 0000000..d3e5a30 --- /dev/null +++ b/node_modules/type-fest/source/tsconfig-json.d.ts @@ -0,0 +1,1179 @@ +declare namespace TsConfigJson { + namespace CompilerOptions { + export type JSX = + | 'preserve' + | 'react' + | 'react-jsx' + | 'react-jsxdev' + | 'react-native'; + + export type Module = + | 'CommonJS' + | 'AMD' + | 'System' + | 'UMD' + | 'ES6' + | 'ES2015' + | 'ES2020' + | 'ES2022' + | 'ESNext' + | 'Node16' + | 'NodeNext' + | 'None' + // Lowercase alternatives + | 'commonjs' + | 'amd' + | 'system' + | 'umd' + | 'es6' + | 'es2015' + | 'es2020' + | 'es2022' + | 'esnext' + | 'node16' + | 'nodenext' + | 'none'; + + export type NewLine = + | 'CRLF' + | 'LF' + // Lowercase alternatives + | 'crlf' + | 'lf'; + + export type Target = + | 'ES3' + | 'ES5' + | 'ES6' + | 'ES2015' + | 'ES2016' + | 'ES2017' + | 'ES2018' + | 'ES2019' + | 'ES2020' + | 'ES2021' + | 'ES2022' + | 'ESNext' + // Lowercase alternatives + | 'es3' + | 'es5' + | 'es6' + | 'es2015' + | 'es2016' + | 'es2017' + | 'es2018' + | 'es2019' + | 'es2020' + | 'es2021' + | 'es2022' + | 'esnext'; + + export type Lib = + | 'ES5' + | 'ES6' + | 'ES7' + | 'ES2015' + | 'ES2015.Collection' + | 'ES2015.Core' + | 'ES2015.Generator' + | 'ES2015.Iterable' + | 'ES2015.Promise' + | 'ES2015.Proxy' + | 'ES2015.Reflect' + | 'ES2015.Symbol.WellKnown' + | 'ES2015.Symbol' + | 'ES2016' + | 'ES2016.Array.Include' + | 'ES2017' + | 'ES2017.Intl' + | 'ES2017.Object' + | 'ES2017.SharedMemory' + | 'ES2017.String' + | 'ES2017.TypedArrays' + | 'ES2018' + | 'ES2018.AsyncGenerator' + | 'ES2018.AsyncIterable' + | 'ES2018.Intl' + | 'ES2018.Promise' + | 'ES2018.Regexp' + | 'ES2019' + | 'ES2019.Array' + | 'ES2019.Object' + | 'ES2019.String' + | 'ES2019.Symbol' + | 'ES2020' + | 'ES2020.BigInt' + | 'ES2020.Promise' + | 'ES2020.String' + | 'ES2020.Symbol.WellKnown' + | 'ES2020.SharedMemory' + | 'ES2020.Intl' + | 'ES2021' + | 'ES2021.Promise' + | 'ES2021.String' + | 'ES2021.WeakRef' + | 'ESNext' + | 'ESNext.Array' + | 'ESNext.AsyncIterable' + | 'ESNext.BigInt' + | 'ESNext.Intl' + | 'ESNext.Promise' + | 'ESNext.String' + | 'ESNext.Symbol' + | 'ESNext.WeakRef' + | 'DOM' + | 'DOM.Iterable' + | 'ScriptHost' + | 'WebWorker' + | 'WebWorker.ImportScripts' + | 'WebWorker.Iterable' + // Lowercase alternatives + | 'es5' + | 'es6' + | 'es7' + | 'es2015' + | 'es2015.collection' + | 'es2015.core' + | 'es2015.generator' + | 'es2015.iterable' + | 'es2015.promise' + | 'es2015.proxy' + | 'es2015.reflect' + | 'es2015.symbol.wellknown' + | 'es2015.symbol' + | 'es2016' + | 'es2016.array.include' + | 'es2017' + | 'es2017.intl' + | 'es2017.object' + | 'es2017.sharedmemory' + | 'es2017.string' + | 'es2017.typedarrays' + | 'es2018' + | 'es2018.asyncgenerator' + | 'es2018.asynciterable' + | 'es2018.intl' + | 'es2018.promise' + | 'es2018.regexp' + | 'es2019' + | 'es2019.array' + | 'es2019.object' + | 'es2019.string' + | 'es2019.symbol' + | 'es2020' + | 'es2020.bigint' + | 'es2020.promise' + | 'es2020.string' + | 'es2020.symbol.wellknown' + | 'es2020.sharedmemory' + | 'es2020.intl' + | 'es2021' + | 'es2021.promise' + | 'es2021.string' + | 'es2021.weakref' + | 'esnext' + | 'esnext.array' + | 'esnext.asynciterable' + | 'esnext.bigint' + | 'esnext.intl' + | 'esnext.promise' + | 'esnext.string' + | 'esnext.symbol' + | 'esnext.weakref' + | 'dom' + | 'dom.iterable' + | 'scripthost' + | 'webworker' + | 'webworker.importscripts' + | 'webworker.iterable'; + + export type Plugin = { + /** + Plugin name. + */ + name: string; + }; + + export type ImportsNotUsedAsValues = + | 'remove' + | 'preserve' + | 'error'; + + export type FallbackPolling = + | 'fixedPollingInterval' + | 'priorityPollingInterval' + | 'dynamicPriorityPolling' + | 'fixedInterval' + | 'priorityInterval' + | 'dynamicPriority' + | 'fixedChunkSize'; + + export type WatchDirectory = + | 'useFsEvents' + | 'fixedPollingInterval' + | 'dynamicPriorityPolling' + | 'fixedChunkSizePolling'; + + export type WatchFile = + | 'fixedPollingInterval' + | 'priorityPollingInterval' + | 'dynamicPriorityPolling' + | 'useFsEvents' + | 'useFsEventsOnParentDirectory' + | 'fixedChunkSizePolling'; + + export type ModuleResolution = + | 'classic' + | 'node' + | 'node10' + | 'node16' + | 'nodenext' + | 'bundler' + // Pascal-cased alternatives + | 'Classic' + | 'Node' + | 'Node10' + | 'Node16' + | 'NodeNext' + | 'Bundler'; + + export type ModuleDetection = + | 'auto' + | 'legacy' + | 'force'; + + export type IgnoreDeprecations = '5.0'; + } + + export type CompilerOptions = { + /** + The character set of the input files. + + @default 'utf8' + @deprecated This option will be removed in TypeScript 5.5. + */ + charset?: string; + + /** + Enables building for project references. + + @default true + */ + composite?: boolean; + + /** + Generates corresponding d.ts files. + + @default false + */ + declaration?: boolean; + + /** + Specify output directory for generated declaration files. + */ + declarationDir?: string; + + /** + Show diagnostic information. + + @default false + */ + diagnostics?: boolean; + + /** + Reduce the number of projects loaded automatically by TypeScript. + + @default false + */ + disableReferencedProjectLoad?: boolean; + + /** + Enforces using indexed accessors for keys declared using an indexed type. + + @default false + */ + noPropertyAccessFromIndexSignature?: boolean; + + /** + Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. + + @default false + */ + emitBOM?: boolean; + + /** + Only emit `.d.ts` declaration files. + + @default false + */ + emitDeclarationOnly?: boolean; + + /** + Differentiate between undefined and not present when type checking. + + @default false + */ + exactOptionalPropertyTypes?: boolean; + + /** + Enable incremental compilation. + + @default `composite` + */ + incremental?: boolean; + + /** + Specify file to store incremental compilation information. + + @default '.tsbuildinfo' + */ + tsBuildInfoFile?: string; + + /** + Emit a single file with source maps instead of having a separate file. + + @default false + */ + inlineSourceMap?: boolean; + + /** + Emit the source alongside the sourcemaps within a single file. + + Requires `--inlineSourceMap` to be set. + + @default false + */ + inlineSources?: boolean; + + /** + Specify what JSX code is generated. + + @default 'preserve' + */ + jsx?: CompilerOptions.JSX; + + /** + Specifies the object invoked for `createElement` and `__spread` when targeting `'react'` JSX emit. + + @default 'React' + */ + reactNamespace?: string; + + /** + Specify the JSX factory function to use when targeting React JSX emit, e.g. `React.createElement` or `h`. + + @default 'React.createElement' + */ + jsxFactory?: string; + + /** + Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. + + @default 'React.Fragment' + */ + jsxFragmentFactory?: string; + + /** + Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`. + + @default 'react' + */ + jsxImportSource?: string; + + /** + Print names of files part of the compilation. + + @default false + */ + listFiles?: boolean; + + /** + Specifies the location where debugger should locate map files instead of generated locations. + */ + mapRoot?: string; + + /** + Specify module code generation: 'None', 'CommonJS', 'AMD', 'System', 'UMD', 'ES6', 'ES2015' or 'ESNext'. Only 'AMD' and 'System' can be used in conjunction with `--outFile`. 'ES6' and 'ES2015' values may be used when targeting 'ES5' or lower. + + @default ['ES3', 'ES5'].includes(target) ? 'CommonJS' : 'ES6' + */ + module?: CompilerOptions.Module; + + /** + Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6). + + @default ['AMD', 'System', 'ES6'].includes(module) ? 'classic' : 'node' + */ + moduleResolution?: CompilerOptions.ModuleResolution; + + /** + Specifies the end of line sequence to be used when emitting files: 'crlf' (Windows) or 'lf' (Unix). + + @default 'LF' + */ + newLine?: CompilerOptions.NewLine; + + /** + Do not emit output. + + @default false + */ + noEmit?: boolean; + + /** + Do not generate custom helper functions like `__extends` in compiled output. + + @default false + */ + noEmitHelpers?: boolean; + + /** + Do not emit outputs if any type checking errors were reported. + + @default false + */ + noEmitOnError?: boolean; + + /** + Warn on expressions and declarations with an implied 'any' type. + + @default false + */ + noImplicitAny?: boolean; + + /** + Raise error on 'this' expressions with an implied any type. + + @default false + */ + noImplicitThis?: boolean; + + /** + Report errors on unused locals. + + @default false + */ + noUnusedLocals?: boolean; + + /** + Report errors on unused parameters. + + @default false + */ + noUnusedParameters?: boolean; + + /** + Do not include the default library file (lib.d.ts). + + @default false + */ + noLib?: boolean; + + /** + Do not add triple-slash references or module import targets to the list of compiled files. + + @default false + */ + noResolve?: boolean; + + /** + Disable strict checking of generic signatures in function types. + + @default false + @deprecated This option will be removed in TypeScript 5.5. + */ + noStrictGenericChecks?: boolean; + + /** + @deprecated use `skipLibCheck` instead. + */ + skipDefaultLibCheck?: boolean; + + /** + Skip type checking of declaration files. + + @default false + */ + skipLibCheck?: boolean; + + /** + Concatenate and emit output to single file. + */ + outFile?: string; + + /** + Redirect output structure to the directory. + */ + outDir?: string; + + /** + Do not erase const enum declarations in generated code. + + @default false + */ + preserveConstEnums?: boolean; + + /** + Do not resolve symlinks to their real path; treat a symlinked file like a real one. + + @default false + */ + preserveSymlinks?: boolean; + + /** + Keep outdated console output in watch mode instead of clearing the screen. + + @default false + */ + preserveWatchOutput?: boolean; + + /** + Stylize errors and messages using color and context (experimental). + + @default true // Unless piping to another program or redirecting output to a file. + */ + pretty?: boolean; + + /** + Do not emit comments to output. + + @default false + */ + removeComments?: boolean; + + /** + Specifies the root directory of input files. + + Use to control the output directory structure with `--outDir`. + */ + rootDir?: string; + + /** + Unconditionally emit imports for unresolved files. + + @default false + */ + isolatedModules?: boolean; + + /** + Generates corresponding '.map' file. + + @default false + */ + sourceMap?: boolean; + + /** + Specifies the location where debugger should locate TypeScript files instead of source locations. + */ + sourceRoot?: string; + + /** + Suppress excess property checks for object literals. + + @default false + @deprecated This option will be removed in TypeScript 5.5. + */ + suppressExcessPropertyErrors?: boolean; + + /** + Suppress noImplicitAny errors for indexing objects lacking index signatures. + + @default false + @deprecated This option will be removed in TypeScript 5.5. + */ + suppressImplicitAnyIndexErrors?: boolean; + + /** + Do not emit declarations for code that has an `@internal` annotation. + */ + stripInternal?: boolean; + + /** + Specify ECMAScript target version. + + @default 'es3' + */ + target?: CompilerOptions.Target; + + /** + Default catch clause variables as `unknown` instead of `any`. + + @default false + */ + useUnknownInCatchVariables?: boolean; + + /** + Watch input files. + + @default false + @deprecated Use watchOptions instead. + */ + watch?: boolean; + + /** + Specify the polling strategy to use when the system runs out of or doesn't support native file watchers. + + @deprecated Use watchOptions.fallbackPolling instead. + */ + fallbackPolling?: CompilerOptions.FallbackPolling; + + /** + Specify the strategy for watching directories under systems that lack recursive file-watching functionality. + + @default 'useFsEvents' + @deprecated Use watchOptions.watchDirectory instead. + */ + watchDirectory?: CompilerOptions.WatchDirectory; + + /** + Specify the strategy for watching individual files. + + @default 'useFsEvents' + @deprecated Use watchOptions.watchFile instead. + */ + watchFile?: CompilerOptions.WatchFile; + + /** + Enables experimental support for ES7 decorators. + + @default false + */ + experimentalDecorators?: boolean; + + /** + Emit design-type metadata for decorated declarations in source. + + @default false + */ + emitDecoratorMetadata?: boolean; + + /** + Do not report errors on unused labels. + + @default false + */ + allowUnusedLabels?: boolean; + + /** + Report error when not all code paths in function return a value. + + @default false + */ + noImplicitReturns?: boolean; + + /** + Add `undefined` to a type when accessed using an index. + + @default false + */ + noUncheckedIndexedAccess?: boolean; + + /** + Report errors for fallthrough cases in switch statement. + + @default false + */ + noFallthroughCasesInSwitch?: boolean; + + /** + Ensure overriding members in derived classes are marked with an override modifier. + + @default false + */ + noImplicitOverride?: boolean; + + /** + Do not report errors on unreachable code. + + @default false + */ + allowUnreachableCode?: boolean; + + /** + Disallow inconsistently-cased references to the same file. + + @default true + */ + forceConsistentCasingInFileNames?: boolean; + + /** + Emit a v8 CPU profile of the compiler run for debugging. + + @default 'profile.cpuprofile' + */ + generateCpuProfile?: string; + + /** + Base directory to resolve non-relative module names. + */ + baseUrl?: string; + + /** + Specify path mapping to be computed relative to baseUrl option. + */ + paths?: Record<string, string[]>; + + /** + List of TypeScript language server plugins to load. + */ + plugins?: CompilerOptions.Plugin[]; + + /** + Specify list of root directories to be used when resolving modules. + */ + rootDirs?: string[]; + + /** + Specify list of directories for type definition files to be included. + */ + typeRoots?: string[]; + + /** + Type declaration files to be included in compilation. + */ + types?: string[]; + + /** + Enable tracing of the name resolution process. + + @default false + */ + traceResolution?: boolean; + + /** + Allow javascript files to be compiled. + + @default false + */ + allowJs?: boolean; + + /** + Do not truncate error messages. + + @default false + */ + noErrorTruncation?: boolean; + + /** + Allow default imports from modules with no default export. This does not affect code emit, just typechecking. + + @default module === 'system' || esModuleInterop + */ + allowSyntheticDefaultImports?: boolean; + + /** + Do not emit `'use strict'` directives in module output. + + @default false + @deprecated This option will be removed in TypeScript 5.5. + */ + noImplicitUseStrict?: boolean; + + /** + Enable to list all emitted files. + + @default false + */ + listEmittedFiles?: boolean; + + /** + Disable size limit for JavaScript project. + + @default false + */ + disableSizeLimit?: boolean; + + /** + List of library files to be included in the compilation. + */ + lib?: CompilerOptions.Lib[]; + + /** + Enable strict null checks. + + @default false + */ + strictNullChecks?: boolean; + + /** + The maximum dependency depth to search under `node_modules` and load JavaScript files. Only applicable with `--allowJs`. + + @default 0 + */ + maxNodeModuleJsDepth?: number; + + /** + Import emit helpers (e.g. `__extends`, `__rest`, etc..) from tslib. + + @default false + */ + importHelpers?: boolean; + + /** + Specify emit/checking behavior for imports that are only used for types. + + @default 'remove' + @deprecated Use `verbatimModuleSyntax` instead. + */ + importsNotUsedAsValues?: CompilerOptions.ImportsNotUsedAsValues; + + /** + Parse in strict mode and emit `'use strict'` for each source file. + + @default false + */ + alwaysStrict?: boolean; + + /** + Enable all strict type checking options. + + @default false + */ + strict?: boolean; + + /** + Enable stricter checking of of the `bind`, `call`, and `apply` methods on functions. + + @default false + */ + strictBindCallApply?: boolean; + + /** + Provide full support for iterables in `for-of`, spread, and destructuring when targeting `ES5` or `ES3`. + + @default false + */ + downlevelIteration?: boolean; + + /** + Report errors in `.js` files. + + @default false + */ + checkJs?: boolean; + + /** + Disable bivariant parameter checking for function types. + + @default false + */ + strictFunctionTypes?: boolean; + + /** + Ensure non-undefined class properties are initialized in the constructor. + + @default false + */ + strictPropertyInitialization?: boolean; + + /** + Emit `__importStar` and `__importDefault` helpers for runtime Babel ecosystem compatibility and enable `--allowSyntheticDefaultImports` for typesystem compatibility. + + @default false + */ + esModuleInterop?: boolean; + + /** + Allow accessing UMD globals from modules. + + @default false + */ + allowUmdGlobalAccess?: boolean; + + /** + Resolve `keyof` to string valued property names only (no numbers or symbols). + + @default false + @deprecated This option will be removed in TypeScript 5.5. + */ + keyofStringsOnly?: boolean; + + /** + Emit ECMAScript standard class fields. + + @default false + */ + useDefineForClassFields?: boolean; + + /** + Generates a sourcemap for each corresponding `.d.ts` file. + + @default false + */ + declarationMap?: boolean; + + /** + Include modules imported with `.json` extension. + + @default false + */ + resolveJsonModule?: boolean; + + /** + Have recompiles in '--incremental' and '--watch' assume that changes within a file will only affect files directly depending on it. + + @default false + */ + assumeChangesOnlyAffectDirectDependencies?: boolean; + + /** + Output more detailed compiler performance information after building. + + @default false + */ + extendedDiagnostics?: boolean; + + /** + Print names of files that are part of the compilation and then stop processing. + + @default false + */ + listFilesOnly?: boolean; + + /** + Disable preferring source files instead of declaration files when referencing composite projects. + + @default true if composite, false otherwise + */ + disableSourceOfProjectReferenceRedirect?: boolean; + + /** + Opt a project out of multi-project reference checking when editing. + + @default false + */ + disableSolutionSearching?: boolean; + + /** + Print names of files which TypeScript sees as a part of your project and the reason they are part of the compilation. + + @default false + */ + explainFiles?: boolean; + + /** + Preserve unused imported values in the JavaScript output that would otherwise be removed. + + @default true + @deprecated Use `verbatimModuleSyntax` instead. + */ + preserveValueImports?: boolean; + + /** + List of file name suffixes to search when resolving a module. + */ + moduleSuffixes?: string[]; + + /** + Control what method is used to detect module-format JS files. + + @default 'auto' + */ + moduleDetection?: CompilerOptions.ModuleDetection; + + /** + Allows TypeScript files to import each other with a TypeScript-specific extension like .ts, .mts, or .tsx. + + @default false + */ + allowImportingTsExtensions?: boolean; + + /** + Forces TypeScript to consult the exports field of package.json files if it ever reads from a package in node_modules. + + @default false + */ + resolvePackageJsonExports?: boolean; + + /** + Forces TypeScript to consult the imports field of package.json files when performing a lookup that starts with # from a file whose ancestor directory contains a package.json. + + @default false + */ + resolvePackageJsonImports?: boolean; + + /** + Suppress errors for file formats that TypeScript does not understand. + + @default false + */ + allowArbitraryExtensions?: boolean; + + /** + List of additional conditions that should succeed when TypeScript resolves from package.json. + */ + customConditions?: string[]; + + /** + Anything that uses the type modifier is dropped entirely. + + @default false + */ + verbatimModuleSyntax?: boolean; + + /** + Suppress deprecation warnings + */ + ignoreDeprecations?: CompilerOptions.IgnoreDeprecations; + }; + + namespace WatchOptions { + export type WatchFileKind = + | 'FixedPollingInterval' + | 'PriorityPollingInterval' + | 'DynamicPriorityPolling' + | 'FixedChunkSizePolling' + | 'UseFsEvents' + | 'UseFsEventsOnParentDirectory'; + + export type WatchDirectoryKind = + | 'UseFsEvents' + | 'FixedPollingInterval' + | 'DynamicPriorityPolling' + | 'FixedChunkSizePolling'; + + export type PollingWatchKind = + | 'FixedInterval' + | 'PriorityInterval' + | 'DynamicPriority' + | 'FixedChunkSize'; + } + + export type WatchOptions = { + + /** + Specify the strategy for watching individual files. + + @default 'UseFsEvents' + */ + watchFile?: WatchOptions.WatchFileKind | Lowercase<WatchOptions.WatchFileKind>; + + /** + Specify the strategy for watching directories under systems that lack recursive file-watching functionality. + + @default 'UseFsEvents' + */ + watchDirectory?: WatchOptions.WatchDirectoryKind | Lowercase<WatchOptions.WatchDirectoryKind>; + + /** + Specify the polling strategy to use when the system runs out of or doesn't support native file watchers. + */ + fallbackPolling?: WatchOptions.PollingWatchKind | Lowercase<WatchOptions.PollingWatchKind>; + + /** + Enable synchronous updates on directory watchers for platforms that don't support recursive watching natively. + */ + synchronousWatchDirectory?: boolean; + + /** + Specifies a list of directories to exclude from watch + */ + excludeDirectories?: string[]; + + /** + Specifies a list of files to exclude from watch + */ + excludeFiles?: string[]; + }; + + /** + Auto type (.d.ts) acquisition options for this project. + */ + export type TypeAcquisition = { + /** + Enable auto type acquisition. + */ + enable?: boolean; + + /** + Specifies a list of type declarations to be included in auto type acquisition. For example, `['jquery', 'lodash']`. + */ + include?: string[]; + + /** + Specifies a list of type declarations to be excluded from auto type acquisition. For example, `['jquery', 'lodash']`. + */ + exclude?: string[]; + }; + + export type References = { + /** + A normalized path on disk. + */ + path: string; + + /** + The path as the user originally wrote it. + */ + originalPath?: string; + + /** + True if the output of this reference should be prepended to the output of this project. + + Only valid for `--outFile` compilations. + @deprecated This option will be removed in TypeScript 5.5. + */ + prepend?: boolean; + + /** + True if it is intended that this reference form a circularity. + */ + circular?: boolean; + }; +} + +/** +Type for [TypeScript's `tsconfig.json` file](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) (TypeScript 3.7). + +@category File +*/ +export type TsConfigJson = { + /** + Instructs the TypeScript compiler how to compile `.ts` files. + */ + compilerOptions?: TsConfigJson.CompilerOptions; + + /** + Instructs the TypeScript compiler how to watch files. + */ + watchOptions?: TsConfigJson.WatchOptions; + + /** + Auto type (.d.ts) acquisition options for this project. + */ + typeAcquisition?: TsConfigJson.TypeAcquisition; + + /** + Enable Compile-on-Save for this project. + */ + compileOnSave?: boolean; + + /** + Path to base configuration file to inherit from. + */ + extends?: string | string[]; + + /** + If no `files` or `include` property is present in a `tsconfig.json`, the compiler defaults to including all files in the containing directory and subdirectories except those specified by `exclude`. When a `files` property is specified, only those files and those specified by `include` are included. + */ + files?: string[]; + + /** + Specifies a list of files to be excluded from compilation. The `exclude` property only affects the files included via the `include` property and not the `files` property. + + Glob patterns require TypeScript version 2.0 or later. + */ + exclude?: string[]; + + /** + Specifies a list of glob patterns that match files to be included in compilation. + + If no `files` or `include` property is present in a `tsconfig.json`, the compiler defaults to including all files in the containing directory and subdirectories except those specified by `exclude`. + */ + include?: string[]; + + /** + Referenced projects. + */ + references?: TsConfigJson.References[]; +}; diff --git a/node_modules/type-fest/source/tuple-to-union.d.ts b/node_modules/type-fest/source/tuple-to-union.d.ts new file mode 100644 index 0000000..b2bdf89 --- /dev/null +++ b/node_modules/type-fest/source/tuple-to-union.d.ts @@ -0,0 +1,51 @@ +/** +Convert a tuple/array into a union type of its elements. + +This can be useful when you have a fixed set of allowed values and want a type defining only the allowed values, but do not want to repeat yourself. + +@example +``` +import type {TupleToUnion} from 'type-fest'; + +const destinations = ['a', 'b', 'c'] as const; + +type Destination = TupleToUnion<typeof destinations>; +//=> 'a' | 'b' | 'c' + +function verifyDestination(destination: unknown): destination is Destination { + return destinations.includes(destination as any); +} + +type RequestBody = { + deliverTo: Destination; +}; + +function verifyRequestBody(body: unknown): body is RequestBody { + const deliverTo = (body as any).deliverTo; + return typeof body === 'object' && body !== null && verifyDestination(deliverTo); +} +``` + +Alternatively, you may use `typeof destinations[number]`. If `destinations` is a tuple, there is no difference. However if `destinations` is a string, the resulting type will the union of the characters in the string. Other types of `destinations` may result in a compile error. In comparison, TupleToUnion will return `never` if a tuple is not provided. + +@example +``` +const destinations = ['a', 'b', 'c'] as const; + +type Destination = typeof destinations[number]; +//=> 'a' | 'b' | 'c' + +const erroringType = new Set(['a', 'b', 'c']); + +type ErroringType = typeof erroringType[number]; +//=> Type 'Set<string>' has no matching index signature for type 'number'. ts(2537) + +const numberBool: { [n: number]: boolean } = { 1: true }; + +type NumberBool = typeof numberBool[number]; +//=> boolean +``` + +@category Array +*/ +export type TupleToUnion<ArrayType> = ArrayType extends readonly unknown[] ? ArrayType[number] : never; diff --git a/node_modules/type-fest/source/typed-array.d.ts b/node_modules/type-fest/source/typed-array.d.ts new file mode 100644 index 0000000..e79de08 --- /dev/null +++ b/node_modules/type-fest/source/typed-array.d.ts @@ -0,0 +1,17 @@ +/** +Matches any [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray), like `Uint8Array` or `Float64Array`. + +@category Array +*/ +export type TypedArray = + | Int8Array + | Uint8Array + | Uint8ClampedArray + | Int16Array + | Uint16Array + | Int32Array + | Uint32Array + | Float32Array + | Float64Array + | BigInt64Array + | BigUint64Array; diff --git a/node_modules/type-fest/source/union-to-intersection.d.ts b/node_modules/type-fest/source/union-to-intersection.d.ts new file mode 100644 index 0000000..eeebd7c --- /dev/null +++ b/node_modules/type-fest/source/union-to-intersection.d.ts @@ -0,0 +1,60 @@ +/** +Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). + +Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153). + +@example +``` +import type {UnionToIntersection} from 'type-fest'; + +type Union = {the(): void} | {great(arg: string): void} | {escape: boolean}; + +type Intersection = UnionToIntersection<Union>; +//=> {the(): void; great(arg: string): void; escape: boolean}; +``` + +A more applicable example which could make its way into your library code follows. + +@example +``` +import type {UnionToIntersection} from 'type-fest'; + +class CommandOne { + commands: { + a1: () => undefined, + b1: () => undefined, + } +} + +class CommandTwo { + commands: { + a2: (argA: string) => undefined, + b2: (argB: string) => undefined, + } +} + +const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands); +type Union = typeof union; +//=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void} + +type Intersection = UnionToIntersection<Union>; +//=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void} +``` + +@category Type +*/ +export type UnionToIntersection<Union> = ( + // `extends unknown` is always going to be the case and is used to convert the + // `Union` into a [distributive conditional + // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). + Union extends unknown + // The union type is used as the only argument to a function since the union + // of function arguments is an intersection. + ? (distributedUnion: Union) => void + // This won't happen. + : never + // Infer the `Intersection` type since TypeScript represents the positional + // arguments of unions of functions as an intersection of the union. +) extends ((mergedIntersection: infer Intersection) => void) + ? Intersection + : never; diff --git a/node_modules/type-fest/source/value-of.d.ts b/node_modules/type-fest/source/value-of.d.ts new file mode 100644 index 0000000..1f6418b --- /dev/null +++ b/node_modules/type-fest/source/value-of.d.ts @@ -0,0 +1,42 @@ +/** +Create a union of the given object's values, and optionally specify which keys to get the values from. + +Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/31438) if you want to have this type as a built-in in TypeScript. + +@example +``` +// data.json +{ + 'foo': 1, + 'bar': 2, + 'biz': 3 +} + +// main.ts +import type {ValueOf} from 'type-fest'; +import data = require('./data.json'); + +export function getData(name: string): ValueOf<typeof data> { + return data[name]; +} + +export function onlyBar(name: string): ValueOf<typeof data, 'bar'> { + return data[name]; +} + +// file.ts +import {getData, onlyBar} from './main'; + +getData('foo'); +//=> 1 + +onlyBar('foo'); +//=> TypeError ... + +onlyBar('bar'); +//=> 2 +``` + +@category Object +*/ +export type ValueOf<ObjectType, ValueType extends keyof ObjectType = keyof ObjectType> = ObjectType[ValueType]; diff --git a/node_modules/type-fest/source/writable-deep.d.ts b/node_modules/type-fest/source/writable-deep.d.ts new file mode 100644 index 0000000..4cca3b2 --- /dev/null +++ b/node_modules/type-fest/source/writable-deep.d.ts @@ -0,0 +1,64 @@ +import type {BuiltIns, HasMultipleCallSignatures} from './internal'; +import type {Writable} from './writable.js'; + +/** +Create a deeply mutable version of an `object`/`ReadonlyMap`/`ReadonlySet`/`ReadonlyArray` type. The inverse of `ReadonlyDeep<T>`. Use `Writable<T>` if you only need one level deep. + +This can be used to [store and mutate options within a class](https://github.com/sindresorhus/pageres/blob/4a5d05fca19a5fbd2f53842cbf3eb7b1b63bddd2/source/index.ts#L72), [edit `readonly` objects within tests](https://stackoverflow.com/questions/50703834), [construct a `readonly` object within a function](https://github.com/Microsoft/TypeScript/issues/24509), or to define a single model where the only thing that changes is whether or not some of the keys are writable. + +@example +``` +import type {WritableDeep} from 'type-fest'; + +type Foo = { + readonly a: number; + readonly b: readonly string[]; // To show that mutability is deeply affected. + readonly c: boolean; +}; + +const writableDeepFoo: WritableDeep<Foo> = {a: 1, b: ['2'], c: true}; +writableDeepFoo.a = 3; +writableDeepFoo.b[0] = 'new value'; +writableDeepFoo.b = ['something']; +``` + +Note that types containing overloaded functions are not made deeply writable due to a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/29732). + +@see Writable +@category Object +@category Array +@category Set +@category Map +*/ +export type WritableDeep<T> = T extends BuiltIns + ? T + : T extends (...arguments_: any[]) => unknown + ? {} extends WritableObjectDeep<T> + ? T + : HasMultipleCallSignatures<T> extends true + ? T + : ((...arguments_: Parameters<T>) => ReturnType<T>) & WritableObjectDeep<T> + : T extends Readonly<ReadonlyMap<infer KeyType, infer ValueType>> + ? WritableMapDeep<KeyType, ValueType> + : T extends Readonly<ReadonlySet<infer ItemType>> + ? WritableSetDeep<ItemType> + : T extends object + ? WritableObjectDeep<T> + : unknown; + +/** +Same as `WritableDeep`, but accepts only `Map`s as inputs. Internal helper for `WritableDeep`. +*/ +type WritableMapDeep<KeyType, ValueType> = {} & Writable<Map<WritableDeep<KeyType>, WritableDeep<ValueType>>>; + +/** +Same as `WritableDeep`, but accepts only `Set`s as inputs. Internal helper for `WritableDeep`. +*/ +type WritableSetDeep<ItemType> = {} & Writable<Set<WritableDeep<ItemType>>>; + +/** +Same as `WritableDeep`, but accepts only `object`s as inputs. Internal helper for `WritableDeep`. +*/ +type WritableObjectDeep<ObjectType extends object> = { + -readonly [KeyType in keyof ObjectType]: WritableDeep<ObjectType[KeyType]> +}; diff --git a/node_modules/type-fest/source/writable-keys-of.d.ts b/node_modules/type-fest/source/writable-keys-of.d.ts new file mode 100644 index 0000000..7432c9f --- /dev/null +++ b/node_modules/type-fest/source/writable-keys-of.d.ts @@ -0,0 +1,30 @@ +import type {IsEqual} from './is-equal'; + +/** +Extract all writable keys from the given type. + +This is useful when you want to create a new type that contains writable keys only. + +@example +``` +import type {WritableKeysOf} from 'type-fest'; + +interface User { + name: string; + surname: string; + readonly id: number; +} + +type UpdateRequest<Entity extends object> = Pick<Entity, WritableKeysOf<Entity>>; + +const update1: UpdateRequest<User> = { + name: 'Alice', + surname: 'Acme', +}; +``` + +@category Utilities +*/ +export type WritableKeysOf<T> = NonNullable<{ + [P in keyof T]: IsEqual<{[Q in P]: T[P]}, {readonly [Q in P]: T[P]}> extends false ? P : never +}[keyof T]>; diff --git a/node_modules/type-fest/source/writable.d.ts b/node_modules/type-fest/source/writable.d.ts new file mode 100644 index 0000000..9a8ca71 --- /dev/null +++ b/node_modules/type-fest/source/writable.d.ts @@ -0,0 +1,40 @@ +import type {Except} from './except'; +import type {Simplify} from './simplify'; + +/** +Create a type that strips `readonly` from all or some of an object's keys. Inverse of `Readonly<T>`. + +This can be used to [store and mutate options within a class](https://github.com/sindresorhus/pageres/blob/4a5d05fca19a5fbd2f53842cbf3eb7b1b63bddd2/source/index.ts#L72), [edit `readonly` objects within tests](https://stackoverflow.com/questions/50703834), [construct a `readonly` object within a function](https://github.com/Microsoft/TypeScript/issues/24509), or to define a single model where the only thing that changes is whether or not some of the keys are writable. + +@example +``` +import type {Writable} from 'type-fest'; + +type Foo = { + readonly a: number; + readonly b: readonly string[]; // To show that only the mutability status of the properties, not their values, are affected. + readonly c: boolean; +}; + +const writableFoo: Writable<Foo> = {a: 1, b: ['2'], c: true}; +writableFoo.a = 3; +writableFoo.b[0] = 'new value'; // Will still fail as the value of property "b" is still a readonly type. +writableFoo.b = ['something']; // Will work as the "b" property itself is no longer readonly. + +type SomeWritable = Writable<Foo, 'b' | 'c'>; +// type SomeWritable = { +// readonly a: number; +// b: readonly string[]; // It's now writable. The type of the property remains unaffected. +// c: boolean; // It's now writable. +// } +``` + +@category Object +*/ +export type Writable<BaseType, Keys extends keyof BaseType = keyof BaseType> = + Simplify< + // Pick just the keys that are not writable from the base type. + Except<BaseType, Keys> & + // Pick the keys that should be writable from the base type and make them writable by removing the `readonly` modifier from the key. + {-readonly [KeyType in keyof Pick<BaseType, Keys>]: Pick<BaseType, Keys>[KeyType]} + >; diff --git a/package.json b/package.json new file mode 100644 index 0000000..213d137 --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": {}, + "devDependencies": { + "json-server": "^1.0.0-alpha.23" + } +} \ No newline at end of file