UNPKG

@d1g1tal/transportr

Version:
1,194 lines (1,178 loc) 105 kB
// node_modules/.pnpm/@d1g1tal+collections@0.2.5/node_modules/@d1g1tal/collections/src/set-multi-map.js var SetMultiMap = class extends Map { /** * Adds a new element with a specified key and value to the SetMultiMap. * If an element with the same key already exists, the value will be added to the underlying {@link Set}. * If the value already exists in the {@link Set}, it will not be added again. * * @param {K} key The key to set. * @param {V} value The value to add to the SetMultiMap * @returns {SetMultiMap<K, V>} The SetMultiMap with the updated key and value. */ set(key, value) { super.set(key, (super.get(key) ?? /* @__PURE__ */ new Set()).add(value)); return this; } /** * Checks if a specific key has a specific value. * * @param {K} key The key to check. * @param {V} value The value to check. * @returns {boolean} True if the key has the value, false otherwise. */ hasValue(key, value) { const values = super.get(key); return values ? values.has(value) : false; } /** * Removes a specific value from a specific key. * * @param {K} key The key to remove the value from. * @param {V} value The value to remove. * @returns {boolean} True if the value was removed, false otherwise. */ deleteValue(key, value) { const values = super.get(key); if (values) { return values.delete(value); } return false; } get [Symbol.toStringTag]() { return "SetMultiMap"; } }; // node_modules/.pnpm/@d1g1tal+subscribr@3.0.3/node_modules/@d1g1tal/subscribr/src/context-event-handler.js var ContextEventHandler = class { #context; #eventHandler; /** * @param {*} context The context to bind to the event handler. * @param {function(*): void} eventHandler The event handler to call when the event is published. */ constructor(context, eventHandler) { this.#context = context; this.#eventHandler = eventHandler; } /** * Call the event handler for the provided event. * * @param {Event} event The event to handle * @param {*} [data] The value to be passed to the event handler as a parameter. */ handle(event, data) { this.#eventHandler.call(this.#context, event, data); } get [Symbol.toStringTag]() { return "ContextEventHandler"; } }; // node_modules/.pnpm/@d1g1tal+subscribr@3.0.3/node_modules/@d1g1tal/subscribr/src/subscription.js var Subscription = class { #eventName; #contextEventHandler; /** * @param {string} eventName The event name. * @param {ContextEventHandler} contextEventHandler Then context event handler. */ constructor(eventName, contextEventHandler) { this.#eventName = eventName; this.#contextEventHandler = contextEventHandler; } /** * Gets the event name for the subscription. * * @returns {string} The event name. */ get eventName() { return this.#eventName; } /** * Gets the context event handler. * * @returns {ContextEventHandler} The context event handler */ get contextEventHandler() { return this.#contextEventHandler; } get [Symbol.toStringTag]() { return "Subscription"; } }; // node_modules/.pnpm/@d1g1tal+subscribr@3.0.3/node_modules/@d1g1tal/subscribr/src/subscribr.js var Subscribr = class { /** @type {SetMultiMap<string, ContextEventHandler>} */ #subscribers; constructor() { this.#subscribers = new SetMultiMap(); } /** * Subscribe to an event * * @param {string} eventName The event name to subscribe to. * @param {function(Event, *): void} eventHandler The event handler to call when the event is published. * @param {*} [context] The context to bind to the event handler. * @returns {Subscription} An object used to check if the subscription still exists and to unsubscribe from the event. */ subscribe(eventName, eventHandler, context = eventHandler) { const contextEventHandler = new ContextEventHandler(context, eventHandler); this.#subscribers.set(eventName, contextEventHandler); return new Subscription(eventName, contextEventHandler); } /** * Unsubscribe from the event * * @param {Subscription} subscription The subscription to unsubscribe. * @param {string} subscription.eventName The event name to subscribe to. * @param {ContextEventHandler} subscription.contextEventHandler The event handler to call when the event is published. * @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object. */ unsubscribe({ eventName, contextEventHandler }) { const contextEventHandlers = this.#subscribers.get(eventName); const removed = contextEventHandlers?.delete(contextEventHandler); if (removed && contextEventHandlers.size == 0) { this.#subscribers.delete(eventName); } return removed; } /** * Publish an event * * @param {string} eventName The name of the event. * @param {Event} [event=new CustomEvent(eventName)] The event to be handled. * @param {*} [data] The value to be passed to the event handler as a parameter. */ publish(eventName, event = new CustomEvent(eventName), data) { if (data == null && !(event instanceof Event)) { [data, event] = [event, new CustomEvent(eventName)]; } this.#subscribers.get(eventName)?.forEach((contextEventHandler) => contextEventHandler.handle(event, data)); } /** * Check if the event and handler are subscribed. * * @param {Subscription} subscription The subscription object. * @param {string} subscription.eventName The name of the event to check. * @param {ContextEventHandler} subscription.contextEventHandler The event handler to check. * @returns {boolean} true if the event name and handler are subscribed, false otherwise. */ isSubscribed({ eventName, contextEventHandler }) { return this.#subscribers.get(eventName)?.has(contextEventHandler); } get [Symbol.toStringTag]() { return "Subscribr"; } }; // src/http-request-methods.js var HttpRequestMethod = { /** * The OPTIONS method represents a request for information about the communication options available on the * request/response chain identified by the Request-URI. This method allows the client to determine the options and/or * requirements associated with a resource, or the capabilities of a server, without implying a resource action or * initiating a resource retrieval. * * Responses to this method are not cacheable. * * If the OPTIONS request includes an entity-body (as indicated by the presence of Content-Length or * Transfer-Encoding), then the media type MUST be indicated by a Content-Type field. Although this specification does * not define any use for such a body, future extensions to HTTP might use the OPTIONS body to make more detailed * queries on the server. A server that does not support such an extension MAY discard the request body. * * If the Request-URI is an asterisk ("*"), the OPTIONS request is intended to apply to the server in general rather * than to a specific resource. Since a server's communication options typically depend on the resource, the "*" * request is only useful as a "ping" or "no-op" type of method, it does nothing beyond allowing the client to test the * capabilities of the server. For example, this can be used to test a proxy for HTTP/1.1 compliance (or lack thereof). * * If the Request-URI is not an asterisk, the OPTIONS request applies only to the options that are available when * communicating with that resource. * * A 200 response SHOULD include any header fields that indicate optional features implemented by the server and * applicable to that resource (e.g., Allow), possibly including extensions not defined by this specification. The * response body, if any, SHOULD also include information about the communication options. The format for such a body * is not defined by this specification, but might be defined by future extensions to HTTP. Content negotiation MAY be * used to select the appropriate response format. If no response body is included, the response MUST include a * Content-Length field with a field-value of "0". * * The Max-Forwards request-header field MAY be used to target a specific proxy in the request chain. When a proxy * receives an OPTIONS request on an absoluteURI for which request forwarding is permitted, the proxy MUST check for a * Max-Forwards field. If the Max-Forwards field-value is zero ("0"), the proxy MUST NOT forward the message, instead, * the proxy SHOULD respond with its own communication options. If the Max-Forwards field-value is an integer greater * than zero, the proxy MUST decrement the field-value when it forwards the request. If no Max-Forwards field is * present in the request, then the forwarded request MUST NOT include a Max-Forwards field. */ OPTIONS: "OPTIONS", /** * The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If * the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in * the response and not the source text of the process, unless that text happens to be the output of the process. * * The semantics of the GET method change to a "conditional GET" if the request message includes an If-Modified-Since; * If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. A conditional GET method requests that the * entity be transferred only under the circumstances described by the conditional header field(s). The conditional GET * method is intended to reduce unnecessary network usage by allowing cached entities to be refreshed without requiring * multiple requests or transferring data already held by the client. * * The semantics of the GET method change to a "partial GET" if the request message includes a Range header field. A * partial GET requests that only part of the entity be transferred, as described in section 14.35. The partial GET * method is intended to reduce unnecessary network usage by allowing partially-retrieved entities to be completed * without transferring data already held by the client. * * The response to a GET request is cacheable if and only if it meets the requirements for HTTP caching described in * section 13. * * See section 15.1.3 for security considerations when used for forms. */ GET: "GET", /** * The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The * meta information contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information * sent in response to a GET request. This method can be used for obtaining meta information about the entity implied by * the request without transferring the entity-body itself. This method is often used for testing hypertext links for * validity, accessibility, and recent modification. * * The response to a HEAD request MAY be cacheable in the sense that the information contained in the response MAY be * used to update a previously cached entity from that resource. If the new field values indicate that the cached * entity differs from the current entity (as would be indicated by a change in Content-Length, Content-MD5, ETag or * Last-Modified), then the cache MUST treat the cache entry as stale. */ HEAD: "HEAD", /** * The POST method is used to request that the origin server accept the entity enclosed in the request as a new * subordinate of the resource identified by the Request-URI in the Request-Line. POST is designed to allow a uniform * method to cover the following functions: * <ul> * <li>Annotation of existing resources,</li> * <li>Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles,</li> * <li>Providing a block of data, such as the result of submitting a form, to a data-handling process,</li> * <li>Extending a database through an append operation.</li> * </ul> * * The actual function performed by the POST method is determined by the server and is usually dependent on the * Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory * containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a * database. * * The action performed by the POST method might not result in a resource that can be identified by a URI. In this * case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the * response includes an entity that describes the result. * * If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity * which describes the status of the request and refers to the new resource, and a Location header (see section 14.30). * * Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header * fields. However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource. * * POST requests MUST obey the message transmission requirements set out in section 8.2. * * See section 15.1.3 for security considerations. */ POST: "POST", /** * The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers * to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing * on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being * defined as a new resource by the requesting user agent, the origin server can create the resource with that URI. If * a new resource is created, the origin server MUST inform the user agent via the 201 (Created) response. If an * existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate * successful completion of the request. If the resource could not be created or modified with the Request-URI, an * appropriate error response SHOULD be given that reflects the nature of the problem. The recipient of the entity MUST * \NOT ignore any Content-* (e.g. Content-Range) headers that it does not understand or implement and MUST return a * 501 (Not Implemented) response in such cases. * * If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those * entries SHOULD be treated as stale. Responses to this method are not cacheable. * * The fundamental difference between the POST and PUT requests is reflected in the different meaning of the * Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource * might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. * In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what * URI is intended and the server MUST NOT attempt to apply the request to some other resource. If the server desires * that the request be applied to a different URI, it MUST send a 301 (Moved Permanently) response, the user agent MAY * then make its own decision regarding whether or not to redirect the request. * * A single resource MAY be identified by many different URIs. For example, an article might have a URI for identifying * "the current version" which is separate from the URI identifying each particular version. In this case, a PUT * request on a general URI might result in several other URIs being defined by the origin server. * * HTTP/1.1 does not define how a PUT method affects the state of an origin server. * * PUT requests MUST obey the message transmission requirements set out in section 8.2. * * Unless otherwise specified for a particular entity-header, the entity-headers in the PUT request SHOULD be applied * to the resource created or modified by the PUT. */ PUT: "PUT", /** * The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY * be overridden by human intervention (or other means) on the origin server. The client cannot be guaranteed that the * operation has been carried out, even if the status code returned from the origin server indicates that the action * has been completed successfully. However, the server SHOULD NOT indicate success unless, at the time the response * is given, it intends to delete the resource or move it to an inaccessible location. * * A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if * the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not * include an entity. * * If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those * entries SHOULD be treated as stale. Responses to this method are not cacheable. */ DELETE: "DELETE", /** * The TRACE method is used to invoke a remote, application-layer loop- back of the request message. The final * recipient of the request SHOULD reflect the message received back to the client as the entity-body of a 200 (OK) * response. The final recipient is either the origin server or the first proxy or gateway to receive a Max-Forwards * value of zero (0) in the request (see section 14.31). A TRACE request MUST NOT include an entity. * * TRACE allows the client to see what is being received at the other end of the request chain and use that data for * testing or diagnostic information. The value of the Via header field (section 14.45) is of particular interest, * since it acts as a trace of the request chain. Use of the Max-Forwards header field allows the client to limit the * length of the request chain, which is useful for testing a chain of proxies forwarding messages in an infinite loop. * * If the request is valid, the response SHOULD contain the entire request message in the entity-body, with a * Content-Type of "message/http". Responses to this method MUST NOT be cached. */ TRACE: "TRACE", /** * This specification reserves the method name CONNECT for use with a proxy that can dynamically switch to being a * tunnel (e.g. SSL tunneling [44]). */ CONNECT: "CONNECT", /** * The PATCH method requests that a set of changes described in the * request entity be applied to the resource identified by the Request- * URI. The set of changes is represented in a format called a "patch * document" identified by a media type. If the Request-URI does not * point to an existing resource, the server MAY create a new resource, * depending on the patch document type (whether it can logically modify * a null resource) and permissions, etc. * * The difference between the PUT and PATCH requests is reflected in the * way the server processes the enclosed entity to modify the resource * identified by the Request-URI. In a PUT request, the enclosed entity * is considered to be a modified version of the resource stored on the * origin server, and the client is requesting that the stored version * be replaced. With PATCH, however, the enclosed entity contains a set * of instructions describing how a resource currently residing on the * origin server should be modified to produce a new version. The PATCH * method affects the resource identified by the Request-URI, and it * also MAY have side effects on other resources; i.e., new resources * may be created, or existing ones modified, by the application of a * PATCH. * * PATCH is neither safe nor idempotent as defined by [RFC2616], Section * 9.1. * * A PATCH request can be issued in such a way as to be idempotent, * which also helps prevent bad outcomes from collisions between two * PATCH requests on the same resource in a similar time frame. * Collisions from multiple PATCH requests may be more dangerous than * PUT collisions because some patch formats need to operate from a * known base-point or else they will corrupt the resource. Clients * using this kind of patch application SHOULD use a conditional request * such that the request will fail if the resource has been updated * since the client last accessed the resource. For example, the client * can use a strong ETag [RFC2616] in an If-Match header on the PATCH * request. * * There are also cases where patch formats do not need to operate from * a known base-point (e.g., appending text lines to log files, or non- * colliding rows to database tables), in which case the same care in * client requests is not needed. * * The server MUST apply the entire set of changes atomically and never * provide (e.g., in response to a GET during this operation) a * partially modified representation. If the entire patch document * cannot be successfully applied, then the server MUST NOT apply any of * the changes. The determination of what constitutes a successful * PATCH can vary depending on the patch document and the type of * resource(s) being modified. For example, the common 'diff' utility * can generate a patch document that applies to multiple files in a * directory hierarchy. The atomicity requirement holds for all * directly affected files. See "Error Handling", Section 2.2, for * details on status codes and possible error conditions. * * If the request passes through a cache and the Request-URI identifies * one or more currently cached entities, those entries SHOULD be * treated as stale. A response to this method is only cacheable if it * contains explicit freshness information (such as an Expires header or * "Cache-Control: max-age" directive) as well as the Content-Location * header matching the Request-URI, indicating that the PATCH response * body is a resource representation. A cached PATCH response can only * be used to respond to subsequent GET and HEAD requests; it MUST NOT * be used to respond to other methods (in particular, PATCH). * * Note that entity-headers contained in the request apply only to the * contained patch document and MUST NOT be applied to the resource * being modified. Thus, a Content-Language header could be present on * the request, but it would only mean (for whatever that's worth) that * the patch document had a language. Servers SHOULD NOT store such * headers except as trace information, and SHOULD NOT use such header * values the same way they might be used on PUT requests. Therefore, * this document does not specify a way to modify a document's Content- * Type or Content-Language value through headers, though a mechanism * could well be designed to achieve this goal through a patch document. * * There is no guarantee that a resource can be modified with PATCH. * Further, it is expected that different patch document formats will be * appropriate for different types of resources and that no single * format will be appropriate for all types of resources. Therefore, * there is no single default patch document format that implementations * are required to support. Servers MUST ensure that a received patch * document is appropriate for the type of resource identified by the * Request-URI. * * Clients need to choose when to use PATCH rather than PUT. For * example, if the patch document size is larger than the size of the * new resource data that would be used in a PUT, then it might make * sense to use PUT instead of PATCH. A comparison to POST is even more * difficult, because POST is used in widely varying ways and can * encompass PUT and PATCH-like operations if the server chooses. If * the operation does not modify the resource identified by the Request- * URI in a predictable way, POST should be considered instead of PATCH * or PUT. */ PATCH: "PATCH" }; var http_request_methods_default = HttpRequestMethod; // src/response-status.js var ResponseStatus = class { /** @type {number} */ #code; /** @type {string} */ #text; /** * * @param {number} code The status code from the {@link Response} * @param {string} text The status text from the {@link Response} */ constructor(code, text) { this.#code = code; this.#text = text; } /** * Returns the status code from the {@link Response} * * @returns {number} The status code. */ get code() { return this.#code; } /** * Returns the status text from the {@link Response}. * * @returns {string} The status text. */ get text() { return this.#text; } /** * A String value that is used in the creation of the default string * description of an object. Called by the built-in method {@link Object.prototype.toString}. * * @override * @returns {string} The default string description of this object. */ get [Symbol.toStringTag]() { return "ResponseStatus"; } /** * tostring method for the class. * * @override * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString|Object.prototype.toString} * @returns {string} The status code and status text. */ toString() { return `${this.#code} ${this.#text}`; } }; // node_modules/.pnpm/@d1g1tal+chrysalis@2.2.1/node_modules/@d1g1tal/chrysalis/src/esm/object-type.js var _type = (object) => object?.constructor ?? object?.prototype?.constructor ?? globalThis[Object.prototype.toString.call(object).slice(8, -1)] ?? object; var object_type_default = _type; // node_modules/.pnpm/@d1g1tal+chrysalis@2.2.1/node_modules/@d1g1tal/chrysalis/src/esm/object-merge.js var _objectMerge = (...objects) => { const target = {}; for (const source of objects) { if (object_type_default(source) != Object) return void 0; let descriptor, sourceType; for (const property of Object.getOwnPropertyNames(source)) { descriptor = Object.getOwnPropertyDescriptor(source, property); if (descriptor.enumerable) { sourceType = object_type_default(source[property]); if (sourceType == Object) { descriptor.value = object_type_default(target[property]) == Object ? _objectMerge(target[property], source[property]) : { ...source[property] }; } else if (sourceType == Array) { descriptor.value = Array.isArray(target[property]) ? [.../* @__PURE__ */ new Set([...source[property], ...target[property]])] : [...source[property]]; } target[property] = descriptor.value; } } } return target; }; var object_merge_default = _objectMerge; // node_modules/.pnpm/@d1g1tal+media-type@5.0.0/node_modules/@d1g1tal/media-type/src/utils.js var httpTokenCodePoints = /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/u; var utils_default = httpTokenCodePoints; // node_modules/.pnpm/@d1g1tal+media-type@5.0.0/node_modules/@d1g1tal/media-type/src/media-type-parameters.js var matcher = /(["\\])/ug; var httpQuotedStringTokenCodePoints = /^[\t\u0020-\u007E\u0080-\u00FF]*$/u; var MediaTypeParameters = class _MediaTypeParameters extends Map { /** * Create a new MediaTypeParameters instance. * * @param {Array<[string, string]>} entries An array of [name, value] tuples. */ constructor(entries = []) { super(entries); } /** * Indicates whether the supplied name and value are valid media type parameters. * * @static * @param {string} name The name of the media type parameter to validate. * @param {string} value The media type parameter value to validate. * @returns {boolean} true if the media type parameter is valid, false otherwise. */ static isValid(name, value) { return utils_default.test(name) && httpQuotedStringTokenCodePoints.test(value); } /** * Gets the media type parameter value for the supplied name. * * @param {string} name The name of the media type parameter to retrieve. * @returns {string} The media type parameter value. */ get(name) { return super.get(name.toLowerCase()); } /** * Indicates whether the media type parameter with the specified name exists or not. * * @param {string} name The name of the media type parameter to check. * @returns {boolean} true if the media type parameter exists, false otherwise. */ has(name) { return super.has(name.toLowerCase()); } /** * Adds a new media type parameter using the specified name and value to the MediaTypeParameters. * If an parameter with the same name already exists, the parameter will be updated. * * @param {string} name The name of the media type parameter to set. * @param {string} value The media type parameter value. * @returns {MediaTypeParameters} This instance. */ set(name, value) { if (!_MediaTypeParameters.isValid(name, value)) { throw new Error(`Invalid media type parameter name/value: ${name}/${value}`); } super.set(name.toLowerCase(), value); return this; } /** * Removes the media type parameter using the specified name. * * @param {string} name The name of the media type parameter to delete. * @returns {boolean} true if the parameter existed and has been removed, or false if the parameter does not exist. */ delete(name) { return super.delete(name.toLowerCase()); } /** * Returns a string representation of the media type parameters. * * @override * @returns {string} The string representation of the media type parameters. */ toString() { return Array.from(this).map(([name, value]) => `;${name}=${!value || !utils_default.test(value) ? `"${value.replace(matcher, "\\$1")}"` : value}`).join(""); } /** * Returns the name of this class. * * @override * @returns {string} The name of this class. */ [Symbol.toStringTag]() { return "MediaTypeParameters"; } }; // node_modules/.pnpm/@d1g1tal+media-type@5.0.0/node_modules/@d1g1tal/media-type/src/media-type-parser.js var whitespaceCharacters = [" ", " ", "\n", "\r"]; var trailingWhitespace = /[ \t\n\r]+$/u; var leadingAndTrailingWhitespace = /^[ \t\n\r]+|[ \t\n\r]+$/ug; var MediaTypeParser = class _MediaTypeParser { /** * Function to parse a media type. * * @static * @param {string} input The media type to parse * @returns {{ type: string, subtype: string, parameters: MediaTypeParameters }} An object populated with the parsed media type properties and any parameters. */ static parse(input) { input = input.replace(leadingAndTrailingWhitespace, ""); const length = input.length, trim = true, lowerCase = false; let { position, result: type, subtype = "" } = _MediaTypeParser.#filterComponent({ input }, "/"); if (!type.length || position >= length || !utils_default.test(type)) { throw new TypeError(_MediaTypeParser.#generateErrorMessage("type", type)); } ({ position, result: subtype } = _MediaTypeParser.#filterComponent({ position: ++position, input, trim }, ";")); if (!subtype.length || !utils_default.test(subtype)) { throw new TypeError(_MediaTypeParser.#generateErrorMessage("subtype", subtype)); } let parameterName = "", parameterValue = null; const parameters = new MediaTypeParameters(); while (position++ < length) { while (whitespaceCharacters.includes(input[position])) { ++position; } ({ position, result: parameterName } = _MediaTypeParser.#filterComponent({ position, input, lowerCase }, ";", "=")); if (position < length) { if (input[position] == ";") { continue; } ++position; } if (input[position] == '"') { [parameterValue, position] = _MediaTypeParser.#collectHttpQuotedString(input, position); while (position < length && input[position] != ";") { ++position; } } else { ({ position, result: parameterValue } = _MediaTypeParser.#filterComponent({ position, input, lowerCase, trim }, ";")); if (!parameterValue) { continue; } } if (parameterName && MediaTypeParameters.isValid(parameterName, parameterValue) && !parameters.has(parameterName)) { parameters.set(parameterName, parameterValue); } } return { type, subtype, parameters }; } /** * Filters a component from the input string. * * @private * @static * @param {Object} options The options. * @param {number} [options.position] The starting position. * @param {string} options.input The input string. * @param {boolean} [options.lowerCase] Indicates whether the result should be lowercased. * @param {boolean} [options.trim] Indicates whether the result should be trimmed. * @param {string[]} charactersToFilter The characters to filter. * @returns {{ position: number, result: string }} An object that includes the resulting string and updated position. */ static #filterComponent({ position = 0, input, lowerCase = true, trim = false }, ...charactersToFilter) { let result = ""; for (const length = input.length; position < length && !charactersToFilter.includes(input[position]); position++) { result += input[position]; } if (lowerCase) { result = result.toLowerCase(); } if (trim) { result = result.replace(trailingWhitespace, ""); } return { position, result }; } /** * Collects all the HTTP quoted strings. * This variant only implements it with the extract-value flag set. * * @private * @static * @param {string} input The string to process. * @param {number} position The starting position. * @returns {Array<string|number>} An array that includes the resulting string and updated position. */ static #collectHttpQuotedString(input, position) { let value = ""; for (let length = input.length, char; ++position < length; ) { if ((char = input[position]) == '"') { break; } value += char == "\\" && ++position < length ? input[position] : char; } return [value, position]; } /** * Generates an error message. * * @private * @static * @param {string} component The component name. * @param {string} value The component value. * @returns {string} The error message. */ static #generateErrorMessage(component, value) { return `Invalid ${component} "${value}": only HTTP token code points are valid.`; } }; // node_modules/.pnpm/@d1g1tal+media-type@5.0.0/node_modules/@d1g1tal/media-type/src/media-type.js var MediaType = class _MediaType { /** @type {string} */ #type; /** @type {string} */ #subtype; /** @type {MediaTypeParameters} */ #parameters; /** * Create a new MediaType instance from a string representation. * * @param {string} mediaType The media type to parse. * @param {Object} [parameters] Optional parameters. */ constructor(mediaType, parameters = {}) { if (object_type_default(parameters) != Object) { throw new TypeError("The parameters argument must be an object"); } ({ type: this.#type, subtype: this.#subtype, parameters: this.#parameters } = MediaTypeParser.parse(mediaType)); for (const [name, value] of Object.entries(parameters)) { this.#parameters.set(name, value); } } static parse(mediaType) { try { return new _MediaType(mediaType); } catch (e) { } return null; } /** * Gets the type. * * @returns {string} The type. */ get type() { return this.#type; } /** * Gets the subtype. * * @returns {string} The subtype. */ get subtype() { return this.#subtype; } /** * Gets the media type essence (type/subtype). * * @returns {string} The media type without any parameters */ get essence() { return `${this.#type}/${this.#subtype}`; } /** * Gets the parameters. * * @returns {MediaTypeParameters} The media type parameters. */ get parameters() { return this.#parameters; } /** * Checks if the media type matches the specified type. * * @todo Fix string handling to parse the type and subtype from the string. * @param {MediaType|string} type The media type to check. * @returns {boolean} true if the media type matches the specified type, false otherwise. */ matches(type) { return this.#type == type?.type && this.#subtype == type?.subtype || this.essence.includes(type); } /** * Gets the serialized version of the media type. * * @returns {string} The serialized media type. */ toString() { return `${this.essence}${this.#parameters.toString()}`; } /** * Gets the name of the class. * * @returns {string} The class name */ get [Symbol.toStringTag]() { return "MediaType"; } }; // src/http-media-type.js var HttpMediaType = { /** Advanced Audio Coding (AAC) */ AAC: "audio/aac", /** AbiWord */ ABW: "application/x-abiword", /** Archive document (multiple files embedded) */ ARC: "application/x-freearc", /** AVIF image */ AVIF: "image/avif", /** Audio Video Interleave (AVI) */ AVI: "video/x-msvideo", /** Amazon Kindle eBook format */ AZW: "application/vnd.amazon.ebook", /** Binary Data */ BIN: "application/octet-stream", /** Windows OS/2 Bitmap Graphics */ BMP: "image/bmp", /** Bzip Archive */ BZIP: "application/x-bzip", /** Bzip2 Archive */ BZIP2: "application/x-bzip2", /** CD audio */ CDA: "application/x-cdf", /** C Shell Script */ CSH: "application/x-csh", /** Cascading Style Sheets (CSS) */ CSS: "text/css", /** Comma-Separated Values */ CSV: "text/csv", /** Microsoft Office Word Document */ DOC: "application/msword", /** Microsoft Office Word Document (OpenXML) */ DOCX: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", /** Microsoft Embedded OpenType */ EOT: "application/vnd.ms-fontobject", /** Electronic Publication (EPUB) */ EPUB: "application/epub+zip", /** GZip Compressed Archive */ GZIP: "application/gzip", /** Graphics Interchange Format */ GIF: "image/gif", /** HyperText Markup Language (HTML) */ HTML: "text/html", /** Icon Format */ ICO: "image/vnd.microsoft.icon", /** iCalendar Format */ ICS: "text/calendar", /** Java Archive (JAR) */ JAR: "application/java-archive", /** JPEG Image */ JPEG: "image/jpeg", /** JavaScript */ JAVA_SCRIPT: "text/javascript", /** JavaScript Object Notation Format (JSON) */ JSON: "application/json", /** JavaScript Object Notation LD Format */ JSON_LD: "application/ld+json", /** JavaScript Object Notation (JSON) Merge Patch */ JSON_MERGE_PATCH: "application/merge-patch+json", /** Musical Instrument Digital Interface (MIDI) */ MID: "audio/midi", /** Musical Instrument Digital Interface (MIDI) */ X_MID: "audio/x-midi", /** MP3 Audio */ MP3: "audio/mpeg", /** MPEG-4 Audio */ MP4A: "audio/mp4", /** MPEG-4 Video */ MP4: "video/mp4", /** MPEG Video */ MPEG: "video/mpeg", /** Apple Installer Package */ MPKG: "application/vnd.apple.installer+xml", /** OpenDocument Presentation Document */ ODP: "application/vnd.oasis.opendocument.presentation", /** OpenDocument Spreadsheet Document */ ODS: "application/vnd.oasis.opendocument.spreadsheet", /** OpenDocument Text Document */ ODT: "application/vnd.oasis.opendocument.text", /** Ogg Audio */ OGA: "audio/ogg", /** Ogg Video */ OGV: "video/ogg", /** Ogg */ OGX: "application/ogg", /** Opus audio */ OPUS: "audio/opus", /** OpenType Font File */ OTF: "font/otf", /** Portable Network Graphics (PNG) */ PNG: "image/png", /** Adobe Portable Document Format */ PDF: "application/pdf", /** Hypertext Preprocessor (Personal Home Page) */ PHP: "application/x-httpd-php", /** Microsoft PowerPoint */ PPT: "application/vnd.ms-powerpoint", /** Microsoft Office Presentation (OpenXML) */ PPTX: "application/vnd.openxmlformats-officedocument.presentationml.presentation", /** RAR Archive */ RAR: "application/vnd.rar", /** Rich Text Format */ RTF: "application/rtf", /** Bourne Shell Script */ SH: "application/x-sh", /** Scalable Vector Graphics (SVG) */ SVG: "image/svg+xml", /** Tape Archive (TAR) */ TAR: "application/x-tar", /** Tagged Image File Format (TIFF) */ TIFF: "image/tiff", /** MPEG transport stream */ TRANSPORT_STREAM: "video/mp2t", /** TrueType Font */ TTF: "font/ttf", /** Text, (generally ASCII or ISO 8859-n) */ TEXT: "text/plain", /** Microsoft Visio */ VSD: "application/vnd.visio", /** Waveform Audio Format (WAV) */ WAV: "audio/wav", /** Open Web Media Project - Audio */ WEBA: "audio/webm", /** Open Web Media Project - Video */ WEBM: "video/webm", /** WebP Image */ WEBP: "image/webp", /** Web Open Font Format */ WOFF: "font/woff", /** Web Open Font Format */ WOFF2: "font/woff2", /** Form - Encoded */ FORM: "application/x-www-form-urlencoded", /** Multipart FormData */ MULTIPART_FORM_DATA: "multipart/form-data", /** XHTML - The Extensible HyperText Markup Language */ XHTML: "application/xhtml+xml", /** Microsoft Excel Document */ XLS: "application/vnd.ms-excel", /** Microsoft Office Spreadsheet Document (OpenXML) */ XLSX: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", /** Extensible Markup Language (XML) */ XML: "application/xml", /** XML User Interface Language (XUL) */ XUL: "application/vnd.mozilla.xul+xml", /** Zip Archive */ ZIP: "application/zip", /** 3GPP audio/video container */ "3GP": "video/3gpp", /** 3GPP2 audio/video container */ "3G2": "video/3gpp2", /** 7-Zip Archive */ "7Z": "application/x-7z-compressed" }; var http_media_type_default = HttpMediaType; // src/constants.js var defaultCharset = "utf-8"; var endsWithSlashRegEx = /\/$/; var mediaTypes = /* @__PURE__ */ new Map([ [http_media_type_default.PNG, new MediaType(http_media_type_default.PNG)], [http_media_type_default.TEXT, new MediaType(http_media_type_default.TEXT, { defaultCharset })], [http_media_type_default.JSON, new MediaType(http_media_type_default.JSON, { defaultCharset })], [http_media_type_default.HTML, new MediaType(http_media_type_default.HTML, { defaultCharset })], [http_media_type_default.JAVA_SCRIPT, new MediaType(http_media_type_default.JAVA_SCRIPT, { defaultCharset })], [http_media_type_default.CSS, new MediaType(http_media_type_default.CSS, { defaultCharset })], [http_media_type_default.XML, new MediaType(http_media_type_default.XML, { defaultCharset })], [http_media_type_default.BIN, new MediaType(http_media_type_default.BIN)] ]); var RequestEvents = Object.freeze({ CONFIGURED: "configured", SUCCESS: "success", ERROR: "error", ABORTED: "aborted", TIMEOUT: "timeout", COMPLETE: "complete", ALL_COMPLETE: "all-complete" }); var SignalEvents = Object.freeze({ ABORT: "abort", TIMEOUT: "timeout" }); var _abortEvent = new CustomEvent(SignalEvents.ABORT, { detail: { cause: new DOMException("The request was aborted", "AbortError") } }); var requestBodyMethods = [http_request_methods_default.POST, http_request_methods_default.PUT, http_request_methods_default.PATCH]; var internalServerError = new ResponseStatus(500, "Internal Server Error"); var eventResponseStatuses = Object.freeze({ [RequestEvents.ABORTED]: new ResponseStatus(499, "Aborted"), [RequestEvents.TIMEOUT]: new ResponseStatus(504, "Request Timeout") }); var abortSignalProxyHandler = { get: (target, property) => property == "signal" ? target.signal.timeout(target.timeout) : Reflect.get(target, property) }; // src/abort-signal.js var AbortSignal = class { /** @type {AbortController} */ #abortController; /** @type {number} */ #timeoutId; /** * @param {NativeAbortSignal} signal The signal to chain. * This signal will be able to abort the request, but will not be notified if the request is aborted by the timeout. */ constructor(signal) { this.#abortController = new AbortController(); signal?.addEventListener(SignalEvents.ABORT, (event) => this.#abort(event)); } /** * The aborted property is a Boolean that indicates whether the request has been aborted (true) or not (false). * * @returns {boolean} Whether the signal was aborted or not */ get aborted() { return this.#abortController.signal.aborted; } /** * The reason property returns a DOMException object indicating the reason the operation was aborted, or null if the operation is not aborted. * * @returns {DOMException} The reason the signal was aborted */ get reason() { return this.#abortController.signal.reason; } /** * Returns an AbortSignal instance that will be aborted when the provided amount of milliseconds have passed. * A value of {@link Infinity} means there is no timeout. * Note: You can't set this property to a value less than 0. * * @param {number} timeout The timeout in milliseconds * @returns {AbortSignal} The abort signal */ timeout(timeout) { if (timeout < 0) { throw new RangeError("The timeout cannot be negative"); } if (timeout != Infinity) { this.#timeoutId ??= setTimeout(() => this.#abort(new CustomEvent(SignalEvents.TIMEOUT, { detail: { timeout, cause: new DOMException(`The request timed-out after ${timeout / 1e3} seconds`, "TimeoutError") } }), true), timeout); } return this.#abortController.signal; } /** * Clears the timeout. * Note: This does not abort the signal, dispatch the timeout event, or reset the timeout. * * @returns {void} */ clearTimeout() { clearTimeout(this.#timeoutId); } /** * Adds an event listener for the 'abort' event. * * @param {EventListener} listener The listener to add * @returns {AbortSignal} The AbortSignal */ onAbort(listener) { this.#abortController.signal.addEventListener(SignalEvents.ABORT, listener); return this; } /** * Adds an event listener for the 'timeout' event. * * @param {EventListener} listener The listener to add * @returns {AbortSignal} The AbortSignal */ onTimeout(listener) { this.#abortController.signal.addEventListener(SignalEvents.TIMEOUT, listener); return this; } /** * Aborts the signal. This is so naughty. ¯\_(ツ)_/¯ * * @param {Event} event The event to abort with * @returns {void} */ abort(event) { this.#abort(event); } /** * Aborts the signal. * * @private * @param {Event} event The event to abort with * @param {boolean} [dispatchEvent = false] Whether to dispatch the event or not * @returns {void} * @fires SignalEvents.ABORT When the signal is aborted * @fires SignalEvents.TIMEOUT When the signal times out */ #abort(event = _abortEvent, dispatchEvent = false) { clearTimeout(this.#timeoutId); this.#abortController.abort(event.detail?.cause); if (dispatchEvent) { this.#abortController.signal.dispatchEvent(event); } } }; // src/http-error.js var HttpError = class extends Error { /** @type {ResponseBody} */ #entity; /** @type {ResponseStatus} */ #responseStatus; /** * @param {string} [message] The error message. * @param {HttpErrorOptions} [httpErrorOptions] The http error options. * @param {any} [httpErrorOptions.cause] The cause of the error. * @param {ResponseStatus} [httpErrorOptions.status] The response status. * @param {ResponseBody} [httpErrorOptions.entity] The error entity from the server, if any. */ constructor(message, { cause, status, entity }) { super(message, { cause }); this.#entity = entity; this.#responseStatus = status; } /** * It returns the value of the private variable #entity. * * @returns {ResponseBody} The entity property of the class. */ get entity() { return this.#entity; } /** * It returns the status code of the {@link Response}. * * @returns {number} The status code of the {@link Response}. */ get statusCode() { return this.#responseStatus?.code; } /** * It returns the status text of the {@link Response}. * * @returns {string} The status code and status text of the {@link Response}. */ get statusText() { return this.#responseStatus?.text; } get name() { return "HttpError"; } /** * A String value that is used in the creation of the default string * description of an object. Called by the built-in method {@link Object.prototype.toString}. * * @returns {string} The default string description of this object. */ get [Symbol.toStringTag]() { return "HttpError"; } }; // src/http-request-headers.js var HttpRequestHeader = { /** * Content-Types that are acceptable for the response. See Content negotiation. Permanent. * * @example * <code>Accept: text/plain</code> */ ACCEPT: "accept", /** * Character sets that are acceptable. Permanent. * * @example * <code>Accept-Charset: utf-8</code> */ ACCEPT_CHARSET: "accept-charset", /** * List of acceptable encodings. See HTTP compression. Permanent. * * @example * <code>Accept-Encoding: gzip, deflate</code> */ ACCEPT_ENCODING: "accept-encoding", /** * List of acceptable human languages for response. See Content negotiation. Permanent. * * @example * <code>Accept-Lang