diff options
author | Kitson Kelly <me@kitsonkelly.com> | 2020-03-29 04:03:49 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-28 13:03:49 -0400 |
commit | bced52505f32d6cca4f944bb610a8a26767908a8 (patch) | |
tree | da49a5df4b7bd6f8306248069228cd6bd0db1303 /cli/js | |
parent | 1397b8e0e7c85762e19d88fde103342bfa563360 (diff) |
Update to Prettier 2 and use ES Private Fields (#4498)
Diffstat (limited to 'cli/js')
108 files changed, 1423 insertions, 1060 deletions
diff --git a/cli/js/buffer.ts b/cli/js/buffer.ts index db2bb22e4..fcb688b9b 100644 --- a/cli/js/buffer.ts +++ b/cli/js/buffer.ts @@ -28,37 +28,37 @@ function copyBytes(dst: Uint8Array, src: Uint8Array, off = 0): number { } export class Buffer implements Reader, SyncReader, Writer, SyncWriter { - private buf: Uint8Array; // contents are the bytes buf[off : len(buf)] - private off = 0; // read at buf[off], write at buf[buf.byteLength] + #buf: Uint8Array; // contents are the bytes buf[off : len(buf)] + #off = 0; // read at buf[off], write at buf[buf.byteLength] constructor(ab?: ArrayBuffer) { if (ab == null) { - this.buf = new Uint8Array(0); + this.#buf = new Uint8Array(0); return; } - this.buf = new Uint8Array(ab); + this.#buf = new Uint8Array(ab); } bytes(): Uint8Array { - return this.buf.subarray(this.off); + return this.#buf.subarray(this.#off); } toString(): string { const decoder = new TextDecoder(); - return decoder.decode(this.buf.subarray(this.off)); + return decoder.decode(this.#buf.subarray(this.#off)); } empty(): boolean { - return this.buf.byteLength <= this.off; + return this.#buf.byteLength <= this.#off; } get length(): number { - return this.buf.byteLength - this.off; + return this.#buf.byteLength - this.#off; } get capacity(): number { - return this.buf.buffer.byteLength; + return this.#buf.buffer.byteLength; } truncate(n: number): void { @@ -69,27 +69,27 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter { if (n < 0 || n > this.length) { throw Error("bytes.Buffer: truncation out of range"); } - this._reslice(this.off + n); + this.#reslice(this.#off + n); } reset(): void { - this._reslice(0); - this.off = 0; + this.#reslice(0); + this.#off = 0; } - private _tryGrowByReslice(n: number): number { - const l = this.buf.byteLength; + #tryGrowByReslice = (n: number): number => { + const l = this.#buf.byteLength; if (n <= this.capacity - l) { - this._reslice(l + n); + this.#reslice(l + n); return l; } return -1; - } + }; - private _reslice(len: number): void { - assert(len <= this.buf.buffer.byteLength); - this.buf = new Uint8Array(this.buf.buffer, 0, len); - } + #reslice = (len: number): void => { + assert(len <= this.#buf.buffer.byteLength); + this.#buf = new Uint8Array(this.#buf.buffer, 0, len); + }; readSync(p: Uint8Array): number | EOF { if (this.empty()) { @@ -101,8 +101,8 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter { } return EOF; } - const nread = copyBytes(p, this.buf.subarray(this.off)); - this.off += nread; + const nread = copyBytes(p, this.#buf.subarray(this.#off)); + this.#off += nread; return nread; } @@ -112,8 +112,8 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter { } writeSync(p: Uint8Array): number { - const m = this._grow(p.byteLength); - return copyBytes(this.buf, p, m); + const m = this.#grow(p.byteLength); + return copyBytes(this.#buf, p, m); } write(p: Uint8Array): Promise<number> { @@ -121,14 +121,14 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter { return Promise.resolve(n); } - private _grow(n: number): number { + #grow = (n: number): number => { const m = this.length; // If buffer is empty, reset to recover space. - if (m === 0 && this.off !== 0) { + if (m === 0 && this.#off !== 0) { this.reset(); } // Fast: Try to grow by means of a reslice. - const i = this._tryGrowByReslice(n); + const i = this.#tryGrowByReslice(n); if (i >= 0) { return i; } @@ -138,41 +138,41 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter { // ArrayBuffer. We only need m+n <= c to slide, but // we instead let capacity get twice as large so we // don't spend all our time copying. - copyBytes(this.buf, this.buf.subarray(this.off)); + copyBytes(this.#buf, this.#buf.subarray(this.#off)); } else if (c > MAX_SIZE - c - n) { throw new Error("The buffer cannot be grown beyond the maximum size."); } else { // Not enough space anywhere, we need to allocate. const buf = new Uint8Array(2 * c + n); - copyBytes(buf, this.buf.subarray(this.off)); - this.buf = buf; + copyBytes(buf, this.#buf.subarray(this.#off)); + this.#buf = buf; } - // Restore this.off and len(this.buf). - this.off = 0; - this._reslice(m + n); + // Restore this.#off and len(this.#buf). + this.#off = 0; + this.#reslice(m + n); return m; - } + }; grow(n: number): void { if (n < 0) { throw Error("Buffer.grow: negative count"); } - const m = this._grow(n); - this._reslice(m); + const m = this.#grow(n); + this.#reslice(m); } async readFrom(r: Reader): Promise<number> { let n = 0; while (true) { try { - const i = this._grow(MIN_READ); - this._reslice(i); - const fub = new Uint8Array(this.buf.buffer, i); + const i = this.#grow(MIN_READ); + this.#reslice(i); + const fub = new Uint8Array(this.#buf.buffer, i); const nread = await r.read(fub); if (nread === EOF) { return n; } - this._reslice(i + nread); + this.#reslice(i + nread); n += nread; } catch (e) { return n; @@ -184,14 +184,14 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter { let n = 0; while (true) { try { - const i = this._grow(MIN_READ); - this._reslice(i); - const fub = new Uint8Array(this.buf.buffer, i); + const i = this.#grow(MIN_READ); + this.#reslice(i); + const fub = new Uint8Array(this.#buf.buffer, i); const nread = r.readSync(fub); if (nread === EOF) { return n; } - this._reslice(i + nread); + this.#reslice(i + nread); n += nread; } catch (e) { return n; diff --git a/cli/js/build.ts b/cli/js/build.ts index c34706139..f00c5b463 100644 --- a/cli/js/build.ts +++ b/cli/js/build.ts @@ -13,7 +13,7 @@ export interface BuildInfo { export const build: BuildInfo = { arch: "" as Arch, - os: "" as OperatingSystem + os: "" as OperatingSystem, }; export function setBuildInfo(os: OperatingSystem, arch: Arch): void { diff --git a/cli/js/colors.ts b/cli/js/colors.ts index 372e90ba5..d0ecdd139 100644 --- a/cli/js/colors.ts +++ b/cli/js/colors.ts @@ -17,7 +17,7 @@ function code(open: number, close: number): Code { return { open: `\x1b[${open}m`, close: `\x1b[${close}m`, - regexp: new RegExp(`\\x1b\\[${close}m`, "g") + regexp: new RegExp(`\\x1b\\[${close}m`, "g"), }; } diff --git a/cli/js/compiler.ts b/cli/js/compiler.ts index 419f07063..b3cd3a481 100644 --- a/cli/js/compiler.ts +++ b/cli/js/compiler.ts @@ -21,12 +21,12 @@ import { defaultBundlerOptions, defaultRuntimeCompileOptions, defaultTranspileOptions, - Host + Host, } from "./compiler/host.ts"; import { processImports, processLocalImports, - resolveModules + resolveModules, } from "./compiler/imports.ts"; import { createWriteFile, @@ -35,7 +35,7 @@ import { ignoredDiagnostics, WriteFileState, processConfigureResponse, - base64ToUint8Array + base64ToUint8Array, } from "./compiler/util.ts"; import { Diagnostic, DiagnosticItem } from "./diagnostics.ts"; import { fromTypeScriptDiagnostic } from "./diagnostics_util.ts"; @@ -93,7 +93,7 @@ async function compile( const { bundle, config, configPath, outFile, rootNames, target } = request; util.log(">>> compile start", { rootNames, - type: CompilerRequestType[request.type] + type: CompilerRequestType[request.type], }); // When a programme is emitted, TypeScript will call `writeFile` with @@ -108,14 +108,14 @@ async function compile( bundle, host: undefined, outFile, - rootNames + rootNames, }; const writeFile = createWriteFile(state); const host = (state.host = new Host({ bundle, target, - writeFile + writeFile, })); let diagnostics: readonly ts.Diagnostic[] | undefined; @@ -129,7 +129,7 @@ async function compile( // requesting those from the privileged side, populating the in memory // cache which will be used by the host, before resolving. const resolvedRootModules = await processImports( - rootNames.map(rootName => [rootName, rootName]), + rootNames.map((rootName) => [rootName, rootName]), undefined, bundle || host.getCompilationSettings().checkJs ); @@ -143,7 +143,7 @@ async function compile( rootNames, options, host, - oldProgram: TS_SNAPSHOT_PROGRAM + oldProgram: TS_SNAPSHOT_PROGRAM, }); diagnostics = ts @@ -171,12 +171,12 @@ async function compile( emitSkipped, diagnostics: diagnostics.length ? fromTypeScriptDiagnostic(diagnostics) - : undefined + : undefined, }; util.log("<<< compile end", { rootNames, - type: CompilerRequestType[request.type] + type: CompilerRequestType[request.type], }); return result; @@ -190,7 +190,7 @@ async function runtimeCompile( util.log(">>> runtime compile start", { rootName, bundle, - sources: sources ? Object.keys(sources) : undefined + sources: sources ? Object.keys(sources) : undefined, }); // resolve the root name, if there are sources, the root name does not @@ -232,7 +232,7 @@ async function runtimeCompile( const resolvedNames = resolveModules(additionalFiles); rootNames.push( ...(await processImports( - resolvedNames.map(rn => [rn, rn]), + resolvedNames.map((rn) => [rn, rn]), undefined, checkJsImports )) @@ -246,14 +246,14 @@ async function runtimeCompile( rootNames, sources, emitMap: {}, - emitBundle: undefined + emitBundle: undefined, }; const writeFile = createWriteFile(state); const host = (state.host = new Host({ bundle, target, - writeFile + writeFile, })); const compilerOptions = [defaultRuntimeCompileOptions]; if (convertedOptions) { @@ -268,7 +268,7 @@ async function runtimeCompile( rootNames, options: host.getCompilationSettings(), host, - oldProgram: TS_SNAPSHOT_PROGRAM + oldProgram: TS_SNAPSHOT_PROGRAM, }); if (bundle) { @@ -288,7 +288,7 @@ async function runtimeCompile( rootName, sources: sources ? Object.keys(sources) : undefined, bundle, - emitMap: Object.keys(state.emitMap) + emitMap: Object.keys(state.emitMap), }); const maybeDiagnostics = diagnostics.length @@ -320,7 +320,7 @@ function runtimeTranspile( inputText, { fileName, - compilerOptions + compilerOptions, } ); result[fileName] = { source, map }; @@ -329,7 +329,7 @@ function runtimeTranspile( } async function tsCompilerOnMessage({ - data: request + data: request, }: { data: CompilerRequest; }): Promise<void> { @@ -364,7 +364,7 @@ async function tsCompilerOnMessage({ } async function wasmCompilerOnMessage({ - data: binary + data: binary, }: { data: string; }): Promise<void> { @@ -411,12 +411,12 @@ Object.defineProperties(globalThis, { value: bootstrapWasmCompilerRuntime, enumerable: false, writable: false, - configurable: false + configurable: false, }, bootstrapTsCompilerRuntime: { value: bootstrapTsCompilerRuntime, enumerable: false, writable: false, - configurable: false - } + configurable: false, + }, }); diff --git a/cli/js/compiler/api.ts b/cli/js/compiler/api.ts index 409ad94db..b7c57b528 100644 --- a/cli/js/compiler/api.ts +++ b/cli/js/compiler/api.ts @@ -157,7 +157,7 @@ export async function transpileOnly( util.log("Deno.transpileOnly", { sources: Object.keys(sources), options }); const payload = { sources, - options: JSON.stringify(options) + options: JSON.stringify(options), }; const result = await runtimeCompilerOps.transpile(payload); return JSON.parse(result); @@ -172,12 +172,12 @@ export async function compile( rootName: sources ? rootName : checkRelative(rootName), sources, options: JSON.stringify(options), - bundle: false + bundle: false, }; util.log("Deno.compile", { rootName: payload.rootName, sources: !!sources, - options + options, }); const result = await runtimeCompilerOps.compile(payload); return JSON.parse(result); @@ -192,12 +192,12 @@ export async function bundle( rootName: sources ? rootName : checkRelative(rootName), sources, options: JSON.stringify(options), - bundle: true + bundle: true, }; util.log("Deno.bundle", { rootName: payload.rootName, sources: !!sources, - options + options, }); const result = await runtimeCompilerOps.compile(payload); return JSON.parse(result); diff --git a/cli/js/compiler/bootstrap.ts b/cli/js/compiler/bootstrap.ts index 978ddbaf8..63de783cf 100644 --- a/cli/js/compiler/bootstrap.ts +++ b/cli/js/compiler/bootstrap.ts @@ -9,7 +9,7 @@ import { getAsset } from "./util.ts"; // load all type definitions and snapshot them. const host = new Host({ target: CompilerHostTarget.Main, - writeFile(): void {} + writeFile(): void {}, }); const options = host.getCompilationSettings(); @@ -34,7 +34,7 @@ host.getSourceFile( export const TS_SNAPSHOT_PROGRAM = ts.createProgram({ rootNames: [`${ASSETS}/bootstrap.ts`], options, - host + host, }); export const SYSTEM_LOADER = getAsset("system_loader.js"); diff --git a/cli/js/compiler/bundler.ts b/cli/js/compiler/bundler.ts index 8e35befc8..c9578fe20 100644 --- a/cli/js/compiler/bundler.ts +++ b/cli/js/compiler/bundler.ts @@ -14,7 +14,7 @@ function normalizeUrl(rootName: string): string { path, false, "/", - code => code === CHAR_FORWARD_SLASH + (code) => code === CHAR_FORWARD_SLASH )}`; } else { return rootName; @@ -29,7 +29,7 @@ export function buildBundle( // when outputting to AMD and a single outfile, TypeScript makes up the module // specifiers which are used to define the modules, and doesn't expose them // publicly, so we have to try to replicate - const sources = sourceFiles.map(sf => sf.fileName); + const sources = sourceFiles.map((sf) => sf.fileName); const sharedPath = commonPath(sources); rootName = normalizeUrl(rootName) .replace(sharedPath, "") @@ -79,7 +79,7 @@ export function setRootExports(program: ts.Program, rootModule: string): void { // that when there isn't. There appears to be no clean way of figuring that // out, so inspecting SymbolFlags that might be present that are type only .filter( - sym => + (sym) => sym.flags & ts.SymbolFlags.Class || !( sym.flags & ts.SymbolFlags.Interface || @@ -94,5 +94,5 @@ export function setRootExports(program: ts.Program, rootModule: string): void { sym.flags & ts.SymbolFlags.TypeAliasExcludes ) ) - .map(sym => sym.getName()); + .map((sym) => sym.getName()); } diff --git a/cli/js/compiler/host.ts b/cli/js/compiler/host.ts index 457388bd9..70e712ffe 100644 --- a/cli/js/compiler/host.ts +++ b/cli/js/compiler/host.ts @@ -9,7 +9,7 @@ import * as util from "../util.ts"; export enum CompilerHostTarget { Main = "main", Runtime = "runtime", - Worker = "worker" + Worker = "worker", } export interface CompilerHostOptions { @@ -32,7 +32,7 @@ export const defaultBundlerOptions: ts.CompilerOptions = { outDir: undefined, outFile: `${OUT_DIR}/bundle.js`, // disabled until we have effective way to modify source maps - sourceMap: false + sourceMap: false, }; export const defaultCompileOptions: ts.CompilerOptions = { @@ -47,11 +47,11 @@ export const defaultCompileOptions: ts.CompilerOptions = { sourceMap: true, strict: true, stripComments: true, - target: ts.ScriptTarget.ESNext + target: ts.ScriptTarget.ESNext, }; export const defaultRuntimeCompileOptions: ts.CompilerOptions = { - outDir: undefined + outDir: undefined, }; export const defaultTranspileOptions: ts.CompilerOptions = { @@ -59,7 +59,7 @@ export const defaultTranspileOptions: ts.CompilerOptions = { module: ts.ModuleKind.ESNext, sourceMap: true, scriptComments: true, - target: ts.ScriptTarget.ESNext + target: ts.ScriptTarget.ESNext, }; const ignoredCompilerOptions: readonly string[] = [ @@ -117,43 +117,41 @@ const ignoredCompilerOptions: readonly string[] = [ "types", "typeRoots", "version", - "watch" + "watch", ]; -export class Host implements ts.CompilerHost { - private readonly _options = defaultCompileOptions; - - private _target: CompilerHostTarget; - - private _writeFile: WriteFileCallback; - - private _getAsset(filename: string): SourceFile { - const lastSegment = filename.split("/").pop()!; - const url = ts.libMap.has(lastSegment) - ? ts.libMap.get(lastSegment)! - : lastSegment; - const sourceFile = SourceFile.get(url); - if (sourceFile) { - return sourceFile; - } - const name = url.includes(".") ? url : `${url}.d.ts`; - const sourceCode = getAsset(name); - return new SourceFile({ - url, - filename: `${ASSETS}/${name}`, - mediaType: MediaType.TypeScript, - sourceCode - }); +function getAssetInternal(filename: string): SourceFile { + const lastSegment = filename.split("/").pop()!; + const url = ts.libMap.has(lastSegment) + ? ts.libMap.get(lastSegment)! + : lastSegment; + const sourceFile = SourceFile.get(url); + if (sourceFile) { + return sourceFile; } + const name = url.includes(".") ? url : `${url}.d.ts`; + const sourceCode = getAsset(name); + return new SourceFile({ + url, + filename: `${ASSETS}/${name}`, + mediaType: MediaType.TypeScript, + sourceCode, + }); +} + +export class Host implements ts.CompilerHost { + readonly #options = defaultCompileOptions; + #target: CompilerHostTarget; + #writeFile: WriteFileCallback; /* Deno specific APIs */ constructor({ bundle = false, target, writeFile }: CompilerHostOptions) { - this._target = target; - this._writeFile = writeFile; + this.#target = target; + this.#writeFile = writeFile; if (bundle) { // options we need to change when we are generating a bundle - Object.assign(this._options, defaultBundlerOptions); + Object.assign(this.#options, defaultBundlerOptions); } } @@ -175,22 +173,22 @@ export class Host implements ts.CompilerHost { for (const key of Object.keys(options)) { if ( ignoredCompilerOptions.includes(key) && - (!(key in this._options) || options[key] !== this._options[key]) + (!(key in this.#options) || options[key] !== this.#options[key]) ) { ignoredOptions.push(key); delete options[key]; } } - Object.assign(this._options, options); + Object.assign(this.#options, options); return { ignoredOptions: ignoredOptions.length ? ignoredOptions : undefined, - diagnostics: errors.length ? errors : undefined + diagnostics: errors.length ? errors : undefined, }; } mergeOptions(...options: ts.CompilerOptions[]): ts.CompilerOptions { - Object.assign(this._options, ...options); - return Object.assign({}, this._options); + Object.assign(this.#options, ...options); + return Object.assign({}, this.#options); } /* TypeScript CompilerHost APIs */ @@ -205,7 +203,7 @@ export class Host implements ts.CompilerHost { getCompilationSettings(): ts.CompilerOptions { util.log("compiler::host.getCompilationSettings()"); - return this._options; + return this.#options; } getCurrentDirectory(): string { @@ -214,7 +212,7 @@ export class Host implements ts.CompilerHost { getDefaultLibFileName(_options: ts.CompilerOptions): string { util.log("compiler::host.getDefaultLibFileName()"); - switch (this._target) { + switch (this.#target) { case CompilerHostTarget.Main: case CompilerHostTarget.Runtime: return `${ASSETS}/lib.deno.window.d.ts`; @@ -237,7 +235,7 @@ export class Host implements ts.CompilerHost { try { assert(!shouldCreateNewSourceFile); const sourceFile = fileName.startsWith(ASSETS) - ? this._getAsset(fileName) + ? getAssetInternal(fileName) : SourceFile.get(fileName); assert(sourceFile != null); if (!sourceFile.tsSourceFile) { @@ -278,12 +276,12 @@ export class Host implements ts.CompilerHost { ): Array<ts.ResolvedModuleFull | undefined> { util.log("compiler::host.resolveModuleNames", { moduleNames, - containingFile + containingFile, }); - return moduleNames.map(specifier => { + return moduleNames.map((specifier) => { const url = SourceFile.getUrl(specifier, containingFile); const sourceFile = specifier.startsWith(ASSETS) - ? this._getAsset(specifier) + ? getAssetInternal(specifier) : url ? SourceFile.get(url) : undefined; @@ -293,7 +291,7 @@ export class Host implements ts.CompilerHost { return { resolvedFileName: sourceFile.url, isExternalLibraryImport: specifier.startsWith(ASSETS), - extension: sourceFile.extension + extension: sourceFile.extension, }; }); } @@ -310,6 +308,6 @@ export class Host implements ts.CompilerHost { sourceFiles?: readonly ts.SourceFile[] ): void { util.log("compiler::host.writeFile", fileName); - this._writeFile(fileName, data, sourceFiles); + this.#writeFile(fileName, data, sourceFiles); } } diff --git a/cli/js/compiler/imports.ts b/cli/js/compiler/imports.ts index a3246c32f..6b48ec945 100644 --- a/cli/js/compiler/imports.ts +++ b/cli/js/compiler/imports.ts @@ -34,7 +34,7 @@ function resolvePath(...pathSegments: string[]): string { resolvedPath, !resolvedAbsolute, "/", - code => code === CHAR_FORWARD_SLASH + (code) => code === CHAR_FORWARD_SLASH ); if (resolvedAbsolute) { @@ -120,7 +120,7 @@ export function processLocalImports( url: moduleName, filename: moduleName, sourceCode: sources[moduleName], - mediaType: getMediaType(moduleName) + mediaType: getMediaType(moduleName), }); sourceFile.cache(specifiers[i][0], referrer); if (!sourceFile.processed) { diff --git a/cli/js/compiler/sourcefile.ts b/cli/js/compiler/sourcefile.ts index e400acbf5..a55de080b 100644 --- a/cli/js/compiler/sourcefile.ts +++ b/cli/js/compiler/sourcefile.ts @@ -12,7 +12,7 @@ export enum MediaType { TSX = 3, Json = 4, Wasm = 5, - Unknown = 6 + Unknown = 6, } export interface SourceFileJson { @@ -50,6 +50,11 @@ function getExtension(fileName: string, mediaType: MediaType): ts.Extension { } } +/** A global cache of module source files that have been loaded. */ +const moduleCache: Map<string, SourceFile> = new Map(); +/** A map of maps which cache source files for quicker modules resolution. */ +const specifierCache: Map<string, Map<string, SourceFile>> = new Map(); + export class SourceFile { extension!: ts.Extension; filename!: string; @@ -63,20 +68,20 @@ export class SourceFile { url!: string; constructor(json: SourceFileJson) { - if (SourceFile._moduleCache.has(json.url)) { + if (moduleCache.has(json.url)) { throw new TypeError("SourceFile already exists"); } Object.assign(this, json); this.extension = getExtension(this.url, this.mediaType); - SourceFile._moduleCache.set(this.url, this); + moduleCache.set(this.url, this); } cache(moduleSpecifier: string, containingFile?: string): void { containingFile = containingFile || ""; - let innerCache = SourceFile._specifierCache.get(containingFile); + let innerCache = specifierCache.get(containingFile); if (!innerCache) { innerCache = new Map(); - SourceFile._specifierCache.set(containingFile, innerCache); + specifierCache.set(containingFile, innerCache); } innerCache.set(moduleSpecifier, this); } @@ -112,14 +117,14 @@ export class SourceFile { importedFiles, referencedFiles, libReferenceDirectives, - typeReferenceDirectives + typeReferenceDirectives, } = preProcessedFileInfo; const typeDirectives = parseTypeDirectives(this.sourceCode); if (typeDirectives) { for (const importedFile of importedFiles) { files.push([ importedFile.fileName, - getMappedModuleName(importedFile, typeDirectives) + getMappedModuleName(importedFile, typeDirectives), ]); } } else if ( @@ -145,18 +150,11 @@ export class SourceFile { return files; } - private static _moduleCache: Map<string, SourceFile> = new Map(); - - private static _specifierCache: Map< - string, - Map<string, SourceFile> - > = new Map(); - static getUrl( moduleSpecifier: string, containingFile: string ): string | undefined { - const containingCache = this._specifierCache.get(containingFile); + const containingCache = specifierCache.get(containingFile); if (containingCache) { const sourceFile = containingCache.get(moduleSpecifier); return sourceFile && sourceFile.url; @@ -165,10 +163,10 @@ export class SourceFile { } static get(url: string): SourceFile | undefined { - return this._moduleCache.get(url); + return moduleCache.get(url); } static has(url: string): boolean { - return this._moduleCache.has(url); + return moduleCache.has(url); } } diff --git a/cli/js/compiler/type_directives.ts b/cli/js/compiler/type_directives.ts index 299532f98..5f33f4b33 100644 --- a/cli/js/compiler/type_directives.ts +++ b/cli/js/compiler/type_directives.ts @@ -39,7 +39,7 @@ export function parseTypeDirectives( directives.push({ fileName, pos, - end: pos + matchString.length + end: pos + matchString.length, }); } if (!directives.length) { @@ -60,7 +60,7 @@ export function parseTypeDirectives( const target: FileReference = { fileName: targetFileName, pos: targetPos, - end: targetPos + targetFileName.length + end: targetPos + targetFileName.length, }; results.set(target, fileName); } diff --git a/cli/js/compiler/util.ts b/cli/js/compiler/util.ts index 8acc83a2d..170dff30f 100644 --- a/cli/js/compiler/util.ts +++ b/cli/js/compiler/util.ts @@ -33,7 +33,7 @@ export interface WriteFileState { export enum CompilerRequestType { Compile = 0, RuntimeCompile = 1, - RuntimeTranspile = 2 + RuntimeTranspile = 2, } export const OUT_DIR = "$deno$"; @@ -255,7 +255,7 @@ export function convertCompilerOptions( } return { options: out as ts.CompilerOptions, - files: files.length ? files : undefined + files: files.length ? files : undefined, }; } @@ -287,7 +287,7 @@ export const ignoredDiagnostics = [ // TS7016: Could not find a declaration file for module '...'. '...' // implicitly has an 'any' type. This is due to `allowJs` being off by // default but importing of a JavaScript module. - 7016 + 7016, ]; export function processConfigureResponse( diff --git a/cli/js/deno.ts b/cli/js/deno.ts index f42e39754..2c1d2a5b7 100644 --- a/cli/js/deno.ts +++ b/cli/js/deno.ts @@ -6,7 +6,7 @@ export { readAll, readAllSync, writeAll, - writeAllSync + writeAllSync, } from "./buffer.ts"; export { build, OperatingSystem, Arch } from "./build.ts"; export { chmodSync, chmod } from "./ops/fs/chmod.ts"; @@ -18,7 +18,7 @@ export { Diagnostic, DiagnosticCategory, DiagnosticItem, - DiagnosticMessageChain + DiagnosticMessageChain, } from "./diagnostics.ts"; export { chdir, cwd } from "./ops/fs/dir.ts"; export { applySourceMap, formatDiagnostics } from "./ops/errors.ts"; @@ -36,7 +36,7 @@ export { seek, seekSync, OpenOptions, - OpenMode + OpenMode, } from "./files.ts"; export { read, readSync, write, writeSync } from "./ops/io.ts"; export { FsEvent, fsEvents } from "./ops/fs_events.ts"; @@ -57,7 +57,7 @@ export { ReadSeeker, WriteSeeker, ReadWriteCloser, - ReadWriteSeeker + ReadWriteSeeker, } from "./io.ts"; export { linkSync, link } from "./ops/fs/link.ts"; export { @@ -65,7 +65,7 @@ export { makeTempDir, makeTempFileSync, makeTempFile, - MakeTempOptions + MakeTempOptions, } from "./ops/fs/make_temp.ts"; export { metrics, Metrics } from "./ops/runtime.ts"; export { mkdirSync, mkdir, MkdirOptions } from "./ops/fs/mkdir.ts"; @@ -76,7 +76,7 @@ export { Listener, Conn, ShutdownMode, - shutdown + shutdown, } from "./net.ts"; export { dir, @@ -85,14 +85,14 @@ export { execPath, hostname, loadavg, - osRelease + osRelease, } from "./ops/os.ts"; export { permissions, PermissionName, PermissionState, PermissionStatus, - Permissions + Permissions, } from "./permissions.ts"; export { openPlugin } from "./plugins.ts"; export { kill } from "./ops/process.ts"; diff --git a/cli/js/diagnostics.ts b/cli/js/diagnostics.ts index 41a8ea8b2..d8a3f2a3c 100644 --- a/cli/js/diagnostics.ts +++ b/cli/js/diagnostics.ts @@ -10,7 +10,7 @@ export enum DiagnosticCategory { Info = 2, Error = 3, Warning = 4, - Suggestion = 5 + Suggestion = 5, } export interface DiagnosticMessageChain { diff --git a/cli/js/diagnostics_util.ts b/cli/js/diagnostics_util.ts index 24a893678..17e73e377 100644 --- a/cli/js/diagnostics_util.ts +++ b/cli/js/diagnostics_util.ts @@ -7,7 +7,7 @@ import { Diagnostic, DiagnosticCategory, DiagnosticMessageChain, - DiagnosticItem + DiagnosticItem, } from "./diagnostics.ts"; interface SourceInformation { @@ -45,7 +45,7 @@ function getSourceInformation( const scriptResourceName = sourceFile.fileName; const { line: lineNumber, - character: startColumn + character: startColumn, } = sourceFile.getLineAndCharacterOfPosition(start); const endPosition = sourceFile.getLineAndCharacterOfPosition(start + length); const endColumn = @@ -67,7 +67,7 @@ function getSourceInformation( lineNumber, scriptResourceName, startColumn, - endColumn + endColumn, }; } @@ -83,7 +83,7 @@ function fromDiagnosticMessageChain( message, code, category: fromDiagnosticCategory(category), - next: fromDiagnosticMessageChain(next) + next: fromDiagnosticMessageChain(next), }; }); } @@ -97,7 +97,7 @@ function parseDiagnostic( code, file, start: startPosition, - length + length, } = item; const sourceInfo = file && startPosition && length @@ -122,7 +122,7 @@ function parseDiagnostic( code, category, startPosition, - endPosition + endPosition, }; return sourceInfo ? { ...base, ...sourceInfo } : base; diff --git a/cli/js/error_stack.ts b/cli/js/error_stack.ts index 6ec8752e6..97e9f68de 100644 --- a/cli/js/error_stack.ts +++ b/cli/js/error_stack.ts @@ -54,7 +54,7 @@ function patchCallSite(callSite: CallSite, location: Location): CallSite { }, getPromiseIndex(): number | null { return callSite.getPromiseIndex(); - } + }, }; } @@ -181,7 +181,7 @@ function prepareStackTrace( applySourceMap({ filename, line, - column + column, }) ); } diff --git a/cli/js/errors.ts b/cli/js/errors.ts index 6aced228a..fc4021321 100644 --- a/cli/js/errors.ts +++ b/cli/js/errors.ts @@ -22,7 +22,7 @@ export enum ErrorKind { Http = 19, URIError = 20, TypeError = 21, - Other = 22 + Other = 22, } export function getErrorClass(kind: ErrorKind): { new (msg: string): Error } { @@ -190,5 +190,5 @@ export const errors = { WriteZero: WriteZero, UnexpectedEof: UnexpectedEof, BadResource: BadResource, - Http: Http + Http: Http, }; diff --git a/cli/js/file_info.ts b/cli/js/file_info.ts index 827239769..c5b884f75 100644 --- a/cli/js/file_info.ts +++ b/cli/js/file_info.ts @@ -24,8 +24,8 @@ export interface FileInfo { // @internal export class FileInfoImpl implements FileInfo { - private readonly _isFile: boolean; - private readonly _isSymlink: boolean; + readonly #isFile: boolean; + readonly #isSymlink: boolean; size: number; modified: number | null; accessed: number | null; @@ -43,28 +43,18 @@ export class FileInfoImpl implements FileInfo { blocks: number | null; /* @internal */ - constructor(private _res: StatResponse) { + constructor(res: StatResponse) { const isUnix = build.os === "mac" || build.os === "linux"; - const modified = this._res.modified; - const accessed = this._res.accessed; - const created = this._res.created; - const name = this._res.name; + const modified = res.modified; + const accessed = res.accessed; + const created = res.created; + const name = res.name; // Unix only - const { - dev, - ino, - mode, - nlink, - uid, - gid, - rdev, - blksize, - blocks - } = this._res; + const { dev, ino, mode, nlink, uid, gid, rdev, blksize, blocks } = res; - this._isFile = this._res.isFile; - this._isSymlink = this._res.isSymlink; - this.size = this._res.size; + this.#isFile = res.isFile; + this.#isSymlink = res.isSymlink; + this.size = res.size; this.modified = modified ? modified : null; this.accessed = accessed ? accessed : null; this.created = created ? created : null; @@ -82,14 +72,14 @@ export class FileInfoImpl implements FileInfo { } isFile(): boolean { - return this._isFile; + return this.#isFile; } isDirectory(): boolean { - return !this._isFile && !this._isSymlink; + return !this.#isFile && !this.#isSymlink; } isSymlink(): boolean { - return this._isSymlink; + return this.#isSymlink; } } diff --git a/cli/js/files.ts b/cli/js/files.ts index 99ae19879..d09fcf8db 100644 --- a/cli/js/files.ts +++ b/cli/js/files.ts @@ -8,7 +8,7 @@ import { SeekMode, SyncReader, SyncWriter, - SyncSeeker + SyncSeeker, } from "./io.ts"; import { close } from "./ops/resources.ts"; import { read, readSync, write, writeSync } from "./ops/io.ts"; @@ -18,7 +18,7 @@ import { open as opOpen, openSync as opOpenSync, OpenOptions, - OpenMode + OpenMode, } from "./ops/fs/open.ts"; export { OpenOptions, OpenMode } from "./ops/fs/open.ts"; @@ -119,7 +119,7 @@ export const stdout = new File(1); export const stderr = new File(2); function checkOpenOptions(options: OpenOptions): void { - if (Object.values(options).filter(val => val === true).length === 0) { + if (Object.values(options).filter((val) => val === true).length === 0) { throw new Error("OpenOptions requires at least one option to be true"); } diff --git a/cli/js/globals.ts b/cli/js/globals.ts index d71a96d39..87ff13b22 100644 --- a/cli/js/globals.ts +++ b/cli/js/globals.ts @@ -160,7 +160,7 @@ export function writable(value: unknown): PropertyDescriptor { value, writable: true, enumerable: true, - configurable: true + configurable: true, }; } @@ -168,14 +168,14 @@ export function nonEnumerable(value: unknown): PropertyDescriptor { return { value, writable: true, - configurable: true + configurable: true, }; } export function readOnly(value: unknown): PropertyDescriptor { return { value, - enumerable: true + enumerable: true, }; } @@ -183,7 +183,7 @@ export function readOnly(value: unknown): PropertyDescriptor { export function getterOnly(getter: () => any): PropertyDescriptor { return { get: getter, - enumerable: true + enumerable: true, }; } @@ -196,7 +196,7 @@ export const windowOrWorkerGlobalScopeMethods = { fetch: writable(fetchTypes.fetch), // queueMicrotask is bound in Rust setInterval: writable(timers.setInterval), - setTimeout: writable(timers.setTimeout) + setTimeout: writable(timers.setTimeout), }; // Other properties shared between WindowScope and WorkerGlobalScope @@ -216,7 +216,7 @@ export const windowOrWorkerGlobalScopeProperties = { Request: nonEnumerable(request.Request), Response: nonEnumerable(fetchTypes.Response), performance: writable(new performanceUtil.Performance()), - Worker: nonEnumerable(workers.WorkerImpl) + Worker: nonEnumerable(workers.WorkerImpl), }; export const eventTargetProperties = { @@ -233,5 +233,5 @@ export const eventTargetProperties = { dispatchEvent: readOnly(eventTarget.EventTarget.prototype.dispatchEvent), removeEventListener: readOnly( eventTarget.EventTarget.prototype.removeEventListener - ) + ), }; diff --git a/cli/js/internals.ts b/cli/js/internals.ts index 6aae1be48..174e9a0d4 100644 --- a/cli/js/internals.ts +++ b/cli/js/internals.ts @@ -11,6 +11,6 @@ export const internalObject: { [key: string]: any } = {}; export function exposeForTest(name: string, value: any): void { Object.defineProperty(internalObject, name, { value, - enumerable: false + enumerable: false, }); } diff --git a/cli/js/io.ts b/cli/js/io.ts index 5e0ee7903..b5af34224 100644 --- a/cli/js/io.ts +++ b/cli/js/io.ts @@ -11,7 +11,7 @@ export type EOF = typeof EOF; export enum SeekMode { SEEK_START = 0, SEEK_CURRENT = 1, - SEEK_END = 2 + SEEK_END = 2, } // Reader is the interface that wraps the basic read() method. @@ -99,8 +99,8 @@ export function toAsyncIterator(r: Reader): AsyncIterableIterator<Uint8Array> { return { value: b.subarray(0, result), - done: false + done: false, }; - } + }, }; } diff --git a/cli/js/lib.deno.ns.d.ts b/cli/js/lib.deno.ns.d.ts index 781387f51..ffaff4e8a 100644 --- a/cli/js/lib.deno.ns.d.ts +++ b/cli/js/lib.deno.ns.d.ts @@ -38,7 +38,7 @@ declare namespace Deno { enum TestStatus { Passed = "passed", Failed = "failed", - Ignored = "ignored" + Ignored = "ignored", } interface TestResult { @@ -60,7 +60,7 @@ declare namespace Deno { Start = "start", TestStart = "testStart", TestEnd = "testEnd", - End = "end" + End = "end", } interface TestEventStart { @@ -402,7 +402,7 @@ declare namespace Deno { export enum SeekMode { SEEK_START = 0, SEEK_CURRENT = 1, - SEEK_END = 2 + SEEK_END = 2, } /** **UNSTABLE**: might make `Reader` into iterator of some sort. */ @@ -766,12 +766,6 @@ declare namespace Deno { * * Based on [Go Buffer](https://golang.org/pkg/bytes/#Buffer). */ export class Buffer implements Reader, SyncReader, Writer, SyncWriter { - private buf; - private off; - private _tryGrowByReslice; - private _reslice; - private _grow; - constructor(ab?: ArrayBuffer); /** Returns a slice holding the unread portion of the buffer. * @@ -1603,7 +1597,7 @@ declare namespace Deno { export enum ShutdownMode { Read = 0, Write, - ReadWrite // TODO(ry) panics on ReadWrite. + ReadWrite, // TODO(ry) panics on ReadWrite. } /** **UNSTABLE**: Maybe should remove `how` parameter maybe remove @@ -1998,7 +1992,7 @@ declare namespace Deno { SIGWINCH = 28, SIGIO = 29, SIGPWR = 30, - SIGSYS = 31 + SIGSYS = 31, } enum MacOSSignal { SIGHUP = 1, @@ -2031,7 +2025,7 @@ declare namespace Deno { SIGWINCH = 28, SIGINFO = 29, SIGUSR1 = 30, - SIGUSR2 = 31 + SIGUSR2 = 31, } /** **UNSTABLE**: make platform independent. @@ -2108,7 +2102,7 @@ declare namespace Deno { Info = 2, Error = 3, Warning = 4, - Suggestion = 5 + Suggestion = 5, } export interface DiagnosticMessageChain { diff --git a/cli/js/lib.deno.shared_globals.d.ts b/cli/js/lib.deno.shared_globals.d.ts index 959dcbfe9..565121bea 100644 --- a/cli/js/lib.deno.shared_globals.d.ts +++ b/cli/js/lib.deno.shared_globals.d.ts @@ -339,12 +339,8 @@ declare namespace __domTypes { export enum NodeType { ELEMENT_NODE = 1, TEXT_NODE = 3, - DOCUMENT_FRAGMENT_NODE = 11 + DOCUMENT_FRAGMENT_NODE = 11, } - export const eventTargetHost: unique symbol; - export const eventTargetListeners: unique symbol; - export const eventTargetMode: unique symbol; - export const eventTargetNodeType: unique symbol; export interface EventListener { (evt: Event): void | Promise<void>; } @@ -358,11 +354,11 @@ declare namespace __domTypes { callback: EventListenerOrEventListenerObject; options: AddEventListenerOptions; } + export const eventTargetHost: unique symbol; + export const eventTargetListeners: unique symbol; + export const eventTargetMode: unique symbol; + export const eventTargetNodeType: unique symbol; export interface EventTarget { - [eventTargetHost]: EventTarget | null; - [eventTargetListeners]: { [type in string]: EventListener[] }; - [eventTargetMode]: string; - [eventTargetNodeType]: NodeType; addEventListener( type: string, callback: EventListenerOrEventListenerObject | null, @@ -438,7 +434,7 @@ declare namespace __domTypes { NONE = 0, CAPTURING_PHASE = 1, AT_TARGET = 2, - BUBBLING_PHASE = 3 + BUBBLING_PHASE = 3, } export interface EventPath { item: EventTarget; @@ -532,16 +528,78 @@ declare namespace __domTypes { options?: boolean | EventListenerOptions ): void; } - export interface ReadableStream { + export interface ReadableStreamReadDoneResult<T> { + done: true; + value?: T; + } + export interface ReadableStreamReadValueResult<T> { + done: false; + value: T; + } + export type ReadableStreamReadResult<T> = + | ReadableStreamReadValueResult<T> + | ReadableStreamReadDoneResult<T>; + export interface ReadableStreamDefaultReader<R = any> { + readonly closed: Promise<void>; + cancel(reason?: any): Promise<void>; + read(): Promise<ReadableStreamReadResult<R>>; + releaseLock(): void; + } + export interface PipeOptions { + preventAbort?: boolean; + preventCancel?: boolean; + preventClose?: boolean; + signal?: AbortSignal; + } + /** This Streams API interface represents a readable stream of byte data. The + * Fetch API offers a concrete instance of a ReadableStream through the body + * property of a Response object. */ + export interface ReadableStream<R = any> { readonly locked: boolean; - cancel(): Promise<void>; - getReader(): ReadableStreamReader; - tee(): [ReadableStream, ReadableStream]; + cancel(reason?: any): Promise<void>; + getReader(options: { mode: "byob" }): ReadableStreamBYOBReader; + getReader(): ReadableStreamDefaultReader<R>; + /* disabled for now + pipeThrough<T>( + { + writable, + readable + }: { + writable: WritableStream<R>; + readable: ReadableStream<T>; + }, + options?: PipeOptions + ): ReadableStream<T>; + pipeTo(dest: WritableStream<R>, options?: PipeOptions): Promise<void>; + */ + tee(): [ReadableStream<R>, ReadableStream<R>]; + } + export interface ReadableStreamReader<R = any> { + cancel(reason: any): Promise<void>; + read(): Promise<ReadableStreamReadResult<R>>; + releaseLock(): void; } - export interface ReadableStreamReader { - cancel(): Promise<void>; - read(): Promise<any>; + export interface ReadableStreamBYOBReader { + readonly closed: Promise<void>; + cancel(reason?: any): Promise<void>; + read<T extends ArrayBufferView>( + view: T + ): Promise<ReadableStreamReadResult<T>>; + releaseLock(): void; + } + export interface WritableStream<W = any> { + readonly locked: boolean; + abort(reason?: any): Promise<void>; + getWriter(): WritableStreamDefaultWriter<W>; + } + export interface WritableStreamDefaultWriter<W = any> { + readonly closed: Promise<void>; + readonly desiredSize: number | null; + readonly ready: Promise<void>; + abort(reason?: any): Promise<void>; + close(): Promise<void>; releaseLock(): void; + write(chunk: W): Promise<void>; } export interface FormData extends DomIterable<string, FormDataEntryValue> { append(name: string, value: string | Blob, fileName?: string): void; @@ -570,7 +628,7 @@ declare namespace __domTypes { } export interface Body { /** A simple getter used to expose a `ReadableStream` of the body contents. */ - readonly body: ReadableStream | null; + readonly body: ReadableStream<Uint8Array> | null; /** Stores a `Boolean` that declares whether the body has been used in a * response yet. */ @@ -799,58 +857,63 @@ declare namespace __domTypes { /** Creates a clone of a `Response` object. */ clone(): Response; } + export interface DOMStringList { + /** Returns the number of strings in strings. */ + readonly length: number; + /** Returns true if strings contains string, and false otherwise. */ + contains(string: string): boolean; + /** Returns the string with index index from strings. */ + item(index: number): string | null; + [index: number]: string; + } + /** The location (URL) of the object it is linked to. Changes done on it are + * reflected on the object it relates to. Both the Document and Window + * interface have such a linked Location, accessible via Document.location and + * Window.location respectively. */ export interface Location { - /** - * Returns a DOMStringList object listing the origins of the ancestor browsing - * contexts, from the parent browsing context to the top-level browsing - * context. - */ - readonly ancestorOrigins: string[]; - /** - * Returns the Location object's URL's fragment (includes leading "#" if + /** Returns a DOMStringList object listing the origins of the ancestor + * browsing contexts, from the parent browsing context to the top-level + * browsing context. */ + readonly ancestorOrigins: DOMStringList; + /** Returns the Location object's URL's fragment (includes leading "#" if * non-empty). + * * Can be set, to navigate to the same URL with a changed fragment (ignores - * leading "#"). - */ + * leading "#"). */ hash: string; - /** - * Returns the Location object's URL's host and port (if different from the - * default port for the scheme). Can be set, to navigate to the same URL with - * a changed host and port. - */ + /** Returns the Location object's URL's host and port (if different from the + * default port for the scheme). + * + * Can be set, to navigate to the same URL with a changed host and port. */ host: string; - /** - * Returns the Location object's URL's host. Can be set, to navigate to the - * same URL with a changed host. - */ + /** Returns the Location object's URL's host. + * + * Can be set, to navigate to the same URL with a changed host. */ hostname: string; - /** - * Returns the Location object's URL. Can be set, to navigate to the given - * URL. - */ + /** Returns the Location object's URL. + * + * Can be set, to navigate to the given URL. */ href: string; + toString(): string; /** Returns the Location object's URL's origin. */ readonly origin: string; - /** - * Returns the Location object's URL's path. - * Can be set, to navigate to the same URL with a changed path. - */ + /** Returns the Location object's URL's path. + * + * Can be set, to navigate to the same URL with a changed path. */ pathname: string; - /** - * Returns the Location object's URL's port. - * Can be set, to navigate to the same URL with a changed port. - */ + /** Returns the Location object's URL's port. + * + * Can be set, to navigate to the same URL with a changed port. */ port: string; - /** - * Returns the Location object's URL's scheme. - * Can be set, to navigate to the same URL with a changed scheme. - */ + /** Returns the Location object's URL's scheme. + * + * Can be set, to navigate to the same URL with a changed scheme. */ protocol: string; - /** - * Returns the Location object's URL's query (includes leading "?" if - * non-empty). Can be set, to navigate to the same URL with a changed query - * (ignores leading "?"). - */ + /** Returns the Location object's URL's query (includes leading "?" if + * non-empty). + * + * Can be set, to navigate to the same URL with a changed query (ignores + * leading "?"). */ search: string; /** * Navigates to the given URL. @@ -860,21 +923,14 @@ declare namespace __domTypes { * Reloads the current page. */ reload(): void; - /** @deprecated */ - reload(forcedReload: boolean): void; - /** - * Removes the current page from the session history and navigates to the - * given URL. - */ + /** Removes the current page from the session history and navigates to the + * given URL. */ replace(url: string): void; } } declare namespace __blob { - export const bytesSymbol: unique symbol; - export const blobBytesWeakMap: WeakMap<__domTypes.Blob, Uint8Array>; export class DenoBlob implements __domTypes.Blob { - private readonly [bytesSymbol]; readonly size: number; readonly type: string; /** A blob object represents a file-like object of immutable, raw data. */ @@ -899,7 +955,6 @@ declare namespace __console { } const isConsoleInstance: unique symbol; export class Console { - private printFunc; indentLevel: number; [isConsoleInstance]: boolean; /** Writes the arguments to stdout */ @@ -982,7 +1037,7 @@ declare namespace __event { constructor({ bubbles, cancelable, - composed + composed, }?: { bubbles?: boolean | undefined; cancelable?: boolean | undefined; @@ -1053,7 +1108,7 @@ declare namespace __customEvent { bubbles, cancelable, composed, - detail + detail, }: __domTypes.CustomEventInit); } export class CustomEvent extends __event.Event @@ -1083,7 +1138,7 @@ declare namespace __eventTarget { constructor({ capture, passive, - once + once, }?: { capture?: boolean | undefined; passive?: boolean | undefined; @@ -1123,7 +1178,7 @@ declare namespace __io { export enum SeekMode { SEEK_START = 0, SEEK_CURRENT = 1, - SEEK_END = 2 + SEEK_END = 2, } export interface Reader { /** Reads up to p.byteLength bytes into `p`. It resolves to the number @@ -1213,16 +1268,15 @@ declare namespace __io { declare namespace __fetch { class Body - implements __domTypes.Body, __domTypes.ReadableStream, __io.ReadCloser { - private rid; + implements + __domTypes.Body, + __domTypes.ReadableStream<Uint8Array>, + __io.ReadCloser { readonly contentType: string; bodyUsed: boolean; - private _bodyPromise; - private _data; readonly locked: boolean; - readonly body: null | Body; + readonly body: __domTypes.ReadableStream<Uint8Array>; constructor(rid: number, contentType: string); - private _bodyBuffer; arrayBuffer(): Promise<ArrayBuffer>; blob(): Promise<__domTypes.Blob>; formData(): Promise<__domTypes.FormData>; @@ -1231,7 +1285,9 @@ declare namespace __fetch { read(p: Uint8Array): Promise<number | Deno.EOF>; close(): void; cancel(): Promise<void>; - getReader(): __domTypes.ReadableStreamReader; + getReader(options: { mode: "byob" }): __domTypes.ReadableStreamBYOBReader; + getReader(): __domTypes.ReadableStreamDefaultReader<Uint8Array>; + getReader(): __domTypes.ReadableStreamBYOBReader; tee(): [__domTypes.ReadableStream, __domTypes.ReadableStream]; [Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array>; } @@ -1283,7 +1339,6 @@ declare namespace __textEncoding { ignoreBOM?: boolean; } export class TextDecoder { - private _encoding; /** Returns encoding's name, lowercased. */ readonly encoding: string; /** Returns `true` if error mode is "fatal", and `false` otherwise. */ @@ -1333,10 +1388,7 @@ declare namespace __timers { declare namespace __urlSearchParams { export class URLSearchParams { - private params; - private url; constructor(init?: string | string[][] | Record<string, string>); - private updateSteps; /** Appends a specified key/value pair as a new search parameter. * * searchParams.append('name', 'first'); @@ -1431,8 +1483,6 @@ declare namespace __urlSearchParams { * searchParams.toString(); */ toString(): string; - private _handleStringInitialization; - private _handleArrayInitialization; } } @@ -1475,16 +1525,12 @@ declare namespace __workers { name?: string; } export class WorkerImpl implements Worker { - private readonly id; - private isClosing; - private readonly isClosedPromise; onerror?: (e: Event) => void; onmessage?: (data: any) => void; onmessageerror?: () => void; constructor(specifier: string, options?: WorkerOptions); postMessage(data: any): void; terminate(): void; - private run; } } diff --git a/cli/js/main.ts b/cli/js/main.ts index 881d3ad4a..bd30d33f7 100644 --- a/cli/js/main.ts +++ b/cli/js/main.ts @@ -13,12 +13,12 @@ Object.defineProperties(globalThis, { value: bootstrapMainRuntime, enumerable: false, writable: false, - configurable: false + configurable: false, }, bootstrapWorkerRuntime: { value: bootstrapWorkerRuntime, enumerable: false, writable: false, - configurable: false - } + configurable: false, + }, }); diff --git a/cli/js/net.ts b/cli/js/net.ts index 9be97dc2e..7c0edf1f3 100644 --- a/cli/js/net.ts +++ b/cli/js/net.ts @@ -168,7 +168,7 @@ export function listen( res = netOps.listen({ transport: "tcp", hostname: "127.0.0.1", - ...(options as ListenOptions) + ...(options as ListenOptions), }); } @@ -205,7 +205,7 @@ export async function connect( res = await netOps.connect({ transport: "tcp", hostname: "127.0.0.1", - ...options + ...options, }); } diff --git a/cli/js/ops/compiler.ts b/cli/js/ops/compiler.ts index 0cbde6543..825cadc16 100644 --- a/cli/js/ops/compiler.ts +++ b/cli/js/ops/compiler.ts @@ -24,7 +24,7 @@ export function fetchSourceFiles( > { return sendAsync("op_fetch_source_files", { specifiers, - referrer + referrer, }); } @@ -47,6 +47,6 @@ export function cache( sendSync("op_cache", { extension, moduleId, - contents + contents, }); } diff --git a/cli/js/ops/dispatch_minimal.ts b/cli/js/ops/dispatch_minimal.ts index 61d630240..570463583 100644 --- a/cli/js/ops/dispatch_minimal.ts +++ b/cli/js/ops/dispatch_minimal.ts @@ -54,7 +54,7 @@ export function recordFromBufMinimal(ui8: Uint8Array): RecordMinimal { promiseId, arg, result, - err + err, }; } diff --git a/cli/js/ops/errors.ts b/cli/js/ops/errors.ts index 39793a85d..5b65d102a 100644 --- a/cli/js/ops/errors.ts +++ b/cli/js/ops/errors.ts @@ -21,11 +21,11 @@ export function applySourceMap(location: Location): Location { const res = sendSync("op_apply_source_map", { filename, line: line - 1, - column: column - 1 + column: column - 1, }); return { filename: res.filename, line: res.line + 1, - column: res.column + 1 + column: res.column + 1, }; } diff --git a/cli/js/ops/fs/open.ts b/cli/js/ops/fs/open.ts index 87696935f..b587f491d 100644 --- a/cli/js/ops/fs/open.ts +++ b/cli/js/ops/fs/open.ts @@ -36,6 +36,6 @@ export function open( path, options, openMode, - mode + mode, }); } diff --git a/cli/js/ops/fs/stat.ts b/cli/js/ops/fs/stat.ts index 20ca3e6b1..f455484c1 100644 --- a/cli/js/ops/fs/stat.ts +++ b/cli/js/ops/fs/stat.ts @@ -25,7 +25,7 @@ export interface StatResponse { export async function lstat(path: string): Promise<FileInfo> { const res = (await sendAsync("op_stat", { path, - lstat: true + lstat: true, })) as StatResponse; return new FileInfoImpl(res); } @@ -33,7 +33,7 @@ export async function lstat(path: string): Promise<FileInfo> { export function lstatSync(path: string): FileInfo { const res = sendSync("op_stat", { path, - lstat: true + lstat: true, }) as StatResponse; return new FileInfoImpl(res); } @@ -41,7 +41,7 @@ export function lstatSync(path: string): FileInfo { export async function stat(path: string): Promise<FileInfo> { const res = (await sendAsync("op_stat", { path, - lstat: false + lstat: false, })) as StatResponse; return new FileInfoImpl(res); } @@ -49,7 +49,7 @@ export async function stat(path: string): Promise<FileInfo> { export function statSync(path: string): FileInfo { const res = sendSync("op_stat", { path, - lstat: false + lstat: false, }) as StatResponse; return new FileInfoImpl(res); } diff --git a/cli/js/ops/fs/utime.ts b/cli/js/ops/fs/utime.ts index 13cac8cb6..cd195531c 100644 --- a/cli/js/ops/fs/utime.ts +++ b/cli/js/ops/fs/utime.ts @@ -14,7 +14,7 @@ export function utimeSync( path, // TODO(ry) split atime, mtime into [seconds, nanoseconds] tuple atime: toSecondsFromEpoch(atime), - mtime: toSecondsFromEpoch(mtime) + mtime: toSecondsFromEpoch(mtime), }); } @@ -27,6 +27,6 @@ export async function utime( path, // TODO(ry) split atime, mtime into [seconds, nanoseconds] tuple atime: toSecondsFromEpoch(atime), - mtime: toSecondsFromEpoch(mtime) + mtime: toSecondsFromEpoch(mtime), }); } diff --git a/cli/js/ops/fs_events.ts b/cli/js/ops/fs_events.ts index 4c08995b8..30a74f291 100644 --- a/cli/js/ops/fs_events.ts +++ b/cli/js/ops/fs_events.ts @@ -17,7 +17,7 @@ class FsEvents implements AsyncIterableIterator<FsEvent> { next(): Promise<IteratorResult<FsEvent>> { return sendAsync("op_fs_events_poll", { - rid: this.rid + rid: this.rid, }); } diff --git a/cli/js/ops/net.ts b/cli/js/ops/net.ts index 7734e8811..369f2ca3c 100644 --- a/cli/js/ops/net.ts +++ b/cli/js/ops/net.ts @@ -19,7 +19,7 @@ export enum ShutdownMode { // Corresponding to SHUT_RD, SHUT_WR, SHUT_RDWR Read = 0, Write, - ReadWrite // unused + ReadWrite, // unused } export function shutdown(rid: number, how: ShutdownMode): void { diff --git a/cli/js/ops/os.ts b/cli/js/ops/os.ts index d2fa4f2bb..e01718c8c 100644 --- a/cli/js/ops/os.ts +++ b/cli/js/ops/os.ts @@ -40,7 +40,7 @@ export function env( set(obj, prop: string, value: string): boolean { setEnv(prop, value); return Reflect.set(obj, prop, value); - } + }, }); } diff --git a/cli/js/ops/tty.ts b/cli/js/ops/tty.ts index 2d5649623..f848d2774 100644 --- a/cli/js/ops/tty.ts +++ b/cli/js/ops/tty.ts @@ -7,6 +7,6 @@ export function isatty(rid: number): boolean { export function setRaw(rid: number, mode: boolean): void { sendSync("op_set_raw", { rid, - mode + mode, }); } diff --git a/cli/js/ops/worker_host.ts b/cli/js/ops/worker_host.ts index 0b9f81795..d483a5313 100644 --- a/cli/js/ops/worker_host.ts +++ b/cli/js/ops/worker_host.ts @@ -12,7 +12,7 @@ export function createWorker( specifier, hasSourceCode, sourceCode, - name + name, }); } diff --git a/cli/js/plugins.ts b/cli/js/plugins.ts index 061193b4f..3fe0574ca 100644 --- a/cli/js/plugins.ts +++ b/cli/js/plugins.ts @@ -14,17 +14,21 @@ interface PluginOp { } class PluginOpImpl implements PluginOp { - constructor(private readonly opId: number) {} + readonly #opId: number; + + constructor(opId: number) { + this.#opId = opId; + } dispatch( control: Uint8Array, zeroCopy?: ArrayBufferView | null ): Uint8Array | null { - return core.dispatch(this.opId, control, zeroCopy); + return core.dispatch(this.#opId, control, zeroCopy); } setAsyncHandler(handler: AsyncHandler): void { - core.setAsyncHandler(this.opId, handler); + core.setAsyncHandler(this.#opId, handler); } } @@ -37,16 +41,16 @@ interface Plugin { } class PluginImpl implements Plugin { - private _ops: { [name: string]: PluginOp } = {}; + #ops: { [name: string]: PluginOp } = {}; - constructor(private readonly rid: number, ops: { [name: string]: number }) { + constructor(_rid: number, ops: { [name: string]: number }) { for (const op in ops) { - this._ops[op] = new PluginOpImpl(ops[op]); + this.#ops[op] = new PluginOpImpl(ops[op]); } } get ops(): { [name: string]: PluginOp } { - return Object.assign({}, this._ops); + return Object.assign({}, this.#ops); } } diff --git a/cli/js/process.ts b/cli/js/process.ts index 057e97f11..c72fdef30 100644 --- a/cli/js/process.ts +++ b/cli/js/process.ts @@ -113,7 +113,7 @@ export function run({ env = {}, stdout = "inherit", stderr = "inherit", - stdin = "inherit" + stdin = "inherit", }: RunOptions): Process { const res = runOp({ cmd: cmd.map(String), @@ -124,7 +124,7 @@ export function run({ stderr: isRid(stderr) ? "" : stderr, stdinRid: isRid(stdin) ? stdin : 0, stdoutRid: isRid(stdout) ? stdout : 0, - stderrRid: isRid(stderr) ? stderr : 0 + stderrRid: isRid(stderr) ? stderr : 0, }) as RunResponse; return new Process(res); } diff --git a/cli/js/rbtree.ts b/cli/js/rbtree.ts index 5de9f125d..7b01024f7 100644 --- a/cli/js/rbtree.ts +++ b/cli/js/rbtree.ts @@ -1,5 +1,7 @@ // Derived from https://github.com/vadimg/js_bintrees. MIT Licensed. +import { assert } from "./util.ts"; + class RBNode<T> { public left: this | null; public right: this | null; @@ -24,16 +26,18 @@ class RBNode<T> { } } -class RBTree<T> { - private root: RBNode<T> | null; +export class RBTree<T> { + #comparator: (a: T, b: T) => number; + #root: RBNode<T> | null; - constructor(private comparator: (a: T, b: T) => number) { - this.root = null; + constructor(comparator: (a: T, b: T) => number) { + this.#comparator = comparator; + this.#root = null; } - // returns null if tree is empty + /** Returns `null` if tree is empty. */ min(): T | null { - let res = this.root; + let res = this.#root; if (res === null) { return null; } @@ -43,11 +47,11 @@ class RBTree<T> { return res.data; } - // returns node data if found, null otherwise + /** Returns node `data` if found, `null` otherwise. */ find(data: T): T | null { - let res = this.root; + let res = this.#root; while (res !== null) { - const c = this.comparator(data, res.data!); + const c = this.#comparator(data, res.data); if (c === 0) { return res.data; } else { @@ -57,13 +61,13 @@ class RBTree<T> { return null; } - // returns true if inserted, false if duplicate + /** returns `true` if inserted, `false` if duplicate. */ insert(data: T): boolean { let ret = false; - if (this.root === null) { + if (this.#root === null) { // empty tree - this.root = new RBNode(data); + this.#root = new RBNode(data); ret = true; } else { const head = new RBNode((null as unknown) as T); // fake tree root @@ -75,8 +79,8 @@ class RBTree<T> { let gp = null; // grandparent let ggp = head; // grand-grand-parent let p: RBNode<T> | null = null; // parent - let node: RBNode<T> | null = this.root; - ggp.right = this.root; + let node: RBNode<T> | null = this.#root; + ggp.right = this.#root; // search down while (true) { @@ -96,14 +100,15 @@ class RBTree<T> { if (isRed(node) && isRed(p)) { const dir2 = ggp.right === gp; + assert(gp); if (node === p!.getChild(last)) { - ggp.setChild(dir2, singleRotate(gp!, !last)); + ggp.setChild(dir2, singleRotate(gp, !last)); } else { - ggp.setChild(dir2, doubleRotate(gp!, !last)); + ggp.setChild(dir2, doubleRotate(gp, !last)); } } - const cmp = this.comparator(node.data!, data); + const cmp = this.#comparator(node.data, data); // stop if found if (cmp === 0) { @@ -123,24 +128,24 @@ class RBTree<T> { } // update root - this.root = head.right; + this.#root = head.right; } // make root black - this.root!.red = false; + this.#root!.red = false; return ret; } - // returns true if removed, false if not found + /** Returns `true` if removed, `false` if not found. */ remove(data: T): boolean { - if (this.root === null) { + if (this.#root === null) { return false; } const head = new RBNode((null as unknown) as T); // fake tree root let node = head; - node.right = this.root; + node.right = this.#root; let p = null; // parent let gp = null; // grand parent let found = null; // found item @@ -154,7 +159,7 @@ class RBTree<T> { p = node; node = node.getChild(dir)!; - const cmp = this.comparator(data, node.data); + const cmp = this.#comparator(data, node.data); dir = cmp > 0; @@ -181,7 +186,8 @@ class RBTree<T> { sibling.red = true; node.red = true; } else { - const dir2 = gp!.right === p; + assert(gp); + const dir2 = gp.right === p; if (isRed(sibling.getChild(last))) { gp!.setChild(dir2, doubleRotate(p, last)); @@ -190,11 +196,14 @@ class RBTree<T> { } // ensure correct coloring - const gpc = gp!.getChild(dir2)!; + const gpc = gp.getChild(dir2); + assert(gpc); gpc.red = true; node.red = true; - gpc.left!.red = false; - gpc.right!.red = false; + assert(gpc.left); + gpc.left.red = false; + assert(gpc.right); + gpc.right.red = false; } } } @@ -204,13 +213,14 @@ class RBTree<T> { // replace and remove if found if (found !== null) { found.data = node.data; - p!.setChild(p!.right === node, node.getChild(node.left === null)); + assert(p); + p.setChild(p.right === node, node.getChild(node.left === null)); } // update root and make it black - this.root = head.right; - if (this.root !== null) { - this.root.red = false; + this.#root = head.right; + if (this.#root !== null) { + this.#root.red = false; } return found !== null; @@ -222,7 +232,8 @@ function isRed<T>(node: RBNode<T> | null): boolean { } function singleRotate<T>(root: RBNode<T>, dir: boolean | number): RBNode<T> { - const save = root.getChild(!dir)!; + const save = root.getChild(!dir); + assert(save); root.setChild(!dir, save.getChild(dir)); save.setChild(dir, root); @@ -237,5 +248,3 @@ function doubleRotate<T>(root: RBNode<T>, dir: boolean | number): RBNode<T> { root.setChild(!dir, singleRotate(root.getChild(!dir)!, !dir)); return singleRotate(root, dir); } - -export { RBTree }; diff --git a/cli/js/repl.ts b/cli/js/repl.ts index f1b0723c8..044713678 100644 --- a/cli/js/repl.ts +++ b/cli/js/repl.ts @@ -17,20 +17,20 @@ const helpMsg = [ "_ Get last evaluation result", "_error Get last thrown error", "exit Exit the REPL", - "help Print this help message" + "help Print this help message", ].join("\n"); const replCommands = { exit: { get(): void { exit(0); - } + }, }, help: { get(): string { return helpMsg; - } - } + }, + }, }; // Error messages that allow users to continue input @@ -42,7 +42,7 @@ const recoverableErrorMessages = [ "Missing initializer in const declaration", // const a "Missing catch or finally after try", // try {} "missing ) after argument list", // console.log(1 - "Unterminated template literal" // `template + "Unterminated template literal", // `template // TODO(kevinkassimo): need a parser to handling errors such as: // "Missing } in template expression" // `${ or `${ a 123 }` ]; @@ -105,10 +105,10 @@ export async function replLoop(): Promise<void> { value: value, writable: true, enumerable: true, - configurable: true + configurable: true, }); console.log("Last evaluation result is no longer saved to _."); - } + }, }); // Configure globalThis._error to give the last thrown error. @@ -120,10 +120,10 @@ export async function replLoop(): Promise<void> { value: value, writable: true, enumerable: true, - configurable: true + configurable: true, }); console.log("Last thrown error is no longer saved to _error."); - } + }, }); while (true) { diff --git a/cli/js/runtime_main.ts b/cli/js/runtime_main.ts index 4c506e0ce..edb02d2d6 100644 --- a/cli/js/runtime_main.ts +++ b/cli/js/runtime_main.ts @@ -17,7 +17,7 @@ import { writable, windowOrWorkerGlobalScopeMethods, windowOrWorkerGlobalScopeProperties, - eventTargetProperties + eventTargetProperties, } from "./globals.ts"; import { internalObject } from "./internals.ts"; import { setSignals } from "./signals.ts"; @@ -63,7 +63,7 @@ export const mainRuntimeGlobalProperties = { onload: writable(undefined), onunload: writable(undefined), close: writable(windowClose), - closed: getterOnly(() => windowIsClosing) + closed: getterOnly(() => windowIsClosing), }; let hasBootstrapped = false; @@ -102,7 +102,7 @@ export function bootstrapMainRuntime(): void { Object.defineProperties(Deno, { pid: readOnly(s.pid), noColor: readOnly(s.noColor), - args: readOnly(Object.freeze(s.args)) + args: readOnly(Object.freeze(s.args)), }); // Setup `Deno` global - we're actually overriding already // existing global `Deno` with `Deno` namespace from "./deno.ts". diff --git a/cli/js/runtime_worker.ts b/cli/js/runtime_worker.ts index bd051dbf2..c7742cf31 100644 --- a/cli/js/runtime_worker.ts +++ b/cli/js/runtime_worker.ts @@ -14,7 +14,7 @@ import { nonEnumerable, windowOrWorkerGlobalScopeMethods, windowOrWorkerGlobalScopeProperties, - eventTargetProperties + eventTargetProperties, } from "./globals.ts"; import * as webWorkerOps from "./ops/web_worker.ts"; import { LocationImpl } from "./web/location.ts"; @@ -85,7 +85,7 @@ export const workerRuntimeGlobalProperties = { // TODO: should be readonly? close: nonEnumerable(close), postMessage: writable(postMessage), - workerMessageRecvCallback: nonEnumerable(workerMessageRecvCallback) + workerMessageRecvCallback: nonEnumerable(workerMessageRecvCallback), }; export function bootstrapWorkerRuntime(name: string): void { diff --git a/cli/js/signals.ts b/cli/js/signals.ts index 28bc271c4..e7fd8c04d 100644 --- a/cli/js/signals.ts +++ b/cli/js/signals.ts @@ -34,7 +34,7 @@ enum LinuxSignal { SIGWINCH = 28, SIGIO = 29, SIGPWR = 30, - SIGSYS = 31 + SIGSYS = 31, } // From `kill -l` @@ -69,7 +69,7 @@ enum MacOSSignal { SIGWINCH = 28, SIGINFO = 29, SIGUSR1 = 30, - SIGUSR2 = 31 + SIGUSR2 = 31, } export const Signal: { [key: string]: number } = {}; @@ -122,39 +122,40 @@ export const signals = { }, windowChange(): SignalStream { return signal(Signal.SIGWINCH); - } + }, }; export class SignalStream implements AsyncIterableIterator<void>, PromiseLike<void> { - private rid: number; - private pollingPromise: Promise<boolean> = Promise.resolve(false); - private disposed = false; + #disposed = false; + #pollingPromise: Promise<boolean> = Promise.resolve(false); + #rid: number; + constructor(signo: number) { - this.rid = bindSignal(signo).rid; - this.loop(); + this.#rid = bindSignal(signo).rid; + this.#loop(); } - private async pollSignal(): Promise<boolean> { - const res = await pollSignal(this.rid); + #pollSignal = async (): Promise<boolean> => { + const res = await pollSignal(this.#rid); return res.done; - } + }; - private async loop(): Promise<void> { + #loop = async (): Promise<void> => { do { - this.pollingPromise = this.pollSignal(); - } while (!(await this.pollingPromise) && !this.disposed); - } + this.#pollingPromise = this.#pollSignal(); + } while (!(await this.#pollingPromise) && !this.#disposed); + }; then<T, S>( f: (v: void) => T | Promise<T>, g?: (v: Error) => S | Promise<S> ): Promise<T | S> { - return this.pollingPromise.then((_): void => {}).then(f, g); + return this.#pollingPromise.then(() => {}).then(f, g); } async next(): Promise<IteratorResult<void>> { - return { done: await this.pollingPromise, value: undefined }; + return { done: await this.#pollingPromise, value: undefined }; } [Symbol.asyncIterator](): AsyncIterableIterator<void> { @@ -162,10 +163,10 @@ export class SignalStream } dispose(): void { - if (this.disposed) { + if (this.#disposed) { throw new Error("The stream has already been disposed."); } - this.disposed = true; - unbindSignal(this.rid); + this.#disposed = true; + unbindSignal(this.#rid); } } diff --git a/cli/js/symbols.ts b/cli/js/symbols.ts index 785b47357..59d0751c0 100644 --- a/cli/js/symbols.ts +++ b/cli/js/symbols.ts @@ -4,5 +4,5 @@ import { customInspect } from "./web/console.ts"; export const symbols = { internal: internalSymbol, - customInspect + customInspect, }; diff --git a/cli/js/testing.ts b/cli/js/testing.ts index 22e719719..94a4cc702 100644 --- a/cli/js/testing.ts +++ b/cli/js/testing.ts @@ -11,7 +11,7 @@ import { assert } from "./util.ts"; const RED_FAILED = red("FAILED"); const GREEN_OK = green("ok"); const YELLOW_IGNORED = yellow("ignored"); -const disabledConsole = new Console((_x: string, _isErr?: boolean): void => {}); +const disabledConsole = new Console((): void => {}); function formatDuration(time = 0): string { const timeStr = `(${time}ms)`; @@ -140,7 +140,7 @@ export interface RunTestsOptions { enum TestStatus { Passed = "passed", Failed = "failed", - Ignored = "ignored" + Ignored = "ignored", } interface TestResult { @@ -154,7 +154,7 @@ export enum TestEvent { Start = "start", TestStart = "testStart", TestEnd = "testEnd", - End = "end" + End = "end", } interface TestEventStart { @@ -188,7 +188,7 @@ class TestApi { ignored: 0, measured: 0, passed: 0, - failed: 0 + failed: 0, }; constructor( @@ -205,7 +205,7 @@ class TestApi { > { yield { kind: TestEvent.Start, - tests: this.testsToRun.length + tests: this.testsToRun.length, }; const results: TestResult[] = []; @@ -243,7 +243,7 @@ class TestApi { kind: TestEvent.End, stats: this.stats, results, - duration + duration, }; } } @@ -283,33 +283,15 @@ interface TestReporter { } export class ConsoleTestReporter implements TestReporter { - private encoder: TextEncoder; - - constructor() { - this.encoder = new TextEncoder(); - } - - private log(msg: string, noNewLine = false): Promise<void> { - if (!noNewLine) { - msg += "\n"; - } - - // Using `stdout` here because it doesn't force new lines - // compared to `console.log`; `core.print` on the other hand - // is line-buffered and doesn't output message without newline - stdout.writeSync(this.encoder.encode(msg)); - return Promise.resolve(); - } - start(event: TestEventStart): Promise<void> { - this.log(`running ${event.tests} tests`); + ConsoleTestReporter.log(`running ${event.tests} tests`); return Promise.resolve(); } testStart(event: TestEventTestStart): Promise<void> { const { name } = event; - this.log(`test ${name} ... `, true); + ConsoleTestReporter.log(`test ${name} ... `, true); return Promise.resolve(); } @@ -318,13 +300,19 @@ export class ConsoleTestReporter implements TestReporter { switch (result.status) { case TestStatus.Passed: - this.log(`${GREEN_OK} ${formatDuration(result.duration)}`); + ConsoleTestReporter.log( + `${GREEN_OK} ${formatDuration(result.duration)}` + ); break; case TestStatus.Failed: - this.log(`${RED_FAILED} ${formatDuration(result.duration)}`); + ConsoleTestReporter.log( + `${RED_FAILED} ${formatDuration(result.duration)}` + ); break; case TestStatus.Ignored: - this.log(`${YELLOW_IGNORED} ${formatDuration(result.duration)}`); + ConsoleTestReporter.log( + `${YELLOW_IGNORED} ${formatDuration(result.duration)}` + ); break; } @@ -334,25 +322,25 @@ export class ConsoleTestReporter implements TestReporter { end(event: TestEventEnd): Promise<void> { const { stats, duration, results } = event; // Attempting to match the output of Rust's test runner. - const failedTests = results.filter(r => r.error); + const failedTests = results.filter((r) => r.error); if (failedTests.length > 0) { - this.log(`\nfailures:\n`); + ConsoleTestReporter.log(`\nfailures:\n`); for (const result of failedTests) { - this.log(`${result.name}`); - this.log(`${stringifyArgs([result.error!])}`); - this.log(""); + ConsoleTestReporter.log(`${result.name}`); + ConsoleTestReporter.log(`${stringifyArgs([result.error!])}`); + ConsoleTestReporter.log(""); } - this.log(`failures:\n`); + ConsoleTestReporter.log(`failures:\n`); for (const result of failedTests) { - this.log(`\t${result.name}`); + ConsoleTestReporter.log(`\t${result.name}`); } } - this.log( + ConsoleTestReporter.log( `\ntest result: ${stats.failed ? RED_FAILED : GREEN_OK}. ` + `${stats.passed} passed; ${stats.failed} failed; ` + `${stats.ignored} ignored; ${stats.measured} measured; ` + @@ -362,6 +350,20 @@ export class ConsoleTestReporter implements TestReporter { return Promise.resolve(); } + + static encoder = new TextEncoder(); + + static log(msg: string, noNewLine = false): Promise<void> { + if (!noNewLine) { + msg += "\n"; + } + + // Using `stdout` here because it doesn't force new lines + // compared to `console.log`; `core.print` on the other hand + // is line-buffered and doesn't output message without newline + stdout.writeSync(ConsoleTestReporter.encoder.encode(msg)); + return Promise.resolve(); + } } export async function runTests({ @@ -370,7 +372,7 @@ export async function runTests({ only = undefined, skip = undefined, disableLog = false, - reporter = undefined + reporter = undefined, }: RunTestsOptions = {}): Promise<{ results: TestResult[]; stats: TestStats; diff --git a/cli/js/tests/blob_test.ts b/cli/js/tests/blob_test.ts index 54071a11e..57793af0e 100644 --- a/cli/js/tests/blob_test.ts +++ b/cli/js/tests/blob_test.ts @@ -38,7 +38,7 @@ unitTest(function blobShouldNotThrowError(): void { try { const options1: object = { ending: "utf8", - hasOwnProperty: "hasOwnProperty" + hasOwnProperty: "hasOwnProperty", }; const options2: object = Object.create(null); new Blob(["Hello World"], options1); @@ -52,7 +52,7 @@ unitTest(function blobShouldNotThrowError(): void { unitTest(function nativeEndLine(): void { const options: object = { - ending: "native" + ending: "native", }; const blob = new Blob(["Hello\nWorld"], options); diff --git a/cli/js/tests/body_test.ts b/cli/js/tests/body_test.ts index 23f6d89e4..c8f783e04 100644 --- a/cli/js/tests/body_test.ts +++ b/cli/js/tests/body_test.ts @@ -5,7 +5,7 @@ import { unitTest, assertEquals, assert } from "./test_util.ts"; // eslint-disable-next-line @typescript-eslint/no-explicit-any function buildBody(body: any): Body { const stub = new Request("", { - body: body + body: body, }); return stub as Body; } @@ -19,7 +19,7 @@ const intArrays = [ Uint32Array, Uint8ClampedArray, Float32Array, - Float64Array + Float64Array, ]; unitTest(async function arrayBufferFromByteArrays(): Promise<void> { const buffer = new TextEncoder().encode("ahoyhoy8").buffer; diff --git a/cli/js/tests/buffer_test.ts b/cli/js/tests/buffer_test.ts index 163ed0a30..9cfb71669 100644 --- a/cli/js/tests/buffer_test.ts +++ b/cli/js/tests/buffer_test.ts @@ -7,7 +7,7 @@ import { assertEquals, assert, assertStrContains, - unitTest + unitTest, } from "./test_util.ts"; const { Buffer, readAll, readAllSync, writeAll, writeAllSync } = Deno; diff --git a/cli/js/tests/chmod_test.ts b/cli/js/tests/chmod_test.ts index e71e0bf26..8a534c701 100644 --- a/cli/js/tests/chmod_test.ts +++ b/cli/js/tests/chmod_test.ts @@ -22,7 +22,7 @@ unitTest( unitTest( { ignore: Deno.build.os === "win", - perms: { read: true, write: true } + perms: { read: true, write: true }, }, function chmodSyncSymlinkSuccess(): void { const enc = new TextEncoder(); @@ -94,7 +94,7 @@ unitTest( unitTest( { ignore: Deno.build.os === "win", - perms: { read: true, write: true } + perms: { read: true, write: true }, }, async function chmodSymlinkSuccess(): Promise<void> { const enc = new TextEncoder(); diff --git a/cli/js/tests/chown_test.ts b/cli/js/tests/chown_test.ts index f1847a08c..2d1dc7756 100644 --- a/cli/js/tests/chown_test.ts +++ b/cli/js/tests/chown_test.ts @@ -7,11 +7,11 @@ if (Deno.build.os !== "win") { // get the user ID and group ID of the current process const uidProc = Deno.run({ stdout: "piped", - cmd: ["python", "-c", "import os; print(os.getuid())"] + cmd: ["python", "-c", "import os; print(os.getuid())"], }); const gidProc = Deno.run({ stdout: "piped", - cmd: ["python", "-c", "import os; print(os.getgid())"] + cmd: ["python", "-c", "import os; print(os.getgid())"], }); assertEquals((await uidProc.status()).code, 0); diff --git a/cli/js/tests/console_test.ts b/cli/js/tests/console_test.ts index e571b02fb..b4848332f 100644 --- a/cli/js/tests/console_test.ts +++ b/cli/js/tests/console_test.ts @@ -6,14 +6,14 @@ import { assert, assertEquals, unitTest } from "./test_util.ts"; const { inspect, writeSync, - stdout + stdout, // eslint-disable-next-line @typescript-eslint/no-explicit-any } = Deno as any; const customInspect = Deno.symbols.customInspect; const { Console, - stringifyArgs + stringifyArgs, // @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol } = Deno[Deno.symbols.internal]; @@ -37,7 +37,7 @@ unitTest(function consoleHasRightInstance(): void { }); unitTest(function consoleTestAssertShouldNotThrowError(): void { - mockConsole(console => { + mockConsole((console) => { console.assert(true); let hasThrown = undefined; try { @@ -92,7 +92,7 @@ unitTest(function consoleTestStringifyCircular(): void { arrowFunc: () => {}, extendedClass: new Extended(), nFunc: new Function(), - extendedCstr: Extended + extendedCstr: Extended, }; const circularObj = { @@ -105,7 +105,7 @@ unitTest(function consoleTestStringifyCircular(): void { nested: nestedObj, emptyObj: {}, arr: [1, "s", false, null, nestedObj], - baseClass: new Base() + baseClass: new Base(), }; nestedObj.o = circularObj; @@ -154,7 +154,7 @@ unitTest(function consoleTestStringifyCircular(): void { stringify( new Map([ [1, "one"], - [2, "two"] + [2, "two"], ]) ), `Map { 1 => "one", 2 => "two" }` @@ -192,7 +192,6 @@ unitTest(function consoleTestStringifyCircular(): void { assertEquals( stringify(console), `{ - printFunc: [Function], log: [Function], debug: [Function], info: [Function], @@ -261,8 +260,8 @@ unitTest(function consoleTestStringifyLargeObject(): void { g: 10, asd: 2, asda: 3, - x: { a: "asd", x: 3 } - } + x: { a: "asd", x: 3 }, + }, }; assertEquals( stringify(obj), @@ -394,14 +393,14 @@ unitTest(function consoleTestWithVariousOrInvalidFormatSpecifier(): void { unitTest(function consoleTestCallToStringOnLabel(): void { const methods = ["count", "countReset", "time", "timeLog", "timeEnd"]; - mockConsole(console => { + mockConsole((console) => { for (const method of methods) { let hasCalled = false; // @ts-ignore console[method]({ toString(): void { hasCalled = true; - } + }, }); assertEquals(hasCalled, true); } @@ -446,7 +445,7 @@ unitTest(function consoleTestClear(): void { // Test bound this issue unitTest(function consoleDetachedLog(): void { - mockConsole(console => { + mockConsole((console) => { const log = console.log; const dir = console.dir; const dirxml = console.dirxml; @@ -635,7 +634,7 @@ unitTest(function consoleTable(): void { console.table( new Map([ [1, "one"], - [2, "two"] + [2, "two"], ]) ); assertEquals( @@ -655,7 +654,7 @@ unitTest(function consoleTable(): void { b: { c: { d: 10 }, e: [1, 2, [5, 6]] }, f: "test", g: new Set([1, 2, 3, "test"]), - h: new Map([[1, "one"]]) + h: new Map([[1, "one"]]), }); assertEquals( out.toString(), @@ -677,7 +676,7 @@ unitTest(function consoleTable(): void { "test", false, { a: 10 }, - ["test", { b: 20, c: "test" }] + ["test", { b: 20, c: "test" }], ]); assertEquals( out.toString(), @@ -745,7 +744,7 @@ unitTest(function consoleTable(): void { // console.log(Error) test unitTest(function consoleLogShouldNotThrowError(): void { - mockConsole(console => { + mockConsole((console) => { let result = 0; try { console.log(new Error("foo")); diff --git a/cli/js/tests/custom_event_test.ts b/cli/js/tests/custom_event_test.ts index 7a5cc44ca..a8b2fcf88 100644 --- a/cli/js/tests/custom_event_test.ts +++ b/cli/js/tests/custom_event_test.ts @@ -7,7 +7,7 @@ unitTest(function customEventInitializedWithDetail(): void { const customEventInit = { bubbles: true, cancelable: true, - detail + detail, } as CustomEventInit; const event = new CustomEvent(type, customEventInit); diff --git a/cli/js/tests/dispatch_minimal_test.ts b/cli/js/tests/dispatch_minimal_test.ts index 60bb620db..afc17f4fb 100644 --- a/cli/js/tests/dispatch_minimal_test.ts +++ b/cli/js/tests/dispatch_minimal_test.ts @@ -3,7 +3,7 @@ import { assertEquals, assertMatch, unitTest, - unreachable + unreachable, } from "./test_util.ts"; const readErrorStackPattern = new RegExp( diff --git a/cli/js/tests/dom_iterable_test.ts b/cli/js/tests/dom_iterable_test.ts index e16378945..827a788a9 100644 --- a/cli/js/tests/dom_iterable_test.ts +++ b/cli/js/tests/dom_iterable_test.ts @@ -5,7 +5,7 @@ import { unitTest, assert, assertEquals } from "./test_util.ts"; function setup() { const dataSymbol = Symbol("data symbol"); class Base { - private [dataSymbol] = new Map<string, number>(); + [dataSymbol] = new Map<string, number>(); constructor( data: Array<[string, number]> | IterableIterator<[string, number]> @@ -21,7 +21,7 @@ function setup() { // This is using an internal API we don't want published as types, so having // to cast to any to "trick" TypeScript // @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol - DomIterable: Deno[Deno.symbols.internal].DomIterableMixin(Base, dataSymbol) + DomIterable: Deno[Deno.symbols.internal].DomIterableMixin(Base, dataSymbol), }; } @@ -30,7 +30,7 @@ unitTest(function testDomIterable(): void { const fixture: Array<[string, number]> = [ ["foo", 1], - ["bar", 2] + ["bar", 2], ]; const domIterable = new DomIterable(fixture); diff --git a/cli/js/tests/error_stack_test.ts b/cli/js/tests/error_stack_test.ts index 7acbd3a3d..6868be215 100644 --- a/cli/js/tests/error_stack_test.ts +++ b/cli/js/tests/error_stack_test.ts @@ -76,7 +76,7 @@ function getMockCallSite( }, getPromiseIndex(): null { return null; - } + }, }; } @@ -90,7 +90,7 @@ unitTest(function prepareStackTrace(): void { structuredStackTrace: CallSite[] ) => string = MockError.prepareStackTrace; const result = prepareStackTrace(new Error("foo"), [ - getMockCallSite("CLI_SNAPSHOT.js", 23, 0) + getMockCallSite("CLI_SNAPSHOT.js", 23, 0), ]); assert(result.startsWith("Error: foo\n")); assert(result.includes(".ts:"), "should remap to something in 'js/'"); @@ -100,7 +100,7 @@ unitTest(function applySourceMap(): void { const result = Deno.applySourceMap({ filename: "CLI_SNAPSHOT.js", line: 23, - column: 0 + column: 0, }); assert(result.filename.endsWith(".ts")); assert(result.line != null); diff --git a/cli/js/tests/event_target_test.ts b/cli/js/tests/event_target_test.ts index 020db1acd..45f626502 100644 --- a/cli/js/tests/event_target_test.ts +++ b/cli/js/tests/event_target_test.ts @@ -114,7 +114,7 @@ unitTest(function dispatchEventShouldNotThrowError(): void { const target = new EventTarget(); const event = new Event("hasOwnProperty", { bubbles: true, - cancelable: false + cancelable: false, }); const listener = (): void => {}; target.addEventListener("hasOwnProperty", listener); @@ -130,7 +130,7 @@ unitTest(function eventTargetThisShouldDefaultToWindow(): void { const { addEventListener, dispatchEvent, - removeEventListener + removeEventListener, } = EventTarget.prototype; let n = 1; const event = new Event("hello"); @@ -164,7 +164,7 @@ unitTest(function eventTargetShouldAcceptEventListenerObject(): void { handleEvent(e: Event): void { assertEquals(e, event); ++callCount; - } + }, }; target.addEventListener("foo", listener); @@ -213,7 +213,7 @@ unitTest( handleEvent(e: Event): void { assertEquals(e, event); ++callCount; - } + }, }; target.addEventListener("foo", listener); diff --git a/cli/js/tests/fetch_test.ts b/cli/js/tests/fetch_test.ts index 67675177e..432ecd59c 100644 --- a/cli/js/tests/fetch_test.ts +++ b/cli/js/tests/fetch_test.ts @@ -5,7 +5,7 @@ import { assertEquals, assertStrContains, assertThrows, - fail + fail, } from "./test_util.ts"; unitTest({ perms: { net: true } }, async function fetchProtocolError(): Promise< @@ -174,7 +174,7 @@ unitTest( unitTest( { - perms: { net: true } + perms: { net: true }, }, async function fetchWithRedirection(): Promise<void> { const response = await fetch("http://localhost:4546/"); // will redirect to http://localhost:4545/ @@ -188,7 +188,7 @@ unitTest( unitTest( { - perms: { net: true } + perms: { net: true }, }, async function fetchWithRelativeRedirection(): Promise<void> { const response = await fetch("http://localhost:4545/cli/tests"); // will redirect to /cli/tests/ @@ -204,7 +204,7 @@ unitTest( // FIXME(bartlomieju): // The feature below is not implemented, but the test should work after implementation ignore: true, - perms: { net: true } + perms: { net: true }, }, async function fetchWithInfRedirection(): Promise<void> { const response = await fetch("http://localhost:4549/cli/tests"); // will redirect to the same place @@ -218,7 +218,7 @@ unitTest( const data = "Hello World"; const response = await fetch("http://localhost:4545/echo_server", { method: "POST", - body: data + body: data, }); const text = await response.text(); assertEquals(text, data); @@ -232,7 +232,7 @@ unitTest( const data = "Hello World"; const req = new Request("http://localhost:4545/echo_server", { method: "POST", - body: data + body: data, }); const response = await fetch(req); const text = await response.text(); @@ -246,7 +246,7 @@ unitTest( const data = "Hello World"; const response = await fetch("http://localhost:4545/echo_server", { method: "POST", - body: new TextEncoder().encode(data) + body: new TextEncoder().encode(data), }); const text = await response.text(); assertEquals(text, data); @@ -260,7 +260,7 @@ unitTest( const params = new URLSearchParams(data); const response = await fetch("http://localhost:4545/echo_server", { method: "POST", - body: params + body: params, }); const text = await response.text(); assertEquals(text, data); @@ -277,11 +277,11 @@ unitTest({ perms: { net: true } }, async function fetchInitBlobBody(): Promise< > { const data = "const a = 1"; const blob = new Blob([data], { - type: "text/javascript" + type: "text/javascript", }); const response = await fetch("http://localhost:4545/echo_server", { method: "POST", - body: blob + body: blob, }); const text = await response.text(); assertEquals(text, data); @@ -295,7 +295,7 @@ unitTest( form.append("field", "value"); const response = await fetch("http://localhost:4545/echo_server", { method: "POST", - body: form + body: form, }); const resultForm = await response.formData(); assertEquals(form.get("field"), resultForm.get("field")); @@ -308,7 +308,7 @@ unitTest({ perms: { net: true } }, async function fetchUserAgent(): Promise< const data = "Hello World"; const response = await fetch("http://localhost:4545/echo_server", { method: "POST", - body: new TextEncoder().encode(data) + body: new TextEncoder().encode(data), }); assertEquals(response.headers.get("user-agent"), `Deno/${Deno.version.deno}`); await response.text(); @@ -337,7 +337,7 @@ function bufferServer(addr: string): Deno.Buffer { const [hostname, port] = addr.split(":"); const listener = Deno.listen({ hostname, - port: Number(port) + port: Number(port), }) as Deno.Listener; const buf = new Deno.Buffer(); listener.accept().then(async (conn: Deno.Conn) => { @@ -364,7 +364,7 @@ unitTest( { // FIXME(bartlomieju) ignore: true, - perms: { net: true } + perms: { net: true }, }, async function fetchRequest(): Promise<void> { const addr = "127.0.0.1:4501"; @@ -373,8 +373,8 @@ unitTest( method: "POST", headers: [ ["Hello", "World"], - ["Foo", "Bar"] - ] + ["Foo", "Bar"], + ], }); assertEquals(response.status, 404); assertEquals(response.headers.get("Content-Length"), "2"); @@ -384,7 +384,7 @@ unitTest( "POST /blah HTTP/1.1\r\n", "hello: World\r\n", "foo: Bar\r\n", - `host: ${addr}\r\n\r\n` + `host: ${addr}\r\n\r\n`, ].join(""); assertEquals(actual, expected); } @@ -394,7 +394,7 @@ unitTest( { // FIXME(bartlomieju) ignore: true, - perms: { net: true } + perms: { net: true }, }, async function fetchPostBodyString(): Promise<void> { const addr = "127.0.0.1:4502"; @@ -404,9 +404,9 @@ unitTest( method: "POST", headers: [ ["Hello", "World"], - ["Foo", "Bar"] + ["Foo", "Bar"], ], - body + body, }); assertEquals(response.status, 404); assertEquals(response.headers.get("Content-Length"), "2"); @@ -418,7 +418,7 @@ unitTest( "foo: Bar\r\n", `host: ${addr}\r\n`, `content-length: ${body.length}\r\n\r\n`, - body + body, ].join(""); assertEquals(actual, expected); } @@ -428,7 +428,7 @@ unitTest( { // FIXME(bartlomieju) ignore: true, - perms: { net: true } + perms: { net: true }, }, async function fetchPostBodyTypedArray(): Promise<void> { const addr = "127.0.0.1:4503"; @@ -439,9 +439,9 @@ unitTest( method: "POST", headers: [ ["Hello", "World"], - ["Foo", "Bar"] + ["Foo", "Bar"], ], - body + body, }); assertEquals(response.status, 404); assertEquals(response.headers.get("Content-Length"), "2"); @@ -453,7 +453,7 @@ unitTest( "foo: Bar\r\n", `host: ${addr}\r\n`, `content-length: ${body.byteLength}\r\n\r\n`, - bodyStr + bodyStr, ].join(""); assertEquals(actual, expected); } @@ -461,11 +461,11 @@ unitTest( unitTest( { - perms: { net: true } + perms: { net: true }, }, async function fetchWithManualRedirection(): Promise<void> { const response = await fetch("http://localhost:4546/", { - redirect: "manual" + redirect: "manual", }); // will redirect to http://localhost:4545/ assertEquals(response.status, 0); assertEquals(response.statusText, ""); @@ -484,11 +484,11 @@ unitTest( unitTest( { - perms: { net: true } + perms: { net: true }, }, async function fetchWithErrorRedirection(): Promise<void> { const response = await fetch("http://localhost:4546/", { - redirect: "error" + redirect: "error", }); // will redirect to http://localhost:4545/ assertEquals(response.status, 0); assertEquals(response.statusText, ""); diff --git a/cli/js/tests/file_test.ts b/cli/js/tests/file_test.ts index 1a7a5f88b..4941554ad 100644 --- a/cli/js/tests/file_test.ts +++ b/cli/js/tests/file_test.ts @@ -58,7 +58,7 @@ unitTest(function fileVariousFileBits(): void { new Blob(), new Uint8Array([0x50, 0x41]), new Uint16Array([0x5353]), - new Uint32Array([0x53534150]) + new Uint32Array([0x53534150]), ], 16 ); diff --git a/cli/js/tests/files_test.ts b/cli/js/tests/files_test.ts index 39af460b8..f81ed3c47 100644 --- a/cli/js/tests/files_test.ts +++ b/cli/js/tests/files_test.ts @@ -3,7 +3,7 @@ import { unitTest, assert, assertEquals, - assertStrContains + assertStrContains, } from "./test_util.ts"; unitTest(function filesStdioFileDescriptors(): void { @@ -46,15 +46,17 @@ unitTest(async function readerToAsyncIterator(): Promise<void> { const encoder = new TextEncoder(); class TestReader implements Deno.Reader { - private offset = 0; - private buf = new Uint8Array(encoder.encode(this.s)); + #offset = 0; + #buf: Uint8Array; - constructor(private readonly s: string) {} + constructor(s: string) { + this.#buf = new Uint8Array(encoder.encode(s)); + } read(p: Uint8Array): Promise<number | Deno.EOF> { - const n = Math.min(p.byteLength, this.buf.byteLength - this.offset); - p.set(this.buf.slice(this.offset, this.offset + n)); - this.offset += n; + const n = Math.min(p.byteLength, this.#buf.byteLength - this.#offset); + p.set(this.#buf.slice(this.#offset, this.#offset + n)); + this.#offset += n; if (n === 0) { return Promise.resolve(Deno.EOF); @@ -76,14 +78,14 @@ unitTest(async function readerToAsyncIterator(): Promise<void> { unitTest( { - perms: { read: true, write: true } + perms: { read: true, write: true }, }, function openSyncMode(): void { const path = Deno.makeTempDirSync() + "/test_openSync.txt"; const file = Deno.openSync(path, { write: true, createNew: true, - mode: 0o626 + mode: 0o626, }); file.close(); const pathInfo = Deno.statSync(path); @@ -95,14 +97,14 @@ unitTest( unitTest( { - perms: { read: true, write: true } + perms: { read: true, write: true }, }, async function openMode(): Promise<void> { const path = (await Deno.makeTempDir()) + "/test_open.txt"; const file = await Deno.open(path, { write: true, createNew: true, - mode: 0o626 + mode: 0o626, }); file.close(); const pathInfo = Deno.statSync(path); @@ -198,7 +200,7 @@ unitTest( const w = { write: true, truncate: true, - create: true + create: true, }; const file = await Deno.open(filename, w); diff --git a/cli/js/tests/form_data_test.ts b/cli/js/tests/form_data_test.ts index 9b218547c..f51a51190 100644 --- a/cli/js/tests/form_data_test.ts +++ b/cli/js/tests/form_data_test.ts @@ -88,7 +88,7 @@ unitTest(function formDataSetEmptyBlobSuccess(): void { unitTest(function formDataParamsForEachSuccess(): void { const init = [ ["a", "54"], - ["b", "true"] + ["b", "true"], ]; const formData = new FormData(); for (const [name, value] of init) { @@ -110,7 +110,7 @@ unitTest(function formDataParamsArgumentsCheck(): void { "getAll", "get", "has", - "forEach" + "forEach", ] as const; const methodRequireTwoParams = ["append", "set"] as const; diff --git a/cli/js/tests/format_error_test.ts b/cli/js/tests/format_error_test.ts index 9831ef160..42c16b0c0 100644 --- a/cli/js/tests/format_error_test.ts +++ b/cli/js/tests/format_error_test.ts @@ -11,8 +11,8 @@ unitTest(function formatDiagnosticBasic() { scriptResourceName: "foo.ts", startColumn: 1, endColumn: 2, - code: 4000 - } + code: 4000, + }, ]; const out = Deno.formatDiagnostics(fixture); assert(out.includes("Example error")); diff --git a/cli/js/tests/headers_test.ts b/cli/js/tests/headers_test.ts index fcb5385a5..1ed58c9a4 100644 --- a/cli/js/tests/headers_test.ts +++ b/cli/js/tests/headers_test.ts @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { unitTest, assert, assertEquals } from "./test_util.ts"; const { - stringifyArgs + stringifyArgs, // @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol } = Deno[Deno.symbols.internal]; @@ -29,7 +29,7 @@ const headerDict: Record<string, string> = { name3: "value3", // @ts-ignore name4: undefined, - "Content-Type": "value4" + "Content-Type": "value4", }; // eslint-disable-next-line @typescript-eslint/no-explicit-any const headerSeq: any[] = []; @@ -142,7 +142,7 @@ const headerEntriesDict: Record<string, string> = { name: "value3", "content-Type": "value4", "Content-Typ": "value5", - "Content-Types": "value6" + "Content-Types": "value6", }; unitTest(function headerForEachSuccess(): void { @@ -346,7 +346,7 @@ unitTest(function customInspectReturnsCorrectHeadersFormat(): void { ); const multiParamHeader = new Headers([ ["Content-Type", "application/json"], - ["Content-Length", "1337"] + ["Content-Length", "1337"], ]); assertEquals( stringify(multiParamHeader), diff --git a/cli/js/tests/internals_test.ts b/cli/js/tests/internals_test.ts index fb712707c..b794bb5e8 100644 --- a/cli/js/tests/internals_test.ts +++ b/cli/js/tests/internals_test.ts @@ -3,7 +3,7 @@ import { unitTest, assert } from "./test_util.ts"; unitTest(function internalsExists(): void { const { - stringifyArgs + stringifyArgs, // @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol } = Deno[Deno.symbols.internal]; assert(!!stringifyArgs); diff --git a/cli/js/tests/net_test.ts b/cli/js/tests/net_test.ts index 2c077c102..6eb0f0dc6 100644 --- a/cli/js/tests/net_test.ts +++ b/cli/js/tests/net_test.ts @@ -3,7 +3,7 @@ import { unitTest, assert, assertEquals, - createResolvable + createResolvable, } from "./test_util.ts"; unitTest({ perms: { net: true } }, function netTcpListenClose(): void { @@ -18,13 +18,13 @@ unitTest( { perms: { net: true }, // TODO: - ignore: Deno.build.os === "win" + ignore: Deno.build.os === "win", }, function netUdpListenClose(): void { const socket = Deno.listen({ hostname: "127.0.0.1", port: 4500, - transport: "udp" + transport: "udp", }); assert(socket.addr.transport === "udp"); assertEquals(socket.addr.hostname, "127.0.0.1"); @@ -39,7 +39,7 @@ unitTest( const filePath = Deno.makeTempFileSync(); const socket = Deno.listen({ address: filePath, - transport: "unix" + transport: "unix", }); assert(socket.addr.transport === "unix"); assertEquals(socket.addr.address, filePath); @@ -53,7 +53,7 @@ unitTest( const filePath = Deno.makeTempFileSync(); const socket = Deno.listen({ address: filePath, - transport: "unixpacket" + transport: "unixpacket", }); assert(socket.addr.transport === "unixpacket"); assertEquals(socket.addr.address, filePath); @@ -63,7 +63,7 @@ unitTest( unitTest( { - perms: { net: true } + perms: { net: true }, }, async function netTcpCloseWhileAccept(): Promise<void> { const listener = Deno.listen({ port: 4501 }); @@ -87,7 +87,7 @@ unitTest( const filePath = await Deno.makeTempFile(); const listener = Deno.listen({ address: filePath, - transport: "unix" + transport: "unix", }); const p = listener.accept(); listener.close(); @@ -337,7 +337,7 @@ unitTest( { // FIXME(bartlomieju) ignore: true, - perms: { net: true } + perms: { net: true }, }, async function netListenAsyncIterator(): Promise<void> { const addr = { hostname: "127.0.0.1", port: 4500 }; @@ -372,14 +372,14 @@ unitTest( { // FIXME(bartlomieju) ignore: true, - perms: { net: true } + perms: { net: true }, }, async function netCloseReadSuccess() { const addr = { hostname: "127.0.0.1", port: 4500 }; const listener = Deno.listen(addr); const closeDeferred = createResolvable(); const closeReadDeferred = createResolvable(); - listener.accept().then(async conn => { + listener.accept().then(async (conn) => { await closeReadDeferred; await conn.write(new Uint8Array([1, 2, 3])); const buf = new Uint8Array(1024); @@ -409,13 +409,13 @@ unitTest( { // FIXME(bartlomieju) ignore: true, - perms: { net: true } + perms: { net: true }, }, async function netDoubleCloseRead() { const addr = { hostname: "127.0.0.1", port: 4500 }; const listener = Deno.listen(addr); const closeDeferred = createResolvable(); - listener.accept().then(async conn => { + listener.accept().then(async (conn) => { await conn.write(new Uint8Array([1, 2, 3])); await closeDeferred; conn.close(); @@ -441,13 +441,13 @@ unitTest( { // FIXME(bartlomieju) ignore: true, - perms: { net: true } + perms: { net: true }, }, async function netCloseWriteSuccess() { const addr = { hostname: "127.0.0.1", port: 4500 }; const listener = Deno.listen(addr); const closeDeferred = createResolvable(); - listener.accept().then(async conn => { + listener.accept().then(async (conn) => { await conn.write(new Uint8Array([1, 2, 3])); await closeDeferred; conn.close(); @@ -480,13 +480,13 @@ unitTest( { // FIXME(bartlomieju) ignore: true, - perms: { net: true } + perms: { net: true }, }, async function netDoubleCloseWrite() { const addr = { hostname: "127.0.0.1", port: 4500 }; const listener = Deno.listen(addr); const closeDeferred = createResolvable(); - listener.accept().then(async conn => { + listener.accept().then(async (conn) => { await closeDeferred; conn.close(); }); @@ -509,7 +509,7 @@ unitTest( unitTest( { - perms: { net: true } + perms: { net: true }, }, async function netHangsOnClose() { let acceptedConn: Deno.Conn; diff --git a/cli/js/tests/os_test.ts b/cli/js/tests/os_test.ts index ef45d36fe..423cded50 100644 --- a/cli/js/tests/os_test.ts +++ b/cli/js/tests/os_test.ts @@ -4,7 +4,7 @@ import { assertEquals, assertNotEquals, assertThrows, - unitTest + unitTest, } from "./test_util.ts"; unitTest({ perms: { env: true } }, function envSuccess(): void { @@ -67,7 +67,7 @@ unitTest( const proc = Deno.run({ cmd: [Deno.execPath(), "eval", src], env: inputEnv, - stdout: "piped" + stdout: "piped", }); const status = await proc.status(); assertEquals(status.success, true); @@ -134,121 +134,121 @@ unitTest({ perms: { env: true } }, function getDir(): void { runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: true } - ] + { os: "linux", shouldHaveValue: true }, + ], }, { kind: "cache", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: true } - ] + { os: "linux", shouldHaveValue: true }, + ], }, { kind: "executable", runtime: [ { os: "mac", shouldHaveValue: false }, { os: "win", shouldHaveValue: false }, - { os: "linux", shouldHaveValue: true } - ] + { os: "linux", shouldHaveValue: true }, + ], }, { kind: "data", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: true } - ] + { os: "linux", shouldHaveValue: true }, + ], }, { kind: "data_local", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: true } - ] + { os: "linux", shouldHaveValue: true }, + ], }, { kind: "audio", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: false } - ] + { os: "linux", shouldHaveValue: false }, + ], }, { kind: "desktop", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: false } - ] + { os: "linux", shouldHaveValue: false }, + ], }, { kind: "document", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: false } - ] + { os: "linux", shouldHaveValue: false }, + ], }, { kind: "download", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: false } - ] + { os: "linux", shouldHaveValue: false }, + ], }, { kind: "font", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: false }, - { os: "linux", shouldHaveValue: true } - ] + { os: "linux", shouldHaveValue: true }, + ], }, { kind: "picture", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: false } - ] + { os: "linux", shouldHaveValue: false }, + ], }, { kind: "public", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: false } - ] + { os: "linux", shouldHaveValue: false }, + ], }, { kind: "template", runtime: [ { os: "mac", shouldHaveValue: false }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: false } - ] + { os: "linux", shouldHaveValue: false }, + ], }, { kind: "tmp", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: true } - ] + { os: "linux", shouldHaveValue: true }, + ], }, { kind: "video", runtime: [ { os: "mac", shouldHaveValue: true }, { os: "win", shouldHaveValue: true }, - { os: "linux", shouldHaveValue: false } - ] - } + { os: "linux", shouldHaveValue: false }, + ], + }, ]; for (const s of scenes) { diff --git a/cli/js/tests/process_test.ts b/cli/js/tests/process_test.ts index 216b8a3bd..47efd86d5 100644 --- a/cli/js/tests/process_test.ts +++ b/cli/js/tests/process_test.ts @@ -3,7 +3,7 @@ import { assert, assertEquals, assertStrContains, - unitTest + unitTest, } from "./test_util.ts"; const { kill, run, readFile, open, makeTempDir, writeFile } = Deno; @@ -22,7 +22,7 @@ unitTest({ perms: { run: true } }, async function runSuccess(): Promise<void> { const p = run({ cmd: ["python", "-c", "print('hello world')"], stdout: "piped", - stderr: "null" + stderr: "null", }); const status = await p.status(); assertEquals(status.success, true); @@ -36,7 +36,7 @@ unitTest( { perms: { run: true } }, async function runCommandFailedWithCode(): Promise<void> { const p = run({ - cmd: ["python", "-c", "import sys;sys.exit(41 + 1)"] + cmd: ["python", "-c", "import sys;sys.exit(41 + 1)"], }); const status = await p.status(); assertEquals(status.success, false); @@ -50,11 +50,11 @@ unitTest( { // No signals on windows. ignore: Deno.build.os === "win", - perms: { run: true } + perms: { run: true }, }, async function runCommandFailedWithSignal(): Promise<void> { const p = run({ - cmd: ["python", "-c", "import os;os.kill(os.getpid(), 9)"] + cmd: ["python", "-c", "import os;os.kill(os.getpid(), 9)"], }); const status = await p.status(); assertEquals(status.success, false); @@ -102,7 +102,7 @@ while True: Deno.writeFileSync(`${cwd}/${pyProgramFile}.py`, enc.encode(pyProgram)); const p = run({ cwd, - cmd: ["python", `${pyProgramFile}.py`] + cmd: ["python", `${pyProgramFile}.py`], }); // Write the expected exit code *after* starting python. @@ -123,7 +123,7 @@ unitTest({ perms: { run: true } }, async function runStdinPiped(): Promise< > { const p = run({ cmd: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"], - stdin: "piped" + stdin: "piped", }); assert(p.stdin); assert(!p.stdout); @@ -147,7 +147,7 @@ unitTest({ perms: { run: true } }, async function runStdoutPiped(): Promise< > { const p = run({ cmd: ["python", "-c", "import sys; sys.stdout.write('hello')"], - stdout: "piped" + stdout: "piped", }); assert(!p.stdin); assert(!p.stderr); @@ -176,7 +176,7 @@ unitTest({ perms: { run: true } }, async function runStderrPiped(): Promise< > { const p = run({ cmd: ["python", "-c", "import sys; sys.stderr.write('hello')"], - stderr: "piped" + stderr: "piped", }); assert(!p.stdin); assert(!p.stdout); @@ -203,7 +203,7 @@ unitTest({ perms: { run: true } }, async function runStderrPiped(): Promise< unitTest({ perms: { run: true } }, async function runOutput(): Promise<void> { const p = run({ cmd: ["python", "-c", "import sys; sys.stdout.write('hello')"], - stdout: "piped" + stdout: "piped", }); const output = await p.output(); const s = new TextDecoder().decode(output); @@ -216,7 +216,7 @@ unitTest({ perms: { run: true } }, async function runStderrOutput(): Promise< > { const p = run({ cmd: ["python", "-c", "import sys; sys.stderr.write('error')"], - stderr: "piped" + stderr: "piped", }); const error = await p.stderrOutput(); const s = new TextDecoder().decode(error); @@ -235,10 +235,10 @@ unitTest( cmd: [ "python", "-c", - "import sys; sys.stderr.write('error\\n'); sys.stdout.write('output\\n');" + "import sys; sys.stderr.write('error\\n'); sys.stdout.write('output\\n');", ], stdout: file.rid, - stderr: file.rid + stderr: file.rid, }); await p.status(); @@ -265,7 +265,7 @@ unitTest( const p = run({ cmd: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"], - stdin: file.rid + stdin: file.rid, }); const status = await p.status(); @@ -280,13 +280,13 @@ unitTest({ perms: { run: true } }, async function runEnv(): Promise<void> { cmd: [ "python", "-c", - "import os, sys; sys.stdout.write(os.environ.get('FOO', '') + os.environ.get('BAR', ''))" + "import os, sys; sys.stdout.write(os.environ.get('FOO', '') + os.environ.get('BAR', ''))", ], env: { FOO: "0123", - BAR: "4567" + BAR: "4567", }, - stdout: "piped" + stdout: "piped", }); const output = await p.output(); const s = new TextDecoder().decode(output); @@ -299,9 +299,9 @@ unitTest({ perms: { run: true } }, async function runClose(): Promise<void> { cmd: [ "python", "-c", - "from time import sleep; import sys; sleep(10000); sys.stderr.write('error')" + "from time import sleep; import sys; sleep(10000); sys.stderr.write('error')", ], - stderr: "piped" + stderr: "piped", }); assert(!p.stdin); assert(!p.stdout); @@ -343,7 +343,7 @@ if (Deno.build.os !== "win") { void > { const p = run({ - cmd: ["python", "-c", "from time import sleep; sleep(10000)"] + cmd: ["python", "-c", "from time import sleep; sleep(10000)"], }); assertEquals(Deno.Signal.SIGINT, 2); @@ -361,7 +361,7 @@ if (Deno.build.os !== "win") { unitTest({ perms: { run: true } }, function killFailed(): void { const p = run({ - cmd: ["python", "-c", "from time import sleep; sleep(10000)"] + cmd: ["python", "-c", "from time import sleep; sleep(10000)"], }); assert(!p.stdin); assert(!p.stdout); diff --git a/cli/js/tests/realpath_test.ts b/cli/js/tests/realpath_test.ts index d185e4095..7725a3aa8 100644 --- a/cli/js/tests/realpath_test.ts +++ b/cli/js/tests/realpath_test.ts @@ -15,7 +15,7 @@ unitTest({ perms: { read: true } }, function realpathSyncSuccess(): void { unitTest( { ignore: Deno.build.os === "win", - perms: { read: true, write: true } + perms: { read: true, write: true }, }, function realpathSyncSymlink(): void { const testDir = Deno.makeTempDirSync(); @@ -67,7 +67,7 @@ unitTest({ perms: { read: true } }, async function realpathSuccess(): Promise< unitTest( { ignore: Deno.build.os === "win", - perms: { read: true, write: true } + perms: { read: true, write: true }, }, async function realpathSymlink(): Promise<void> { const testDir = Deno.makeTempDirSync(); diff --git a/cli/js/tests/request_test.ts b/cli/js/tests/request_test.ts index 15e19e285..8a276c5e7 100644 --- a/cli/js/tests/request_test.ts +++ b/cli/js/tests/request_test.ts @@ -6,8 +6,8 @@ unitTest(function fromInit(): void { body: "ahoyhoy", method: "POST", headers: { - "test-header": "value" - } + "test-header": "value", + }, }); // @ts-ignore @@ -34,7 +34,7 @@ unitTest(async function cloneRequestBodyStream(): Promise<void> { // hack to get a stream const stream = new Request("", { body: "a test body" }).body; const r1 = new Request("https://example.com", { - body: stream + body: stream, }); const r2 = r1.clone(); diff --git a/cli/js/tests/signal_test.ts b/cli/js/tests/signal_test.ts index c966e696b..a51df09d7 100644 --- a/cli/js/tests/signal_test.ts +++ b/cli/js/tests/signal_test.ts @@ -4,7 +4,7 @@ import { assert, assertEquals, assertThrows, - createResolvable + createResolvable, } from "./test_util.ts"; function defer(n: number): Promise<void> { diff --git a/cli/js/tests/test_util.ts b/cli/js/tests/test_util.ts index 980d32bac..da2e917f8 100644 --- a/cli/js/tests/test_util.ts +++ b/cli/js/tests/test_util.ts @@ -10,7 +10,7 @@ export { assertStrictEq, assertStrContains, unreachable, - fail + fail, } from "../../../std/testing/asserts.ts"; export { readLines } from "../../../std/io/bufio.ts"; export { parse as parseArgs } from "../../../std/flags/mod.ts"; @@ -28,7 +28,7 @@ export interface Permissions { export function fmtPerms(perms: Permissions): string { const p = Object.keys(perms) .filter((e): boolean => perms[e as keyof Permissions] === true) - .map(key => `--allow-${key}`); + .map((key) => `--allow-${key}`); if (p.length) { return p.join(" "); @@ -48,7 +48,7 @@ export async function getProcessPermissions(): Promise<Permissions> { net: await isGranted("net"), env: await isGranted("env"), plugin: await isGranted("plugin"), - hrtime: await isGranted("hrtime") + hrtime: await isGranted("hrtime"), }; } @@ -108,7 +108,7 @@ function normalizeTestPermissions(perms: UnitTestPermissions): Permissions { run: !!perms.run, env: !!perms.env, plugin: !!perms.plugin, - hrtime: !!perms.hrtime + hrtime: !!perms.hrtime, }; } @@ -170,7 +170,7 @@ export function unitTest( name, fn, ignore: !!options.ignore, - perms: normalizedPerms + perms: normalizedPerms, }; REGISTERED_UNIT_TESTS.push(unitTestDefinition); @@ -194,17 +194,19 @@ export function createResolvable<T>(): Resolvable<T> { return Object.assign(promise, methods!) as Resolvable<T>; } +const encoder = new TextEncoder(); + export class SocketReporter implements Deno.TestReporter { - private encoder: TextEncoder; + #conn: Deno.Conn; - constructor(private conn: Deno.Conn) { - this.encoder = new TextEncoder(); + constructor(conn: Deno.Conn) { + this.#conn = conn; } // eslint-disable-next-line @typescript-eslint/no-explicit-any async write(msg: any): Promise<void> { - const encodedMsg = this.encoder.encode(JSON.stringify(msg) + "\n"); - await Deno.writeAll(this.conn, encodedMsg); + const encodedMsg = encoder.encode(JSON.stringify(msg) + "\n"); + await Deno.writeAll(this.#conn, encodedMsg); } async start(msg: Deno.TestEventStart): Promise<void> { @@ -229,9 +231,9 @@ export class SocketReporter implements Deno.TestReporter { } async end(msg: Deno.TestEventEnd): Promise<void> { - const encodedMsg = this.encoder.encode(JSON.stringify(msg)); - await Deno.writeAll(this.conn, encodedMsg); - this.conn.closeWrite(); + const encodedMsg = encoder.encode(JSON.stringify(msg)); + await Deno.writeAll(this.#conn, encodedMsg); + this.#conn.closeWrite(); } } @@ -245,7 +247,7 @@ unitTest(function permissionsMatches(): void { env: false, run: false, plugin: false, - hrtime: false + hrtime: false, }, normalizeTestPermissions({ read: true }) ) @@ -260,7 +262,7 @@ unitTest(function permissionsMatches(): void { env: false, run: false, plugin: false, - hrtime: false + hrtime: false, }, normalizeTestPermissions({}) ) @@ -275,7 +277,7 @@ unitTest(function permissionsMatches(): void { env: true, run: true, plugin: true, - hrtime: true + hrtime: true, }, normalizeTestPermissions({ read: true }) ), @@ -291,7 +293,7 @@ unitTest(function permissionsMatches(): void { env: false, run: false, plugin: false, - hrtime: false + hrtime: false, }, normalizeTestPermissions({ read: true }) ), @@ -307,7 +309,7 @@ unitTest(function permissionsMatches(): void { env: true, run: true, plugin: true, - hrtime: true + hrtime: true, }, { read: true, @@ -316,7 +318,7 @@ unitTest(function permissionsMatches(): void { env: true, run: true, plugin: true, - hrtime: true + hrtime: true, } ) ); @@ -330,9 +332,9 @@ unitTest( { perms: { read: true } }, function assertAllUnitTestFilesImported(): void { const directoryTestFiles = Deno.readdirSync("./cli/js/tests/") - .map(k => k.name) + .map((k) => k.name) .filter( - file => + (file) => file!.endsWith(".ts") && !file!.endsWith("unit_tests.ts") && !file!.endsWith("test_util.ts") && @@ -344,12 +346,12 @@ unitTest( const importLines = new TextDecoder("utf-8") .decode(unitTestsFile) .split("\n") - .filter(line => line.startsWith("import")); + .filter((line) => line.startsWith("import")); const importedTestFiles = importLines.map( - relativeFilePath => relativeFilePath.match(/\/([^\/]+)";/)![1] + (relativeFilePath) => relativeFilePath.match(/\/([^\/]+)";/)![1] ); - directoryTestFiles.forEach(dirFile => { + directoryTestFiles.forEach((dirFile) => { if (!importedTestFiles.includes(dirFile!)) { throw new Error( "cil/js/tests/unit_tests.ts is missing import of test file: cli/js/" + diff --git a/cli/js/tests/testing_test.ts b/cli/js/tests/testing_test.ts index 9ed89f532..09378ec30 100644 --- a/cli/js/tests/testing_test.ts +++ b/cli/js/tests/testing_test.ts @@ -18,7 +18,7 @@ unitTest(function nameOfTestCaseCantBeEmpty(): void { () => { Deno.test({ name: "", - fn: () => {} + fn: () => {}, }); }, TypeError, @@ -29,7 +29,7 @@ unitTest(function nameOfTestCaseCantBeEmpty(): void { unitTest(function testFnCantBeAnonymous(): void { assertThrows( () => { - Deno.test(function() {}); + Deno.test(function () {}); }, TypeError, "The test function can't be anonymous" diff --git a/cli/js/tests/text_encoding_test.ts b/cli/js/tests/text_encoding_test.ts index e85655feb..c8a7fbe42 100644 --- a/cli/js/tests/text_encoding_test.ts +++ b/cli/js/tests/text_encoding_test.ts @@ -21,7 +21,7 @@ unitTest(function atobWithAsciiWhitespace(): void { "aGVsbG8gd29ybGQ=\n", "aGVsbG\t8gd29ybGQ=", `aGVsbG\t8g - d29ybGQ=` + d29ybGQ=`, ]; for (const encoded of encodedList) { diff --git a/cli/js/tests/timers_test.ts b/cli/js/tests/timers_test.ts index f758d5fca..7adff0095 100644 --- a/cli/js/tests/timers_test.ts +++ b/cli/js/tests/timers_test.ts @@ -4,7 +4,7 @@ import { createResolvable, assert, assertEquals, - assertNotEquals + assertNotEquals, } from "./test_util.ts"; function deferred(): { @@ -23,7 +23,7 @@ function deferred(): { return { promise, resolve: resolve!, - reject: reject! + reject: reject!, }; } @@ -180,7 +180,7 @@ unitTest(async function timeoutCallbackThis(): Promise<void> { foo(): void { assertEquals(this, window); resolve(); - } + }, }; setTimeout(obj.foo, 1); await promise; @@ -198,7 +198,7 @@ unitTest(async function timeoutBindThis(): Promise<void> { [], "foo", (): void => {}, - Object.prototype + Object.prototype, ]; for (const thisArg of thisCheckPassed) { @@ -240,7 +240,7 @@ unitTest(function clearTimeoutShouldConvertToNumber(): void { valueOf(): number { called = true; return 1; - } + }, }; clearTimeout((obj as unknown) as number); assert(called); diff --git a/cli/js/tests/tls_test.ts b/cli/js/tests/tls_test.ts index 20dd62f9b..019b81652 100644 --- a/cli/js/tests/tls_test.ts +++ b/cli/js/tests/tls_test.ts @@ -3,7 +3,7 @@ import { assert, assertEquals, createResolvable, - unitTest + unitTest, } from "./test_util.ts"; import { BufWriter, BufReader } from "../../../std/io/bufio.ts"; import { TextProtoReader } from "../../../std/textproto/mod.ts"; @@ -28,7 +28,7 @@ unitTest(async function connectTLSCertFileNoReadPerm(): Promise<void> { await Deno.connectTLS({ hostname: "github.com", port: 443, - certFile: "cli/tests/tls/RootCA.crt" + certFile: "cli/tests/tls/RootCA.crt", }); } catch (e) { err = e; @@ -45,13 +45,13 @@ unitTest( hostname: "localhost", port: 4500, certFile: "cli/tests/tls/localhost.crt", - keyFile: "cli/tests/tls/localhost.key" + keyFile: "cli/tests/tls/localhost.key", }; try { Deno.listenTLS({ ...options, - certFile: "./non/existent/file" + certFile: "./non/existent/file", }); } catch (e) { err = e; @@ -61,7 +61,7 @@ unitTest( try { Deno.listenTLS({ ...options, - keyFile: "./non/existent/file" + keyFile: "./non/existent/file", }); } catch (e) { err = e; @@ -77,7 +77,7 @@ unitTest({ perms: { net: true } }, function listenTLSNoReadPerm(): void { hostname: "localhost", port: 4500, certFile: "cli/tests/tls/localhost.crt", - keyFile: "cli/tests/tls/localhost.key" + keyFile: "cli/tests/tls/localhost.key", }); } catch (e) { err = e; @@ -88,7 +88,7 @@ unitTest({ perms: { net: true } }, function listenTLSNoReadPerm(): void { unitTest( { - perms: { read: true, write: true, net: true } + perms: { read: true, write: true, net: true }, }, function listenTLSEmptyKeyFile(): void { let err; @@ -96,19 +96,19 @@ unitTest( hostname: "localhost", port: 4500, certFile: "cli/tests/tls/localhost.crt", - keyFile: "cli/tests/tls/localhost.key" + keyFile: "cli/tests/tls/localhost.key", }; const testDir = Deno.makeTempDirSync(); const keyFilename = testDir + "/key.pem"; Deno.writeFileSync(keyFilename, new Uint8Array([]), { - mode: 0o666 + mode: 0o666, }); try { Deno.listenTLS({ ...options, - keyFile: keyFilename + keyFile: keyFilename, }); } catch (e) { err = e; @@ -125,19 +125,19 @@ unitTest( hostname: "localhost", port: 4500, certFile: "cli/tests/tls/localhost.crt", - keyFile: "cli/tests/tls/localhost.key" + keyFile: "cli/tests/tls/localhost.key", }; const testDir = Deno.makeTempDirSync(); const certFilename = testDir + "/cert.crt"; Deno.writeFileSync(certFilename, new Uint8Array([]), { - mode: 0o666 + mode: 0o666, }); try { Deno.listenTLS({ ...options, - certFile: certFilename + certFile: certFilename, }); } catch (e) { err = e; @@ -157,7 +157,7 @@ unitTest( hostname, port, certFile: "cli/tests/tls/localhost.crt", - keyFile: "cli/tests/tls/localhost.key" + keyFile: "cli/tests/tls/localhost.key", }); const response = encoder.encode( @@ -180,7 +180,7 @@ unitTest( const conn = await Deno.connectTLS({ hostname, port, - certFile: "cli/tests/tls/RootCA.pem" + certFile: "cli/tests/tls/RootCA.pem", }); assert(conn.rid > 0); const w = new BufWriter(conn); diff --git a/cli/js/tests/umask_test.ts b/cli/js/tests/umask_test.ts index e4576c515..71a5e71f8 100644 --- a/cli/js/tests/umask_test.ts +++ b/cli/js/tests/umask_test.ts @@ -3,7 +3,7 @@ import { unitTest, assertEquals } from "./test_util.ts"; unitTest( { - ignore: Deno.build.os === "win" + ignore: Deno.build.os === "win", }, function umaskSuccess(): void { const prevMask = Deno.umask(0o020); diff --git a/cli/js/tests/unit_test_runner.ts b/cli/js/tests/unit_test_runner.ts index e79e1b7ea..8d3eaa4f5 100755 --- a/cli/js/tests/unit_test_runner.ts +++ b/cli/js/tests/unit_test_runner.ts @@ -8,7 +8,7 @@ import { registerUnitTests, SocketReporter, fmtPerms, - parseArgs + parseArgs, } from "./test_util.ts"; interface PermissionSetTestResult { @@ -27,7 +27,7 @@ const PERMISSIONS: Deno.PermissionName[] = [ "env", "run", "plugin", - "hrtime" + "hrtime", ]; /** @@ -69,7 +69,7 @@ async function workerRunnerMain( failFast: false, exitOnFail: false, reporter: socketReporter, - only: filter + only: filter, }); } @@ -93,7 +93,7 @@ function spawnWorkerRunner( "cli/js/tests/unit_test_runner.ts", "--worker", `--addr=${addr}`, - `--perms=${permStr}` + `--perms=${permStr}`, ]; if (filter) { @@ -107,7 +107,7 @@ function spawnWorkerRunner( cmd, stdin: ioMode, stdout: ioMode, - stderr: ioMode + stderr: ioMode, }); return p; @@ -177,7 +177,7 @@ async function runTestsForPermissionSet( permsStr: permsFmt, duration: endEvent.duration, stats: endEvent.stats, - results: endEvent.results + results: endEvent.results, }; } @@ -223,7 +223,7 @@ async function masterRunnerMain( kind: Deno.TestEvent.End, stats, duration, - results + results, }); testsPassed = testsPassed && testResult.passed; } @@ -288,7 +288,7 @@ function assertOrHelp(expr: unknown): asserts expr { async function main(): Promise<void> { const args = parseArgs(Deno.args, { boolean: ["master", "worker", "verbose"], - "--": true + "--": true, }); if (args.help) { @@ -315,7 +315,7 @@ async function main(): Promise<void> { await Deno.runTests({ failFast: false, exitOnFail: true, - only: filter + only: filter, }); } diff --git a/cli/js/tests/url_search_params_test.ts b/cli/js/tests/url_search_params_test.ts index b256395a0..3e71d2900 100644 --- a/cli/js/tests/url_search_params_test.ts +++ b/cli/js/tests/url_search_params_test.ts @@ -13,7 +13,7 @@ unitTest(function urlSearchParamsInitString(): void { unitTest(function urlSearchParamsInitIterable(): void { const init = [ ["a", "54"], - ["b", "true"] + ["b", "true"], ]; const searchParams = new URLSearchParams(init); assertEquals(searchParams.toString(), "a=54&b=true"); @@ -94,7 +94,7 @@ unitTest(function urlSearchParamsSortSuccess(): void { unitTest(function urlSearchParamsForEachSuccess(): void { const init = [ ["a", "54"], - ["b", "true"] + ["b", "true"], ]; const searchParams = new URLSearchParams(init); let callNum = 0; @@ -225,7 +225,7 @@ unitTest(function urlSearchParamsDeletingAppendedMultiple(): void { // ref: https://github.com/web-platform-tests/wpt/blob/master/url/urlsearchparams-constructor.any.js#L176-L182 unitTest(function urlSearchParamsCustomSymbolIterator(): void { const params = new URLSearchParams(); - params[Symbol.iterator] = function*(): IterableIterator<[string, string]> { + params[Symbol.iterator] = function* (): IterableIterator<[string, string]> { yield ["a", "b"]; }; const params1 = new URLSearchParams((params as unknown) as string[][]); @@ -236,7 +236,7 @@ unitTest( function urlSearchParamsCustomSymbolIteratorWithNonStringParams(): void { const params = {}; // @ts-ignore - params[Symbol.iterator] = function*(): IterableIterator<[number, number]> { + params[Symbol.iterator] = function* (): IterableIterator<[number, number]> { yield [1, 2]; }; const params1 = new URLSearchParams((params as unknown) as string[][]); diff --git a/cli/js/tests/url_test.ts b/cli/js/tests/url_test.ts index 5b3067e4b..e1b2d47bd 100644 --- a/cli/js/tests/url_test.ts +++ b/cli/js/tests/url_test.ts @@ -98,6 +98,12 @@ unitTest(function urlModifyHref(): void { assertEquals(url.hash, "#qux"); }); +unitTest(function urlNormalize(): void { + const url = new URL("http://example.com"); + assertEquals(url.pathname, "/"); + assertEquals(url.href, "http://example.com/"); +}); + unitTest(function urlModifyPathname(): void { const url = new URL("http://foo.bar/baz%qat/qux%quux"); assertEquals(url.pathname, "/baz%qat/qux%quux"); @@ -183,7 +189,7 @@ unitTest(function sortingNonExistentParamRemovesQuestionMarkFromURL(): void { unitTest( { // FIXME(bartlomieju) - ignore: true + ignore: true, }, function customInspectFunction(): void { const url = new URL("http://example.com/?"); diff --git a/cli/js/tests/utime_test.ts b/cli/js/tests/utime_test.ts index 8cd34d39a..917b8b8b6 100644 --- a/cli/js/tests/utime_test.ts +++ b/cli/js/tests/utime_test.ts @@ -15,7 +15,7 @@ unitTest( const testDir = Deno.makeTempDirSync(); const filename = testDir + "/file.txt"; Deno.writeFileSync(filename, new TextEncoder().encode("hello"), { - mode: 0o666 + mode: 0o666, }); const atime = 1000; @@ -115,7 +115,7 @@ unitTest( const testDir = Deno.makeTempDirSync(); const filename = testDir + "/file.txt"; Deno.writeFileSync(filename, new TextEncoder().encode("hello"), { - mode: 0o666 + mode: 0o666, }); const atime = 1000; diff --git a/cli/js/tls.ts b/cli/js/tls.ts index 5a9b9ace0..ef87b5aa1 100644 --- a/cli/js/tls.ts +++ b/cli/js/tls.ts @@ -15,13 +15,13 @@ export async function connectTLS({ port, hostname = "127.0.0.1", transport = "tcp", - certFile = undefined + certFile = undefined, }: ConnectTLSOptions): Promise<Conn> { const res = await tlsOps.connectTLS({ port, hostname, transport, - certFile + certFile, }); return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!); } @@ -46,14 +46,14 @@ export function listenTLS({ certFile, keyFile, hostname = "0.0.0.0", - transport = "tcp" + transport = "tcp", }: ListenTLSOptions): Listener { const res = tlsOps.listenTLS({ port, certFile, keyFile, hostname, - transport + transport, }); return new TLSListenerImpl(res.rid, res.localAddr); } diff --git a/cli/js/util.ts b/cli/js/util.ts index 692ea6d00..6db8ade7b 100644 --- a/cli/js/util.ts +++ b/cli/js/util.ts @@ -67,6 +67,6 @@ export function immutableDefine( Object.defineProperty(o, p, { value, configurable: false, - writable: false + writable: false, }); } diff --git a/cli/js/version.ts b/cli/js/version.ts index 8f7851589..534195ce5 100644 --- a/cli/js/version.ts +++ b/cli/js/version.ts @@ -8,7 +8,7 @@ interface Version { export const version: Version = { deno: "", v8: "", - typescript: "" + typescript: "", }; export function setVersions( diff --git a/cli/js/web/blob.ts b/cli/js/web/blob.ts index 31674a62d..5309ddaf4 100644 --- a/cli/js/web/blob.ts +++ b/cli/js/web/blob.ts @@ -124,12 +124,8 @@ function processBlobParts( return bytes; } -// A WeakMap holding blob to byte array mapping. -// Ensures it does not impact garbage collection. -export const blobBytesWeakMap = new WeakMap<domTypes.Blob, Uint8Array>(); - export class DenoBlob implements domTypes.Blob { - private readonly [bytesSymbol]: Uint8Array; + [bytesSymbol]: Uint8Array; readonly size: number = 0; readonly type: string = ""; @@ -165,14 +161,11 @@ export class DenoBlob implements domTypes.Blob { this[bytesSymbol] = bytes; this.size = bytes.byteLength; this.type = normalizedType; - - // Register bytes for internal private use. - blobBytesWeakMap.set(this, bytes); } slice(start?: number, end?: number, contentType?: string): DenoBlob { return new DenoBlob([this[bytesSymbol].slice(start, end)], { - type: contentType || this.type + type: contentType || this.type, }); } } diff --git a/cli/js/web/body.ts b/cli/js/web/body.ts index 03c35848a..a16f872b9 100644 --- a/cli/js/web/body.ts +++ b/cli/js/web/body.ts @@ -124,7 +124,7 @@ export const BodyUsedError = "Failed to execute 'clone' on 'Body': body is already used"; export class Body implements domTypes.Body { - protected _stream: domTypes.ReadableStream | null; + protected _stream: domTypes.ReadableStream<string | ArrayBuffer> | null; constructor(protected _bodySource: BodySource, readonly contentType: string) { validateBodyType(this, _bodySource); @@ -148,8 +148,8 @@ export class Body implements domTypes.Body { start(controller: ReadableStreamController): void { controller.enqueue(bodySource); controller.close(); - } - }); + }, + }) as domTypes.ReadableStream<ArrayBuffer | string>; } return this._stream; } @@ -247,7 +247,7 @@ export class Body implements domTypes.Body { if (dispositionParams.has("filename")) { const filename = dispositionParams.get("filename")!; const blob = new DenoBlob([enc.encode(octets)], { - type: partContentType + type: partContentType, }); // TODO: based on spec // https://xhr.spec.whatwg.org/#dom-formdata-append diff --git a/cli/js/web/console.ts b/cli/js/web/console.ts index f95e50b40..554c5a1b3 100644 --- a/cli/js/web/console.ts +++ b/cli/js/web/console.ts @@ -174,7 +174,7 @@ function createArrayString( displayName: "", delims: ["[", "]"], entryHandler: (el, ctx, level, maxLevel): string => - stringifyWithQuotes(el, ctx, level + 1, maxLevel) + stringifyWithQuotes(el, ctx, level + 1, maxLevel), }; return createIterableString(value, ctx, level, maxLevel, printConfig); } @@ -191,7 +191,7 @@ function createTypedArrayString( displayName: typedArrayName, delims: ["[", "]"], entryHandler: (el, ctx, level, maxLevel): string => - stringifyWithQuotes(el, ctx, level + 1, maxLevel) + stringifyWithQuotes(el, ctx, level + 1, maxLevel), }; return createIterableString(value, ctx, level, maxLevel, printConfig); } @@ -207,7 +207,7 @@ function createSetString( displayName: "Set", delims: ["{", "}"], entryHandler: (el, ctx, level, maxLevel): string => - stringifyWithQuotes(el, ctx, level + 1, maxLevel) + stringifyWithQuotes(el, ctx, level + 1, maxLevel), }; return createIterableString(value, ctx, level, maxLevel, printConfig); } @@ -230,7 +230,7 @@ function createMapString( level + 1, maxLevel )} => ${stringifyWithQuotes(val, ctx, level + 1, maxLevel)}`; - } + }, }; return createIterableString(value, ctx, level, maxLevel, printConfig); } @@ -494,10 +494,12 @@ const timerMap = new Map<string, number>(); const isConsoleInstance = Symbol("isConsoleInstance"); export class Console { + #printFunc: PrintFunc; indentLevel: number; [isConsoleInstance] = false; - constructor(private printFunc: PrintFunc) { + constructor(printFunc: PrintFunc) { + this.#printFunc = printFunc; this.indentLevel = 0; this[isConsoleInstance] = true; @@ -511,9 +513,9 @@ export class Console { } log = (...args: unknown[]): void => { - this.printFunc( + this.#printFunc( stringifyArgs(args, { - indentLevel: this.indentLevel + indentLevel: this.indentLevel, }) + "\n", false ); @@ -523,15 +525,15 @@ export class Console { info = this.log; dir = (obj: unknown, options: InspectOptions = {}): void => { - this.printFunc(stringifyArgs([obj], options) + "\n", false); + this.#printFunc(stringifyArgs([obj], options) + "\n", false); }; dirxml = this.dir; warn = (...args: unknown[]): void => { - this.printFunc( + this.#printFunc( stringifyArgs(args, { - indentLevel: this.indentLevel + indentLevel: this.indentLevel, }) + "\n", true ); @@ -604,7 +606,7 @@ export class Console { this.log(cliTable(header, body)); const createColumn = (value: unknown, shift?: number): string[] => [ ...(shift ? [...new Array(shift)].map((): string => "") : []), - stringifyValue(value) + stringifyValue(value), ]; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -660,8 +662,8 @@ export class Console { indexKey, ...(properties || [ ...headerKeys, - !isMap && values.length > 0 && valuesKey - ]) + !isMap && values.length > 0 && valuesKey, + ]), ].filter(Boolean) as string[]; const body = [indexKeys, ...bodyValues, values]; @@ -733,7 +735,7 @@ export class Console { const message = stringifyArgs(args, { indentLevel: 0 }); const err = { name: "Trace", - message + message, }; // @ts-ignore Error.captureStackTrace(err, this.trace); diff --git a/cli/js/web/console_table.ts b/cli/js/web/console_table.ts index 7e698f712..2cb0005d7 100644 --- a/cli/js/web/console_table.ts +++ b/cli/js/web/console_table.ts @@ -19,7 +19,7 @@ const tableChars = { rightMiddle: "┤", left: "│ ", right: " │", - middle: " │ " + middle: " │ ", }; const colorRegExp = /\u001b\[\d\d?m/g; diff --git a/cli/js/web/custom_event.ts b/cli/js/web/custom_event.ts index 24a263baf..418b7ea34 100644 --- a/cli/js/web/custom_event.ts +++ b/cli/js/web/custom_event.ts @@ -1,32 +1,31 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import * as domTypes from "./dom_types.ts"; import * as event from "./event.ts"; -import { getPrivateValue, requiredArguments } from "./util.ts"; - -// WeakMaps are recommended for private attributes (see MDN link below) -// https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Add-on_SDK/Guides/Contributor_s_Guide/Private_Properties#Using_WeakMaps -export const customEventAttributes = new WeakMap(); +import { requiredArguments } from "./util.ts"; export class CustomEvent extends event.Event implements domTypes.CustomEvent { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + #detail: any; + constructor( type: string, customEventInitDict: domTypes.CustomEventInit = {} ) { - requiredArguments("CustomEvent", arguments.length, 1); super(type, customEventInitDict); + requiredArguments("CustomEvent", arguments.length, 1); const { detail = null } = customEventInitDict; - customEventAttributes.set(this, { detail }); + this.#detail = detail; } // eslint-disable-next-line @typescript-eslint/no-explicit-any get detail(): any { - return getPrivateValue(this, customEventAttributes, "detail"); + return this.#detail; } initCustomEvent( - type: string, - bubbles?: boolean, - cancelable?: boolean, + _type: string, + _bubbles?: boolean, + _cancelable?: boolean, // eslint-disable-next-line @typescript-eslint/no-explicit-any detail?: any ): void { @@ -34,7 +33,7 @@ export class CustomEvent extends event.Event implements domTypes.CustomEvent { return; } - customEventAttributes.set(this, { detail }); + this.#detail = detail; } get [Symbol.toStringTag](): string { diff --git a/cli/js/web/dom_iterable.ts b/cli/js/web/dom_iterable.ts index e9be9009f..191958f11 100644 --- a/cli/js/web/dom_iterable.ts +++ b/cli/js/web/dom_iterable.ts @@ -72,7 +72,7 @@ export function DomIterableMixin<K, V, TBase extends Constructor>( // we want the Base class name to be the name of the class. Object.defineProperty(DomIterable, "name", { value: Base.name, - configurable: true + configurable: true, }); return DomIterable; diff --git a/cli/js/web/dom_types.ts b/cli/js/web/dom_types.ts index bcc6be468..33cda1582 100644 --- a/cli/js/web/dom_types.ts +++ b/cli/js/web/dom_types.ts @@ -68,7 +68,7 @@ interface AbortSignalEventMap { export enum NodeType { ELEMENT_NODE = 1, TEXT_NODE = 3, - DOCUMENT_FRAGMENT_NODE = 11 + DOCUMENT_FRAGMENT_NODE = 11, } export const eventTargetHost: unique symbol = Symbol(); @@ -153,7 +153,7 @@ export enum EventPhase { NONE = 0, CAPTURING_PHASE = 1, AT_TARGET = 2, - BUBBLING_PHASE = 3 + BUBBLING_PHASE = 3, } export interface EventPath { @@ -280,7 +280,7 @@ export interface Blob { } export interface Body { - readonly body: ReadableStream | null; + readonly body: ReadableStream<Uint8Array> | null; readonly bodyUsed: boolean; arrayBuffer(): Promise<ArrayBuffer>; blob(): Promise<Blob>; @@ -289,11 +289,78 @@ export interface Body { text(): Promise<string>; } -export interface ReadableStream { +export interface ReadableStreamReadDoneResult<T> { + done: true; + value?: T; +} + +export interface ReadableStreamReadValueResult<T> { + done: false; + value: T; +} + +export type ReadableStreamReadResult<T> = + | ReadableStreamReadValueResult<T> + | ReadableStreamReadDoneResult<T>; + +export interface ReadableStreamDefaultReader<R = any> { + readonly closed: Promise<void>; + cancel(reason?: any): Promise<void>; + read(): Promise<ReadableStreamReadResult<R>>; + releaseLock(): void; +} + +export interface PipeOptions { + preventAbort?: boolean; + preventCancel?: boolean; + preventClose?: boolean; + signal?: AbortSignal; +} + +export interface ReadableStream<R = any> { readonly locked: boolean; cancel(reason?: any): Promise<void>; - getReader(): ReadableStreamReader; - tee(): ReadableStream[]; + getReader(options: { mode: "byob" }): ReadableStreamBYOBReader; + getReader(): ReadableStreamDefaultReader<R>; + /* disabled for now + pipeThrough<T>( + { + writable, + readable + }: { + writable: WritableStream<R>; + readable: ReadableStream<T>; + }, + options?: PipeOptions + ): ReadableStream<T>; + pipeTo(dest: WritableStream<R>, options?: PipeOptions): Promise<void>; + */ + tee(): [ReadableStream<R>, ReadableStream<R>]; +} + +export interface ReadableStreamBYOBReader { + readonly closed: Promise<void>; + cancel(reason?: any): Promise<void>; + read<T extends ArrayBufferView>( + view: T + ): Promise<ReadableStreamReadResult<T>>; + releaseLock(): void; +} + +export interface WritableStream<W = any> { + readonly locked: boolean; + abort(reason?: any): Promise<void>; + getWriter(): WritableStreamDefaultWriter<W>; +} + +export interface WritableStreamDefaultWriter<W = any> { + readonly closed: Promise<void>; + readonly desiredSize: number | null; + readonly ready: Promise<void>; + abort(reason?: any): Promise<void>; + close(): Promise<void>; + releaseLock(): void; + write(chunk: W): Promise<void>; } export interface UnderlyingSource<R = any> { @@ -311,9 +378,9 @@ export interface UnderlyingByteSource { type: "bytes"; } -export interface ReadableStreamReader { - cancel(reason?: any): Promise<void>; - read(): Promise<any>; +export interface ReadableStreamReader<R = any> { + cancel(reason: any): Promise<void>; + read(): Promise<ReadableStreamReadResult<R>>; releaseLock(): void; } @@ -530,12 +597,20 @@ export interface Response extends Body { clone(): Response; } +export interface DOMStringList { + readonly length: number; + contains(string: string): boolean; + item(index: number): string | null; + [index: number]: string; +} + export interface Location { - readonly ancestorOrigins: string[]; + readonly ancestorOrigins: DOMStringList; hash: string; host: string; hostname: string; href: string; + toString(): string; readonly origin: string; pathname: string; port: string; @@ -543,6 +618,72 @@ export interface Location { search: string; assign(url: string): void; reload(): void; - reload(forcedReload: boolean): void; replace(url: string): void; } + +export interface URL { + hash: string; + host: string; + hostname: string; + href: string; + toString(): string; + readonly origin: string; + password: string; + pathname: string; + port: string; + protocol: string; + search: string; + readonly searchParams: URLSearchParams; + username: string; + toJSON(): string; +} + +export interface URLSearchParams { + /** + * Appends a specified key/value pair as a new search parameter. + */ + append(name: string, value: string): void; + /** + * Deletes the given search parameter, and its associated value, from the list of all search parameters. + */ + delete(name: string): void; + /** + * Returns the first value associated to the given search parameter. + */ + get(name: string): string | null; + /** + * Returns all the values association with a given search parameter. + */ + getAll(name: string): string[]; + /** + * Returns a Boolean indicating if such a search parameter exists. + */ + has(name: string): boolean; + /** + * Sets the value associated to a given search parameter to the given value. If there were several values, delete the others. + */ + set(name: string, value: string): void; + sort(): void; + /** + * Returns a string containing a query string suitable for use in a URL. Does not include the question mark. + */ + toString(): string; + forEach( + callbackfn: (value: string, key: string, parent: URLSearchParams) => void, + thisArg?: any + ): void; + + [Symbol.iterator](): IterableIterator<[string, string]>; + /** + * Returns an array of key, value pairs for every entry in the search params. + */ + entries(): IterableIterator<[string, string]>; + /** + * Returns a list of keys in the search params. + */ + keys(): IterableIterator<string>; + /** + * Returns a list of values in the search params. + */ + values(): IterableIterator<string>; +} diff --git a/cli/js/web/dom_util.ts b/cli/js/web/dom_util.ts index 5780d9c52..40a8c618f 100644 --- a/cli/js/web/dom_util.ts +++ b/cli/js/web/dom_util.ts @@ -2,6 +2,23 @@ // Utility functions for DOM nodes import * as domTypes from "./dom_types.ts"; +export function getDOMStringList(arr: string[]): domTypes.DOMStringList { + Object.defineProperties(arr, { + contains: { + value(searchElement: string): boolean { + return arr.includes(searchElement); + }, + enumerable: true, + }, + item: { + value(idx: number): string | null { + return idx in arr ? arr[idx] : null; + }, + }, + }); + return (arr as unknown) as domTypes.DOMStringList; +} + export function isNode(nodeImpl: domTypes.EventTarget | null): boolean { return Boolean(nodeImpl && "nodeType" in nodeImpl); } diff --git a/cli/js/web/event.ts b/cli/js/web/event.ts index ef5c4d175..b063efa60 100644 --- a/cli/js/web/event.ts +++ b/cli/js/web/event.ts @@ -39,11 +39,11 @@ export class Event implements domTypes.Event { isTrusted: false, relatedTarget: null, target: null, - timeStamp: Date.now() + timeStamp: Date.now(), }); Reflect.defineProperty(this, "isTrusted", { enumerable: true, - get: isTrusted + get: isTrusted, }); } @@ -90,7 +90,7 @@ export class Event implements domTypes.Event { isTrusted: this.isTrusted, relatedTarget: this.relatedTarget, target: this.target, - timeStamp: this.timeStamp + timeStamp: this.timeStamp, }); } @@ -121,7 +121,7 @@ export class Event implements domTypes.Event { isTrusted: this.isTrusted, relatedTarget: this.relatedTarget, target: this.target, - timeStamp: this.timeStamp + timeStamp: this.timeStamp, }); } @@ -156,7 +156,7 @@ export class Event implements domTypes.Event { isTrusted: this.isTrusted, relatedTarget: value, target: this.target, - timeStamp: this.timeStamp + timeStamp: this.timeStamp, }); } @@ -175,7 +175,7 @@ export class Event implements domTypes.Event { isTrusted: this.isTrusted, relatedTarget: this.relatedTarget, target: value, - timeStamp: this.timeStamp + timeStamp: this.timeStamp, }); } @@ -200,8 +200,8 @@ export class Event implements domTypes.Event { rootOfClosedTree: false, slotInClosedTree: false, target: null, - touchTargetList: [] - } + touchTargetList: [], + }, ]; let currentTargetIndex = 0; @@ -242,7 +242,7 @@ export class Event implements domTypes.Event { rootOfClosedTree: false, slotInClosedTree: false, target: null, - touchTargetList: [] + touchTargetList: [], }); } @@ -277,7 +277,7 @@ export class Event implements domTypes.Event { rootOfClosedTree: false, slotInClosedTree: false, target: null, - touchTargetList: [] + touchTargetList: [], }); } @@ -314,7 +314,7 @@ Reflect.defineProperty(Event.prototype, "cancelable", { enumerable: true }); Reflect.defineProperty(Event.prototype, "composed", { enumerable: true }); Reflect.defineProperty(Event.prototype, "currentTarget", { enumerable: true }); Reflect.defineProperty(Event.prototype, "defaultPrevented", { - enumerable: true + enumerable: true, }); Reflect.defineProperty(Event.prototype, "dispatched", { enumerable: true }); Reflect.defineProperty(Event.prototype, "eventPhase", { enumerable: true }); diff --git a/cli/js/web/event_target.ts b/cli/js/web/event_target.ts index 7fe26441d..605504a3a 100644 --- a/cli/js/web/event_target.ts +++ b/cli/js/web/event_target.ts @@ -7,7 +7,7 @@ import { isShadowRoot, isShadowInclusiveAncestor, isSlotable, - retarget + retarget, } from "./dom_util.ts"; // https://dom.spec.whatwg.org/#get-the-parent @@ -70,7 +70,7 @@ export class EventTarget implements domTypes.EventTarget { listeners[type].push({ callback, - options: normalizedOptions + options: normalizedOptions, }); } @@ -438,7 +438,7 @@ const eventTargetHelpers = { const returnValue: domTypes.AddEventListenerOptions = { capture: Boolean(options), once: false, - passive: false + passive: false, }; return returnValue; @@ -452,7 +452,7 @@ const eventTargetHelpers = { ): domTypes.EventListenerOptions { if (typeof options === "boolean" || typeof options === "undefined") { const returnValue: domTypes.EventListenerOptions = { - capture: Boolean(options) + capture: Boolean(options), }; return returnValue; @@ -481,17 +481,17 @@ const eventTargetHelpers = { relatedTarget, touchTargetList: touchTargets, rootOfClosedTree, - slotInClosedTree + slotInClosedTree, }); - } + }, }; Reflect.defineProperty(EventTarget.prototype, "addEventListener", { - enumerable: true + enumerable: true, }); Reflect.defineProperty(EventTarget.prototype, "removeEventListener", { - enumerable: true + enumerable: true, }); Reflect.defineProperty(EventTarget.prototype, "dispatchEvent", { - enumerable: true + enumerable: true, }); diff --git a/cli/js/web/fetch.ts b/cli/js/web/fetch.ts index 62e5d7928..6438838c7 100644 --- a/cli/js/web/fetch.ts +++ b/cli/js/web/fetch.ts @@ -32,53 +32,58 @@ function hasHeaderValueOf(s: string, value: string): boolean { return new RegExp(`^${value}[\t\s]*;?`).test(s); } -class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser { - private _bodyUsed = false; - private _bodyPromise: null | Promise<ArrayBuffer> = null; - private _data: ArrayBuffer | null = null; +class Body + implements domTypes.Body, domTypes.ReadableStream<Uint8Array>, io.ReadCloser { + #bodyUsed = false; + #bodyPromise: Promise<ArrayBuffer> | null = null; + #data: ArrayBuffer | null = null; + #rid: number; readonly locked: boolean = false; // TODO - readonly body: null | Body = this; + readonly body: domTypes.ReadableStream<Uint8Array>; - constructor(private rid: number, readonly contentType: string) {} + constructor(rid: number, readonly contentType: string) { + this.#rid = rid; + this.body = this; + } - private async _bodyBuffer(): Promise<ArrayBuffer> { - assert(this._bodyPromise == null); + #bodyBuffer = async (): Promise<ArrayBuffer> => { + assert(this.#bodyPromise == null); const buf = new Buffer(); try { const nread = await buf.readFrom(this); const ui8 = buf.bytes(); assert(ui8.byteLength === nread); - this._data = ui8.buffer.slice( + this.#data = ui8.buffer.slice( ui8.byteOffset, ui8.byteOffset + nread ) as ArrayBuffer; - assert(this._data.byteLength === nread); + assert(this.#data.byteLength === nread); } finally { this.close(); } - return this._data; - } + return this.#data; + }; // eslint-disable-next-line require-await async arrayBuffer(): Promise<ArrayBuffer> { // If we've already bufferred the response, just return it. - if (this._data != null) { - return this._data; + if (this.#data != null) { + return this.#data; } // If there is no _bodyPromise yet, start it. - if (this._bodyPromise == null) { - this._bodyPromise = this._bodyBuffer(); + if (this.#bodyPromise == null) { + this.#bodyPromise = this.#bodyBuffer(); } - return this._bodyPromise; + return this.#bodyPromise; } async blob(): Promise<domTypes.Blob> { const arrayBuffer = await this.arrayBuffer(); return new DenoBlob([arrayBuffer], { - type: this.contentType + type: this.contentType, }); } @@ -164,7 +169,7 @@ class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser { if (dispositionParams.has("filename")) { const filename = dispositionParams.get("filename")!; const blob = new DenoBlob([enc.encode(octets)], { - type: partContentType + type: partContentType, }); // TODO: based on spec // https://xhr.spec.whatwg.org/#dom-formdata-append @@ -220,12 +225,12 @@ class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser { } read(p: Uint8Array): Promise<number | io.EOF> { - this._bodyUsed = true; - return read(this.rid, p); + this.#bodyUsed = true; + return read(this.#rid, p); } close(): Promise<void> { - close(this.rid); + close(this.#rid); return Promise.resolve(); } @@ -233,7 +238,11 @@ class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser { return notImplemented(); } - getReader(): domTypes.ReadableStreamReader { + getReader(options: { mode: "byob" }): domTypes.ReadableStreamBYOBReader; + getReader(): domTypes.ReadableStreamDefaultReader<Uint8Array>; + getReader(): + | domTypes.ReadableStreamBYOBReader + | domTypes.ReadableStreamDefaultReader<Uint8Array> { return notImplemented(); } @@ -246,7 +255,24 @@ class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser { } get bodyUsed(): boolean { - return this._bodyUsed; + return this.#bodyUsed; + } + + pipeThrough<T>( + _: { + writable: domTypes.WritableStream<Uint8Array>; + readable: domTypes.ReadableStream<T>; + }, + _options?: domTypes.PipeOptions + ): domTypes.ReadableStream<T> { + return notImplemented(); + } + + pipeTo( + _dest: domTypes.WritableStream<Uint8Array>, + _options?: domTypes.PipeOptions + ): Promise<void> { + return notImplemented(); } } @@ -255,7 +281,7 @@ export class Response implements domTypes.Response { readonly redirected: boolean; headers: domTypes.Headers; readonly trailer: Promise<domTypes.Headers>; - readonly body: null | Body; + readonly body: Body | null; constructor( readonly url: string, @@ -308,7 +334,7 @@ export class Response implements domTypes.Response { "Content-Type", "Expires", "Last-Modified", - "Pragma" + "Pragma", ].map((c: string) => c.toLowerCase()); for (const h of this.headers) { /* Technically this is still not standards compliant because we are @@ -337,35 +363,36 @@ export class Response implements domTypes.Response { this.redirected = redirected_; } - private bodyViewable(): boolean { + #bodyViewable = (): boolean => { if ( this.type == "error" || this.type == "opaque" || this.type == "opaqueredirect" || this.body == undefined - ) + ) { return true; + } return false; - } + }; arrayBuffer(): Promise<ArrayBuffer> { /* You have to do the null check here and not in the function because * otherwise TS complains about this.body potentially being null */ - if (this.bodyViewable() || this.body == null) { + if (this.#bodyViewable() || this.body == null) { return Promise.reject(new Error("Response body is null")); } return this.body.arrayBuffer(); } blob(): Promise<domTypes.Blob> { - if (this.bodyViewable() || this.body == null) { + if (this.#bodyViewable() || this.body == null) { return Promise.reject(new Error("Response body is null")); } return this.body.blob(); } formData(): Promise<domTypes.FormData> { - if (this.bodyViewable() || this.body == null) { + if (this.#bodyViewable() || this.body == null) { return Promise.reject(new Error("Response body is null")); } return this.body.formData(); @@ -373,14 +400,14 @@ export class Response implements domTypes.Response { // eslint-disable-next-line @typescript-eslint/no-explicit-any json(): Promise<any> { - if (this.bodyViewable() || this.body == null) { + if (this.#bodyViewable() || this.body == null) { return Promise.reject(new Error("Response body is null")); } return this.body.json(); } text(): Promise<string> { - if (this.bodyViewable() || this.body == null) { + if (this.#bodyViewable() || this.body == null) { return Promise.reject(new Error("Response body is null")); } return this.body.text(); @@ -453,7 +480,7 @@ function sendFetchReq( const args = { method, url, - headers: headerArray + headers: headerArray, }; return opFetch(args, body); @@ -527,8 +554,9 @@ export async function fetch( } part += "\r\n"; if (fieldValue instanceof DomFileImpl) { - part += `Content-Type: ${fieldValue.type || - "application/octet-stream"}\r\n`; + part += `Content-Type: ${ + fieldValue.type || "application/octet-stream" + }\r\n`; } part += "\r\n"; if (fieldValue instanceof DomFileImpl) { diff --git a/cli/js/web/form_data.ts b/cli/js/web/form_data.ts index f60a146d9..db5d24ad4 100644 --- a/cli/js/web/form_data.ts +++ b/cli/js/web/form_data.ts @@ -8,7 +8,7 @@ import { requiredArguments } from "./util.ts"; const dataSymbol = Symbol("data"); class FormDataBase { - private [dataSymbol]: Array<[string, domTypes.FormDataEntryValue]> = []; + [dataSymbol]: Array<[string, domTypes.FormDataEntryValue]> = []; append(name: string, value: string): void; append(name: string, value: blob.DenoBlob, filename?: string): void; @@ -17,7 +17,7 @@ class FormDataBase { name = String(name); if (value instanceof blob.DenoBlob) { const dfile = new domFile.DomFileImpl([value], filename || name, { - type: value.type + type: value.type, }); this[dataSymbol].push([name, dfile]); } else { @@ -84,7 +84,7 @@ class FormDataBase { if (!found) { if (value instanceof blob.DenoBlob) { const dfile = new domFile.DomFileImpl([value], filename || name, { - type: value.type + type: value.type, }); this[dataSymbol][i][1] = dfile; } else { @@ -103,7 +103,7 @@ class FormDataBase { if (!found) { if (value instanceof blob.DenoBlob) { const dfile = new domFile.DomFileImpl([value], filename || name, { - type: value.type + type: value.type, }); this[dataSymbol].push([name, dfile]); } else { diff --git a/cli/js/web/headers.ts b/cli/js/web/headers.ts index 9ff594224..e1d81393d 100644 --- a/cli/js/web/headers.ts +++ b/cli/js/web/headers.ts @@ -17,32 +17,32 @@ function isHeaders(value: any): value is domTypes.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]; - } +// TODO: headerGuard? Investigate if it is needed +// node-fetch did not implement this but it is in the spec +function 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`); - } +// 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. +function 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`); - } +function validateValue(value: string): void { + if (invalidHeaderCharRegex.test(value)) { + throw new TypeError(`${value} is not a legal HTTP header value`); } +} + +// ref: https://fetch.spec.whatwg.org/#dom-headers +class HeadersBase { + [headerMap]: Map<string, string>; constructor(init?: domTypes.HeadersInit) { if (init === null) { @@ -64,9 +64,9 @@ class HeadersBase { 2 ); - const [name, value] = this._normalizeParams(tuple[0], tuple[1]); - this._validateName(name); - this._validateValue(value); + const [name, value] = normalizeParams(tuple[0], tuple[1]); + validateName(name); + validateValue(value); const existingValue = this[headerMap].get(name); this[headerMap].set( name, @@ -77,9 +77,9 @@ class HeadersBase { 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); + const [name, value] = normalizeParams(rawName, rawValue); + validateName(name); + validateValue(value); this[headerMap].set(name, value); } } @@ -101,9 +101,9 @@ class HeadersBase { // 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 [newname, newvalue] = normalizeParams(name, value); + validateName(newname); + validateValue(newvalue); const v = this[headerMap].get(newname); const str = v ? `${v}, ${newvalue}` : newvalue; this[headerMap].set(newname, str); @@ -111,31 +111,31 @@ class HeadersBase { delete(name: string): void { requiredArguments("Headers.delete", arguments.length, 1); - const [newname] = this._normalizeParams(name); - this._validateName(newname); + const [newname] = normalizeParams(name); + 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 [newname] = normalizeParams(name); + 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); + const [newname] = normalizeParams(name); + 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); + const [newname, newvalue] = normalizeParams(name, value); + validateName(newname); + validateValue(newvalue); this[headerMap].set(newname, newvalue); } diff --git a/cli/js/web/location.ts b/cli/js/web/location.ts index d48cce3c7..862a4c1e4 100644 --- a/cli/js/web/location.ts +++ b/cli/js/web/location.ts @@ -1,12 +1,15 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { URL } from "./url.ts"; import { notImplemented } from "../util.ts"; -import { Location } from "./dom_types.ts"; +import { DOMStringList, Location } from "./dom_types.ts"; +import { getDOMStringList } from "./dom_util.ts"; export class LocationImpl implements Location { + #url: URL; + constructor(url: string) { const u = new URL(url); - this.url = u; + this.#url = u; this.hash = u.hash; this.host = u.host; this.href = u.href; @@ -18,13 +21,11 @@ export class LocationImpl implements Location { this.search = u.search; } - private url: URL; - toString(): string { - return this.url.toString(); + return this.#url.toString(); } - readonly ancestorOrigins: string[] = []; + readonly ancestorOrigins: DOMStringList = getDOMStringList([]); hash: string; host: string; hostname: string; @@ -45,6 +46,8 @@ export class LocationImpl implements Location { } } +/** Sets the `window.location` at runtime. + * @internal */ export function setLocation(url: string): void { globalThis.location = new LocationImpl(url); Object.freeze(globalThis.location); diff --git a/cli/js/web/request.ts b/cli/js/web/request.ts index 8afc35e7a..96edaf59e 100644 --- a/cli/js/web/request.ts +++ b/cli/js/web/request.ts @@ -136,7 +136,7 @@ export class Request extends body.Body implements domTypes.Request { body: body2, method: this.method, headers: new Headers(headersList), - credentials: this.credentials + credentials: this.credentials, }); return cloned; } diff --git a/cli/js/web/streams/readable-byte-stream-controller.ts b/cli/js/web/streams/readable-byte-stream-controller.ts index 8067b5d35..1b473b77a 100644 --- a/cli/js/web/streams/readable-byte-stream-controller.ts +++ b/cli/js/web/streams/readable-byte-stream-controller.ts @@ -148,7 +148,7 @@ export class ReadableByteStreamController bytesFilled: 0, elementSize: 1, ctor: Uint8Array, - readerType: "default" + readerType: "default", }; this[rs.pendingPullIntos_].push(pullIntoDescriptor); } diff --git a/cli/js/web/streams/readable-internals.ts b/cli/js/web/streams/readable-internals.ts index b96262ef7..f46c79850 100644 --- a/cli/js/web/streams/readable-internals.ts +++ b/cli/js/web/streams/readable-internals.ts @@ -10,7 +10,7 @@ import { QueuingStrategy, QueuingStrategySizeCallback, UnderlyingSource, - UnderlyingByteSource + UnderlyingByteSource, } from "../dom_types.ts"; // ReadableStreamDefaultController @@ -345,7 +345,7 @@ export function readableStreamCancel<OutputType>( const sourceCancelPromise = stream[readableStreamController_][cancelSteps_]( reason ); - return sourceCancelPromise.then(_ => undefined); + return sourceCancelPromise.then((_) => undefined); } export function readableStreamClose<OutputType>( @@ -558,13 +558,13 @@ export function setUpReadableStreamDefaultController<OutputType>( const startResult = startAlgorithm(); Promise.resolve(startResult).then( - _ => { + (_) => { controller[started_] = true; // Assert: controller.[[pulling]] is false. // Assert: controller.[[pullAgain]] is false. readableStreamDefaultControllerCallPullIfNeeded(controller); }, - error => { + (error) => { readableStreamDefaultControllerError(controller, error); } ); @@ -678,14 +678,14 @@ export function readableStreamDefaultControllerCallPullIfNeeded<OutputType>( controller[pulling_] = true; controller[pullAlgorithm_](controller).then( - _ => { + (_) => { controller[pulling_] = false; if (controller[pullAgain_]) { controller[pullAgain_] = false; readableStreamDefaultControllerCallPullIfNeeded(controller); } }, - error => { + (error) => { readableStreamDefaultControllerError(controller, error); } ); @@ -768,13 +768,13 @@ export function setUpReadableByteStreamController( // Let startResult be the result of performing startAlgorithm. const startResult = startAlgorithm(); Promise.resolve(startResult).then( - _ => { + (_) => { controller[started_] = true; // Assert: controller.[[pulling]] is false. // Assert: controller.[[pullAgain]] is false. readableByteStreamControllerCallPullIfNeeded(controller); }, - error => { + (error) => { readableByteStreamControllerError(controller, error); } ); @@ -811,14 +811,14 @@ export function readableByteStreamControllerCallPullIfNeeded( // Assert: controller.[[pullAgain]] is false. controller[pulling_] = true; controller[pullAlgorithm_](controller).then( - _ => { + (_) => { controller[pulling_] = false; if (controller[pullAgain_]) { controller[pullAgain_] = false; readableByteStreamControllerCallPullIfNeeded(controller); } }, - error => { + (error) => { readableByteStreamControllerError(controller, error); } ); @@ -1122,7 +1122,7 @@ export function readableByteStreamControllerPullInto( bytesFilled: 0, elementSize, ctor, - readerType: "byob" + readerType: "byob", }; if (controller[pendingPullIntos_].length > 0) { diff --git a/cli/js/web/streams/readable-stream.ts b/cli/js/web/streams/readable-stream.ts index e062c278e..50753260d 100644 --- a/cli/js/web/streams/readable-stream.ts +++ b/cli/js/web/streams/readable-stream.ts @@ -11,18 +11,18 @@ import { QueuingStrategy, QueuingStrategySizeCallback, UnderlyingSource, - UnderlyingByteSource + UnderlyingByteSource, } from "../dom_types.ts"; import { ReadableStreamDefaultController, - setUpReadableStreamDefaultControllerFromUnderlyingSource + setUpReadableStreamDefaultControllerFromUnderlyingSource, } from "./readable-stream-default-controller.ts"; import { ReadableStreamDefaultReader } from "./readable-stream-default-reader.ts"; import { ReadableByteStreamController, - setUpReadableByteStreamControllerFromUnderlyingSource + setUpReadableByteStreamControllerFromUnderlyingSource, } from "./readable-byte-stream-controller.ts"; import { SDReadableStreamBYOBReader } from "./readable-stream-byob-reader.ts"; @@ -123,7 +123,7 @@ export class SDReadableStream<OutputType> return rs.readableStreamCancel(this, reason); } - tee(): Array<SDReadableStream<OutputType>> { + tee(): [SDReadableStream<OutputType>, SDReadableStream<OutputType>] { return readableStreamTee(this, false); } @@ -280,7 +280,9 @@ export function readableStreamTee<OutputType>( let branch2: SDReadableStream<OutputType>; let cancelResolve: (reason: shared.ErrorResult) => void; - const cancelPromise = new Promise<void>(resolve => (cancelResolve = resolve)); + const cancelPromise = new Promise<void>( + (resolve) => (cancelResolve = resolve) + ); const pullAlgorithm = (): Promise<void> => { return rs @@ -362,7 +364,7 @@ export function readableStreamTee<OutputType>( cancel2Algorithm ); - reader[rs.closedPromise_].promise.catch(error => { + reader[rs.closedPromise_].promise.catch((error) => { if (!closedOrErrored) { rs.readableStreamDefaultControllerError( branch1![ diff --git a/cli/js/web/streams/shared-internals.ts b/cli/js/web/streams/shared-internals.ts index 3d802b083..7b0de2274 100644 --- a/cli/js/web/streams/shared-internals.ts +++ b/cli/js/web/streams/shared-internals.ts @@ -223,7 +223,7 @@ export function createAlgorithmFromUnderlyingMethod< if (typeof method !== "function") { throw new TypeError(`Field "${methodName}" is not a function.`); } - return function(...fnArgs: any[]): any { + return function (...fnArgs: any[]): any { return promiseCall(method, obj, fnArgs.concat(extraArgs)); }; } @@ -252,7 +252,7 @@ export function makeSizeAlgorithmFromSizeFunction<T>( if (typeof sizeFn !== "function" && typeof sizeFn !== "undefined") { throw new TypeError("size function must be undefined or a function"); } - return function(chunk: T): number { + return function (chunk: T): number { if (typeof sizeFn === "function") { return sizeFn(chunk); } @@ -265,7 +265,7 @@ export function makeSizeAlgorithmFromSizeFunction<T>( export const enum ControlledPromiseState { Pending, Resolved, - Rejected + Rejected, } export interface ControlledPromise<V> { @@ -277,14 +277,14 @@ export interface ControlledPromise<V> { export function createControlledPromise<V>(): ControlledPromise<V> { const conProm = { - state: ControlledPromiseState.Pending + state: ControlledPromiseState.Pending, } as ControlledPromise<V>; - conProm.promise = new Promise<V>(function(resolve, reject) { - conProm.resolve = function(v?: V): void { + conProm.promise = new Promise<V>(function (resolve, reject) { + conProm.resolve = function (v?: V): void { conProm.state = ControlledPromiseState.Resolved; resolve(v); }; - conProm.reject = function(e?: ErrorResult): void { + conProm.reject = function (e?: ErrorResult): void { conProm.state = ControlledPromiseState.Rejected; reject(e); }; diff --git a/cli/js/web/text_encoding.ts b/cli/js/web/text_encoding.ts index 5f04972aa..6fd498e59 100644 --- a/cli/js/web/text_encoding.ts +++ b/cli/js/web/text_encoding.ts @@ -149,8 +149,8 @@ interface Encoder { } class SingleByteDecoder implements Decoder { - private _index: number[]; - private _fatal: boolean; + #index: number[]; + #fatal: boolean; constructor( index: number[], @@ -159,20 +159,20 @@ class SingleByteDecoder implements Decoder { if (ignoreBOM) { throw new TypeError("Ignoring the BOM is available only with utf-8."); } - this._fatal = fatal; - this._index = index; + this.#fatal = fatal; + this.#index = index; } - handler(stream: Stream, byte: number): number { + handler(_stream: Stream, byte: number): number { if (byte === END_OF_STREAM) { return FINISHED; } if (isASCIIByte(byte)) { return byte; } - const codePoint = this._index[byte - 0x80]; + const codePoint = this.#index[byte - 0x80]; if (codePoint == null) { - return decoderError(this._fatal); + return decoderError(this.#fatal); } return codePoint; @@ -199,9 +199,9 @@ const encodingMap: { [key: string]: string[] } = { "latin1", "us-ascii", "windows-1252", - "x-cp1252" + "x-cp1252", ], - "utf-8": ["unicode-1-1-utf-8", "utf-8", "utf8"] + "utf-8": ["unicode-1-1-utf-8", "utf-8", "utf8"], }; // We convert these into a Map where every label resolves to its canonical // encoding type. @@ -221,13 +221,134 @@ const decoders = new Map<string, (options: DecoderOptions) => Decoder>(); const encodingIndexes = new Map<string, number[]>(); // prettier-ignore encodingIndexes.set("windows-1252", [ - 8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143,144, - 8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376,160,161, - 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180, - 181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199, - 200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218, - 219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237, - 238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 + 8364, + 129, + 8218, + 402, + 8222, + 8230, + 8224, + 8225, + 710, + 8240, + 352, + 8249, + 338, + 141, + 381, + 143, + 144, + 8216, + 8217, + 8220, + 8221, + 8226, + 8211, + 8212, + 732, + 8482, + 353, + 8250, + 339, + 157, + 382, + 376, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255 ]); for (const [key, index] of encodingIndexes) { decoders.set( @@ -247,37 +368,37 @@ function codePointsToString(codePoints: number[]): string { } class Stream { - private _tokens: number[]; + #tokens: number[]; constructor(tokens: number[] | Uint8Array) { - this._tokens = [].slice.call(tokens); - this._tokens.reverse(); + this.#tokens = [...tokens]; + this.#tokens.reverse(); } endOfStream(): boolean { - return !this._tokens.length; + return !this.#tokens.length; } read(): number { - return !this._tokens.length ? END_OF_STREAM : this._tokens.pop()!; + return !this.#tokens.length ? END_OF_STREAM : this.#tokens.pop()!; } prepend(token: number | number[]): void { if (Array.isArray(token)) { while (token.length) { - this._tokens.push(token.pop()!); + this.#tokens.push(token.pop()!); } } else { - this._tokens.push(token); + this.#tokens.push(token); } } push(token: number | number[]): void { if (Array.isArray(token)) { while (token.length) { - this._tokens.unshift(token.shift()!); + this.#tokens.unshift(token.shift()!); } } else { - this._tokens.unshift(token); + this.#tokens.unshift(token); } } } @@ -299,10 +420,10 @@ function isEitherArrayBuffer(x: any): x is EitherArrayBuffer { } export class TextDecoder { - private _encoding: string; + #encoding: string; get encoding(): string { - return this._encoding; + return this.#encoding; } readonly fatal: boolean = false; readonly ignoreBOM: boolean = false; @@ -314,9 +435,7 @@ export class TextDecoder { if (options.fatal) { this.fatal = true; } - label = String(label) - .trim() - .toLowerCase(); + label = String(label).trim().toLowerCase(); const encoding = encodings.get(label); if (!encoding) { throw new RangeError( @@ -326,7 +445,7 @@ export class TextDecoder { if (!decoders.has(encoding) && encoding !== "utf-8") { throw new TypeError(`Internal decoder ('${encoding}') not found.`); } - this._encoding = encoding; + this.#encoding = encoding; } decode( @@ -354,7 +473,7 @@ export class TextDecoder { // For simple utf-8 decoding "Deno.core.decode" can be used for performance if ( - this._encoding === "utf-8" && + this.#encoding === "utf-8" && this.fatal === false && this.ignoreBOM === false ) { @@ -363,13 +482,13 @@ export class TextDecoder { // For performance reasons we utilise a highly optimised decoder instead of // the general decoder. - if (this._encoding === "utf-8") { + if (this.#encoding === "utf-8") { return decodeUtf8(bytes, this.fatal, this.ignoreBOM); } - const decoder = decoders.get(this._encoding)!({ + const decoder = decoders.get(this.#encoding)!({ fatal: this.fatal, - ignoreBOM: this.ignoreBOM + ignoreBOM: this.ignoreBOM, }); const inputStream = new Stream(bytes); const output: number[] = []; @@ -455,7 +574,7 @@ export class TextEncoder { return { read, - written + written, }; } get [Symbol.toStringTag](): string { diff --git a/cli/js/web/timers.ts b/cli/js/web/timers.ts index 9a957f3fe..ff18543fa 100644 --- a/cli/js/web/timers.ts +++ b/cli/js/web/timers.ts @@ -223,7 +223,7 @@ function setTimer( delay, due: now + delay, repeat, - scheduled: false + scheduled: false, }; // Register the timer's existence in the id-to-timer map. idMap.set(timer.id, timer); diff --git a/cli/js/web/url.ts b/cli/js/web/url.ts index 6ef6b367c..2b6a0d341 100644 --- a/cli/js/web/url.ts +++ b/cli/js/web/url.ts @@ -1,8 +1,8 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import * as urlSearchParams from "./url_search_params.ts"; +import { customInspect } from "./console.ts"; import * as domTypes from "./dom_types.ts"; +import { urls, URLSearchParams } from "./url_search_params.ts"; import { getRandomValues } from "../ops/get_random_values.ts"; -import { customInspect } from "./console.ts"; interface URLParts { protocol: string; @@ -24,7 +24,7 @@ const patterns = { authentication: "(?:([^:]*)(?::([^@]*))?@)", hostname: "([^:]+)", - port: "(?::(\\d+))" + port: "(?::(\\d+))", }; const urlRegExp = new RegExp( @@ -35,10 +35,10 @@ const authorityRegExp = new RegExp( `^${patterns.authentication}?${patterns.hostname}${patterns.port}?$` ); -const searchParamsMethods: Array<keyof urlSearchParams.URLSearchParams> = [ +const searchParamsMethods: Array<keyof URLSearchParams> = [ "append", "delete", - "set" + "set", ]; function parse(url: string): URLParts | undefined { @@ -57,7 +57,7 @@ function parse(url: string): URLParts | undefined { port: authorityMatch[4] || "", path: urlMatch[3] || "", query: urlMatch[4] || "", - hash: urlMatch[5] || "" + hash: urlMatch[5] || "", }; } } @@ -136,9 +136,11 @@ function resolvePathFromBase(path: string, basePath: string): string { return normalizePath(prefix + suffix); } -export class URL { - private _parts: URLParts; - private _searchParams!: urlSearchParams.URLSearchParams; +/** @internal */ +export const parts = new WeakMap<URL, URLParts>(); + +export class URL implements domTypes.URL { + #searchParams!: URLSearchParams; [customInspect](): string { const keys = [ @@ -152,7 +154,7 @@ export class URL { "port", "pathname", "hash", - "search" + "search", ]; const objectString = keys .map((key: string) => `${key}: "${this[key as keyof this] || ""}"`) @@ -160,8 +162,8 @@ export class URL { return `URL { ${objectString} }`; } - private _updateSearchParams(): void { - const searchParams = new urlSearchParams.URLSearchParams(this.search); + #updateSearchParams = (): void => { + const searchParams = new URLSearchParams(this.search); for (const methodName of searchParamsMethods) { /* eslint-disable @typescript-eslint/no-explicit-any */ @@ -172,27 +174,25 @@ export class URL { }; /* eslint-enable */ } - this._searchParams = searchParams; + this.#searchParams = searchParams; - // convert to `any` that has avoided the private limit - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (this._searchParams as any).url = this; - } + urls.set(searchParams, this); + }; get hash(): string { - return this._parts.hash; + return parts.get(this)!.hash; } set hash(value: string) { value = unescape(String(value)); if (!value) { - this._parts.hash = ""; + parts.get(this)!.hash = ""; } else { if (value.charAt(0) !== "#") { value = `#${value}`; } // hashes can contain % and # unescaped - this._parts.hash = escape(value) + parts.get(this)!.hash = escape(value) .replace(/%25/g, "%") .replace(/%23/g, "#"); } @@ -205,17 +205,17 @@ export class URL { set host(value: string) { value = String(value); const url = new URL(`http://${value}`); - this._parts.hostname = url.hostname; - this._parts.port = url.port; + parts.get(this)!.hostname = url.hostname; + parts.get(this)!.port = url.port; } get hostname(): string { - return this._parts.hostname; + return parts.get(this)!.hostname; } set hostname(value: string) { value = String(value); - this._parts.hostname = encodeURIComponent(value); + parts.get(this)!.hostname = encodeURIComponent(value); } get href(): string { @@ -234,8 +234,8 @@ export class URL { value = String(value); if (value !== this.href) { const url = new URL(value); - this._parts = { ...url._parts }; - this._updateSearchParams(); + parts.set(this, { ...parts.get(url)! }); + this.#updateSearchParams(); } } @@ -247,16 +247,16 @@ export class URL { } get password(): string { - return this._parts.password; + return parts.get(this)!.password; } set password(value: string) { value = String(value); - this._parts.password = encodeURIComponent(value); + parts.get(this)!.password = encodeURIComponent(value); } get pathname(): string { - return this._parts.path ? this._parts.path : "/"; + return parts.get(this)?.path || "/"; } set pathname(value: string) { @@ -265,22 +265,22 @@ export class URL { value = `/${value}`; } // paths can contain % unescaped - this._parts.path = escape(value).replace(/%25/g, "%"); + parts.get(this)!.path = escape(value).replace(/%25/g, "%"); } get port(): string { - return this._parts.port; + return parts.get(this)!.port; } set port(value: string) { const port = parseInt(String(value), 10); - this._parts.port = isNaN(port) + parts.get(this)!.port = isNaN(port) ? "" : Math.max(0, port % 2 ** 16).toString(); } get protocol(): string { - return `${this._parts.protocol}:`; + return `${parts.get(this)!.protocol}:`; } set protocol(value: string) { @@ -289,16 +289,17 @@ export class URL { if (value.charAt(value.length - 1) === ":") { value = value.slice(0, -1); } - this._parts.protocol = encodeURIComponent(value); + parts.get(this)!.protocol = encodeURIComponent(value); } } get search(): string { - if (this._parts.query === null || this._parts.query === "") { + const query = parts.get(this)!.query; + if (query === null || query === "") { return ""; } - return this._parts.query; + return query; } set search(value: string) { @@ -313,27 +314,27 @@ export class URL { query = value; } - this._parts.query = query; - this._updateSearchParams(); + parts.get(this)!.query = query; + this.#updateSearchParams(); } get username(): string { - return this._parts.username; + return parts.get(this)!.username; } set username(value: string) { value = String(value); - this._parts.username = encodeURIComponent(value); + parts.get(this)!.username = encodeURIComponent(value); } - get searchParams(): urlSearchParams.URLSearchParams { - return this._searchParams; + get searchParams(): URLSearchParams { + return this.#searchParams; } constructor(url: string, base?: string | URL) { let baseParts: URLParts | undefined; if (base) { - baseParts = typeof base === "string" ? parse(base) : base._parts; + baseParts = typeof base === "string" ? parse(base) : parts.get(base); if (!baseParts || baseParts.protocol == "") { throw new TypeError("Invalid base URL."); } @@ -345,9 +346,9 @@ export class URL { } if (urlParts.protocol) { - this._parts = urlParts; + parts.set(this, urlParts); } else if (baseParts) { - this._parts = { + parts.set(this, { protocol: baseParts.protocol, username: baseParts.username, password: baseParts.password, @@ -355,12 +356,12 @@ export class URL { port: baseParts.port, path: resolvePathFromBase(urlParts.path, baseParts.path || "/"), query: urlParts.query, - hash: urlParts.hash - }; + hash: urlParts.hash, + }); } else { throw new TypeError("URL requires a base URL."); } - this._updateSearchParams(); + this.#updateSearchParams(); } toString(): string { diff --git a/cli/js/web/url_search_params.ts b/cli/js/web/url_search_params.ts index 8f60f2918..aad59bb8c 100644 --- a/cli/js/web/url_search_params.ts +++ b/cli/js/web/url_search_params.ts @@ -1,33 +1,61 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { URL } from "./url.ts"; -import { requiredArguments } from "./util.ts"; - -// Returns whether o is iterable. -// @internal -export function isIterable<T, P extends keyof T, K extends T[P]>( - o: T -): o is T & Iterable<[P, K]> { - // checks for null and undefined - if (o == null) { - return false; - } - return ( - typeof ((o as unknown) as Iterable<[P, K]>)[Symbol.iterator] === "function" - ); +import * as domTypes from "./dom_types.ts"; +import { URL, parts } from "./url.ts"; +import { isIterable, requiredArguments } from "./util.ts"; + +/** @internal */ +export const urls = new WeakMap<URLSearchParams, URL | null>(); + +function handleStringInitialization( + searchParams: URLSearchParams, + init: string +): void { + // Overload: USVString + // If init is a string and starts with U+003F (?), + // remove the first code point from init. + if (init.charCodeAt(0) === 0x003f) { + init = init.slice(1); + } + + for (const pair of init.split("&")) { + // Empty params are ignored + if (pair.length === 0) { + continue; + } + const position = pair.indexOf("="); + const name = pair.slice(0, position === -1 ? pair.length : position); + const value = pair.slice(name.length + 1); + searchParams.append(decodeURIComponent(name), decodeURIComponent(value)); + } +} + +function handleArrayInitialization( + searchParams: URLSearchParams, + init: string[][] | Iterable<[string, string]> +): void { + // Overload: sequence<sequence<USVString>> + for (const tuple of init) { + // If pair does not contain exactly two items, then throw a TypeError. + if (tuple.length !== 2) { + throw new TypeError( + "URLSearchParams.constructor tuple array argument must only contain pair elements" + ); + } + searchParams.append(tuple[0], tuple[1]); + } } -export class URLSearchParams { - private params: Array<[string, string]> = []; - private url: URL | null = null; +export class URLSearchParams implements domTypes.URLSearchParams { + #params: Array<[string, string]> = []; constructor(init: string | string[][] | Record<string, string> = "") { if (typeof init === "string") { - this._handleStringInitialization(init); + handleStringInitialization(this, init); return; } if (Array.isArray(init) || isIterable(init)) { - this._handleArrayInitialization(init); + handleArrayInitialization(this, init); return; } @@ -36,7 +64,7 @@ export class URLSearchParams { } if (init instanceof URLSearchParams) { - this.params = init.params; + this.#params = [...init.#params]; return; } @@ -44,10 +72,13 @@ export class URLSearchParams { for (const key of Object.keys(init)) { this.append(key, init[key]); } + + urls.set(this, null); } - private updateSteps(): void { - if (this.url === null) { + #updateSteps = (): void => { + const url = urls.get(this); + if (url == null) { return; } @@ -56,35 +87,34 @@ export class URLSearchParams { query = null; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (this.url as any)._parts.query = query; - } + parts.get(url)!.query = query; + }; append(name: string, value: string): void { requiredArguments("URLSearchParams.append", arguments.length, 2); - this.params.push([String(name), String(value)]); - this.updateSteps(); + this.#params.push([String(name), String(value)]); + this.#updateSteps(); } delete(name: string): void { requiredArguments("URLSearchParams.delete", arguments.length, 1); name = String(name); let i = 0; - while (i < this.params.length) { - if (this.params[i][0] === name) { - this.params.splice(i, 1); + while (i < this.#params.length) { + if (this.#params[i][0] === name) { + this.#params.splice(i, 1); } else { i++; } } - this.updateSteps(); + this.#updateSteps(); } getAll(name: string): string[] { requiredArguments("URLSearchParams.getAll", arguments.length, 1); name = String(name); const values = []; - for (const entry of this.params) { + for (const entry of this.#params) { if (entry[0] === name) { values.push(entry[1]); } @@ -96,7 +126,7 @@ export class URLSearchParams { get(name: string): string | null { requiredArguments("URLSearchParams.get", arguments.length, 1); name = String(name); - for (const entry of this.params) { + for (const entry of this.#params) { if (entry[0] === name) { return entry[1]; } @@ -108,7 +138,7 @@ export class URLSearchParams { has(name: string): boolean { requiredArguments("URLSearchParams.has", arguments.length, 1); name = String(name); - return this.params.some((entry): boolean => entry[0] === name); + return this.#params.some((entry) => entry[0] === name); } set(name: string, value: string): void { @@ -121,14 +151,14 @@ export class URLSearchParams { value = String(value); let found = false; let i = 0; - while (i < this.params.length) { - if (this.params[i][0] === name) { + while (i < this.#params.length) { + if (this.#params[i][0] === name) { if (!found) { - this.params[i][1] = value; + this.#params[i][1] = value; found = true; i++; } else { - this.params.splice(i, 1); + this.#params.splice(i, 1); } } else { i++; @@ -141,14 +171,12 @@ export class URLSearchParams { this.append(name, value); } - this.updateSteps(); + this.#updateSteps(); } sort(): void { - this.params = this.params.sort((a, b): number => - a[0] === b[0] ? 0 : a[0] > b[0] ? 1 : -1 - ); - this.updateSteps(); + this.#params.sort((a, b) => (a[0] === b[0] ? 0 : a[0] > b[0] ? 1 : -1)); + this.#updateSteps(); } forEach( @@ -168,66 +196,31 @@ export class URLSearchParams { } *keys(): IterableIterator<string> { - for (const entry of this.params) { - yield entry[0]; + for (const [key] of this.#params) { + yield key; } } *values(): IterableIterator<string> { - for (const entry of this.params) { - yield entry[1]; + for (const [, value] of this.#params) { + yield value; } } *entries(): IterableIterator<[string, string]> { - yield* this.params; + yield* this.#params; } *[Symbol.iterator](): IterableIterator<[string, string]> { - yield* this.params; + yield* this.#params; } toString(): string { - return this.params + return this.#params .map( - (tuple): string => + (tuple) => `${encodeURIComponent(tuple[0])}=${encodeURIComponent(tuple[1])}` ) .join("&"); } - - private _handleStringInitialization(init: string): void { - // Overload: USVString - // If init is a string and starts with U+003F (?), - // remove the first code point from init. - if (init.charCodeAt(0) === 0x003f) { - init = init.slice(1); - } - - for (const pair of init.split("&")) { - // Empty params are ignored - if (pair.length === 0) { - continue; - } - const position = pair.indexOf("="); - const name = pair.slice(0, position === -1 ? pair.length : position); - const value = pair.slice(name.length + 1); - this.append(decodeURIComponent(name), decodeURIComponent(value)); - } - } - - private _handleArrayInitialization( - init: string[][] | Iterable<[string, string]> - ): void { - // Overload: sequence<sequence<USVString>> - for (const tuple of init) { - // If pair does not contain exactly two items, then throw a TypeError. - if (tuple.length !== 2) { - throw new TypeError( - "URLSearchParams.constructor tuple array argument must only contain pair elements" - ); - } - this.append(tuple[0], tuple[1]); - } - } } diff --git a/cli/js/web/util.ts b/cli/js/web/util.ts index 8d248ce1f..19a30a675 100644 --- a/cli/js/web/util.ts +++ b/cli/js/web/util.ts @@ -31,7 +31,7 @@ export function immutableDefine( Object.defineProperty(o, p, { value, configurable: false, - writable: false + writable: false, }); } @@ -53,3 +53,18 @@ export function hasOwnProperty<T>(obj: T, v: PropertyKey): boolean { } return Object.prototype.hasOwnProperty.call(obj, v); } + +/** Returns whether o is iterable. + * + * @internal */ +export function isIterable<T, P extends keyof T, K extends T[P]>( + o: T +): o is T & Iterable<[P, K]> { + // checks for null and undefined + if (o == null) { + return false; + } + return ( + typeof ((o as unknown) as Iterable<[P, K]>)[Symbol.iterator] === "function" + ); +} diff --git a/cli/js/web/workers.ts b/cli/js/web/workers.ts index 256090d57..834d0f297 100644 --- a/cli/js/web/workers.ts +++ b/cli/js/web/workers.ts @@ -4,13 +4,12 @@ import { createWorker, hostTerminateWorker, hostPostMessage, - hostGetMessage + hostGetMessage, } from "../ops/worker_host.ts"; import { log } from "../util.ts"; import { TextDecoder, TextEncoder } from "./text_encoding.ts"; /* import { blobURLMap } from "./web/url.ts"; -import { blobBytesWeakMap } from "./web/blob.ts"; */ import { Event } from "./event.ts"; import { EventTarget } from "./event_target.ts"; @@ -48,13 +47,13 @@ export interface WorkerOptions { } export class WorkerImpl extends EventTarget implements Worker { - private readonly id: number; - private isClosing = false; + readonly #id: number; + #name: string; + #terminated = false; + public onerror?: (e: any) => void; public onmessage?: (data: any) => void; public onmessageerror?: () => void; - private name: string; - private terminated = false; constructor(specifier: string, options?: WorkerOptions) { super(); @@ -66,7 +65,7 @@ export class WorkerImpl extends EventTarget implements Worker { ); } - this.name = name; + this.#name = name; const hasSourceCode = false; const sourceCode = decoder.decode(new Uint8Array()); @@ -92,11 +91,11 @@ export class WorkerImpl extends EventTarget implements Worker { sourceCode, options?.name ); - this.id = id; + this.#id = id; this.poll(); } - private handleError(e: any): boolean { + #handleError = (e: any): boolean => { // TODO: this is being handled in a type unsafe way, it should be type safe // eslint-disable-next-line @typescript-eslint/no-explicit-any const event = new Event("error", { cancelable: true }) as any; @@ -115,14 +114,14 @@ export class WorkerImpl extends EventTarget implements Worker { } return handled; - } + }; async poll(): Promise<void> { - while (!this.terminated) { - const event = await hostGetMessage(this.id); + while (!this.#terminated) { + const event = await hostGetMessage(this.#id); // If terminate was called then we ignore all messages - if (this.terminated) { + if (this.#terminated) { return; } @@ -137,15 +136,15 @@ export class WorkerImpl extends EventTarget implements Worker { } if (type === "error") { - if (!this.handleError(event.error)) { + if (!this.#handleError(event.error)) { throw Error(event.error.message); } continue; } if (type === "close") { - log(`Host got "close" message from worker: ${this.name}`); - this.terminated = true; + log(`Host got "close" message from worker: ${this.#name}`); + this.#terminated = true; return; } @@ -154,17 +153,17 @@ export class WorkerImpl extends EventTarget implements Worker { } postMessage(data: any): void { - if (this.terminated) { + if (this.#terminated) { return; } - hostPostMessage(this.id, encodeMessage(data)); + hostPostMessage(this.#id, encodeMessage(data)); } terminate(): void { - if (!this.terminated) { - this.terminated = true; - hostTerminateWorker(this.id); + if (!this.#terminated) { + this.#terminated = true; + hostTerminateWorker(this.#id); } } } |