mirror of
https://github.com/denoland/deno.git
synced 2025-09-27 04:39:10 +00:00
Merge deno_cli_snapshots into deno_cli (#3064)
This commit is contained in:
parent
9049213867
commit
b81e5db17a
148 changed files with 38 additions and 83 deletions
139
cli/js/headers.ts
Normal file
139
cli/js/headers.ts
Normal file
|
@ -0,0 +1,139 @@
|
|||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||
import * as domTypes from "./dom_types.ts";
|
||||
import { DomIterableMixin } from "./mixins/dom_iterable.ts";
|
||||
import { requiredArguments } from "./util.ts";
|
||||
|
||||
// From node-fetch
|
||||
// Copyright (c) 2016 David Frank. MIT License.
|
||||
const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/;
|
||||
const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function isHeaders(value: any): value is domTypes.Headers {
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
return value instanceof Headers;
|
||||
}
|
||||
|
||||
const headerMap = Symbol("header map");
|
||||
|
||||
// ref: https://fetch.spec.whatwg.org/#dom-headers
|
||||
class HeadersBase {
|
||||
private [headerMap]: Map<string, string>;
|
||||
// TODO: headerGuard? Investigate if it is needed
|
||||
// node-fetch did not implement this but it is in the spec
|
||||
|
||||
private _normalizeParams(name: string, value?: string): string[] {
|
||||
name = String(name).toLowerCase();
|
||||
value = String(value).trim();
|
||||
return [name, value];
|
||||
}
|
||||
|
||||
// The following name/value validations are copied from
|
||||
// https://github.com/bitinn/node-fetch/blob/master/src/headers.js
|
||||
// Copyright (c) 2016 David Frank. MIT License.
|
||||
private _validateName(name: string): void {
|
||||
if (invalidTokenRegex.test(name) || name === "") {
|
||||
throw new TypeError(`${name} is not a legal HTTP header name`);
|
||||
}
|
||||
}
|
||||
|
||||
private _validateValue(value: string): void {
|
||||
if (invalidHeaderCharRegex.test(value)) {
|
||||
throw new TypeError(`${value} is not a legal HTTP header value`);
|
||||
}
|
||||
}
|
||||
|
||||
constructor(init?: domTypes.HeadersInit) {
|
||||
if (init === null) {
|
||||
throw new TypeError(
|
||||
"Failed to construct 'Headers'; The provided value was not valid"
|
||||
);
|
||||
} else if (isHeaders(init)) {
|
||||
this[headerMap] = new Map(init);
|
||||
} else {
|
||||
this[headerMap] = new Map();
|
||||
if (Array.isArray(init)) {
|
||||
for (const tuple of init) {
|
||||
// If header does not contain exactly two items,
|
||||
// then throw a TypeError.
|
||||
// ref: https://fetch.spec.whatwg.org/#concept-headers-fill
|
||||
requiredArguments(
|
||||
"Headers.constructor tuple array argument",
|
||||
tuple.length,
|
||||
2
|
||||
);
|
||||
|
||||
const [name, value] = this._normalizeParams(tuple[0], tuple[1]);
|
||||
this._validateName(name);
|
||||
this._validateValue(value);
|
||||
const existingValue = this[headerMap].get(name);
|
||||
this[headerMap].set(
|
||||
name,
|
||||
existingValue ? `${existingValue}, ${value}` : value
|
||||
);
|
||||
}
|
||||
} else if (init) {
|
||||
const names = Object.keys(init);
|
||||
for (const rawName of names) {
|
||||
const rawValue = init[rawName];
|
||||
const [name, value] = this._normalizeParams(rawName, rawValue);
|
||||
this._validateName(name);
|
||||
this._validateValue(value);
|
||||
this[headerMap].set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ref: https://fetch.spec.whatwg.org/#concept-headers-append
|
||||
append(name: string, value: string): void {
|
||||
requiredArguments("Headers.append", arguments.length, 2);
|
||||
const [newname, newvalue] = this._normalizeParams(name, value);
|
||||
this._validateName(newname);
|
||||
this._validateValue(newvalue);
|
||||
const v = this[headerMap].get(newname);
|
||||
const str = v ? `${v}, ${newvalue}` : newvalue;
|
||||
this[headerMap].set(newname, str);
|
||||
}
|
||||
|
||||
delete(name: string): void {
|
||||
requiredArguments("Headers.delete", arguments.length, 1);
|
||||
const [newname] = this._normalizeParams(name);
|
||||
this._validateName(newname);
|
||||
this[headerMap].delete(newname);
|
||||
}
|
||||
|
||||
get(name: string): string | null {
|
||||
requiredArguments("Headers.get", arguments.length, 1);
|
||||
const [newname] = this._normalizeParams(name);
|
||||
this._validateName(newname);
|
||||
const value = this[headerMap].get(newname);
|
||||
return value || null;
|
||||
}
|
||||
|
||||
has(name: string): boolean {
|
||||
requiredArguments("Headers.has", arguments.length, 1);
|
||||
const [newname] = this._normalizeParams(name);
|
||||
this._validateName(newname);
|
||||
return this[headerMap].has(newname);
|
||||
}
|
||||
|
||||
set(name: string, value: string): void {
|
||||
requiredArguments("Headers.set", arguments.length, 2);
|
||||
const [newname, newvalue] = this._normalizeParams(name, value);
|
||||
this._validateName(newname);
|
||||
this._validateValue(newvalue);
|
||||
this[headerMap].set(newname, newvalue);
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag](): string {
|
||||
return "Headers";
|
||||
}
|
||||
}
|
||||
|
||||
// @internal
|
||||
export class Headers extends DomIterableMixin<
|
||||
string,
|
||||
string,
|
||||
typeof HeadersBase
|
||||
>(HeadersBase, headerMap) {}
|
Loading…
Add table
Add a link
Reference in a new issue