Update to Prettier 2 and use ES Private Fields (#4498)

This commit is contained in:
Kitson Kelly 2020-03-29 04:03:49 +11:00 committed by GitHub
parent 1397b8e0e7
commit bced52505f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
329 changed files with 2787 additions and 2430 deletions

View File

@ -28,37 +28,37 @@ function copyBytes(dst: Uint8Array, src: Uint8Array, off = 0): number {
} }
export class Buffer implements Reader, SyncReader, Writer, SyncWriter { export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
private buf: Uint8Array; // contents are the bytes buf[off : len(buf)] #buf: Uint8Array; // contents are the bytes buf[off : len(buf)]
private off = 0; // read at buf[off], write at buf[buf.byteLength] #off = 0; // read at buf[off], write at buf[buf.byteLength]
constructor(ab?: ArrayBuffer) { constructor(ab?: ArrayBuffer) {
if (ab == null) { if (ab == null) {
this.buf = new Uint8Array(0); this.#buf = new Uint8Array(0);
return; return;
} }
this.buf = new Uint8Array(ab); this.#buf = new Uint8Array(ab);
} }
bytes(): Uint8Array { bytes(): Uint8Array {
return this.buf.subarray(this.off); return this.#buf.subarray(this.#off);
} }
toString(): string { toString(): string {
const decoder = new TextDecoder(); const decoder = new TextDecoder();
return decoder.decode(this.buf.subarray(this.off)); return decoder.decode(this.#buf.subarray(this.#off));
} }
empty(): boolean { empty(): boolean {
return this.buf.byteLength <= this.off; return this.#buf.byteLength <= this.#off;
} }
get length(): number { get length(): number {
return this.buf.byteLength - this.off; return this.#buf.byteLength - this.#off;
} }
get capacity(): number { get capacity(): number {
return this.buf.buffer.byteLength; return this.#buf.buffer.byteLength;
} }
truncate(n: number): void { truncate(n: number): void {
@ -69,27 +69,27 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
if (n < 0 || n > this.length) { if (n < 0 || n > this.length) {
throw Error("bytes.Buffer: truncation out of range"); throw Error("bytes.Buffer: truncation out of range");
} }
this._reslice(this.off + n); this.#reslice(this.#off + n);
} }
reset(): void { reset(): void {
this._reslice(0); this.#reslice(0);
this.off = 0; this.#off = 0;
} }
private _tryGrowByReslice(n: number): number { #tryGrowByReslice = (n: number): number => {
const l = this.buf.byteLength; const l = this.#buf.byteLength;
if (n <= this.capacity - l) { if (n <= this.capacity - l) {
this._reslice(l + n); this.#reslice(l + n);
return l; return l;
} }
return -1; return -1;
} };
private _reslice(len: number): void { #reslice = (len: number): void => {
assert(len <= this.buf.buffer.byteLength); assert(len <= this.#buf.buffer.byteLength);
this.buf = new Uint8Array(this.buf.buffer, 0, len); this.#buf = new Uint8Array(this.#buf.buffer, 0, len);
} };
readSync(p: Uint8Array): number | EOF { readSync(p: Uint8Array): number | EOF {
if (this.empty()) { if (this.empty()) {
@ -101,8 +101,8 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
} }
return EOF; return EOF;
} }
const nread = copyBytes(p, this.buf.subarray(this.off)); const nread = copyBytes(p, this.#buf.subarray(this.#off));
this.off += nread; this.#off += nread;
return nread; return nread;
} }
@ -112,8 +112,8 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
} }
writeSync(p: Uint8Array): number { writeSync(p: Uint8Array): number {
const m = this._grow(p.byteLength); const m = this.#grow(p.byteLength);
return copyBytes(this.buf, p, m); return copyBytes(this.#buf, p, m);
} }
write(p: Uint8Array): Promise<number> { write(p: Uint8Array): Promise<number> {
@ -121,14 +121,14 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
return Promise.resolve(n); return Promise.resolve(n);
} }
private _grow(n: number): number { #grow = (n: number): number => {
const m = this.length; const m = this.length;
// If buffer is empty, reset to recover space. // If buffer is empty, reset to recover space.
if (m === 0 && this.off !== 0) { if (m === 0 && this.#off !== 0) {
this.reset(); this.reset();
} }
// Fast: Try to grow by means of a reslice. // Fast: Try to grow by means of a reslice.
const i = this._tryGrowByReslice(n); const i = this.#tryGrowByReslice(n);
if (i >= 0) { if (i >= 0) {
return i; return i;
} }
@ -138,41 +138,41 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
// ArrayBuffer. We only need m+n <= c to slide, but // ArrayBuffer. We only need m+n <= c to slide, but
// we instead let capacity get twice as large so we // we instead let capacity get twice as large so we
// don't spend all our time copying. // 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) { } else if (c > MAX_SIZE - c - n) {
throw new Error("The buffer cannot be grown beyond the maximum size."); throw new Error("The buffer cannot be grown beyond the maximum size.");
} else { } else {
// Not enough space anywhere, we need to allocate. // Not enough space anywhere, we need to allocate.
const buf = new Uint8Array(2 * c + n); const buf = new Uint8Array(2 * c + n);
copyBytes(buf, this.buf.subarray(this.off)); copyBytes(buf, this.#buf.subarray(this.#off));
this.buf = buf; this.#buf = buf;
} }
// Restore this.off and len(this.buf). // Restore this.#off and len(this.#buf).
this.off = 0; this.#off = 0;
this._reslice(m + n); this.#reslice(m + n);
return m; return m;
} };
grow(n: number): void { grow(n: number): void {
if (n < 0) { if (n < 0) {
throw Error("Buffer.grow: negative count"); throw Error("Buffer.grow: negative count");
} }
const m = this._grow(n); const m = this.#grow(n);
this._reslice(m); this.#reslice(m);
} }
async readFrom(r: Reader): Promise<number> { async readFrom(r: Reader): Promise<number> {
let n = 0; let n = 0;
while (true) { while (true) {
try { try {
const i = this._grow(MIN_READ); const i = this.#grow(MIN_READ);
this._reslice(i); this.#reslice(i);
const fub = new Uint8Array(this.buf.buffer, i); const fub = new Uint8Array(this.#buf.buffer, i);
const nread = await r.read(fub); const nread = await r.read(fub);
if (nread === EOF) { if (nread === EOF) {
return n; return n;
} }
this._reslice(i + nread); this.#reslice(i + nread);
n += nread; n += nread;
} catch (e) { } catch (e) {
return n; return n;
@ -184,14 +184,14 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
let n = 0; let n = 0;
while (true) { while (true) {
try { try {
const i = this._grow(MIN_READ); const i = this.#grow(MIN_READ);
this._reslice(i); this.#reslice(i);
const fub = new Uint8Array(this.buf.buffer, i); const fub = new Uint8Array(this.#buf.buffer, i);
const nread = r.readSync(fub); const nread = r.readSync(fub);
if (nread === EOF) { if (nread === EOF) {
return n; return n;
} }
this._reslice(i + nread); this.#reslice(i + nread);
n += nread; n += nread;
} catch (e) { } catch (e) {
return n; return n;

View File

@ -13,7 +13,7 @@ export interface BuildInfo {
export const build: BuildInfo = { export const build: BuildInfo = {
arch: "" as Arch, arch: "" as Arch,
os: "" as OperatingSystem os: "" as OperatingSystem,
}; };
export function setBuildInfo(os: OperatingSystem, arch: Arch): void { export function setBuildInfo(os: OperatingSystem, arch: Arch): void {

View File

@ -17,7 +17,7 @@ function code(open: number, close: number): Code {
return { return {
open: `\x1b[${open}m`, open: `\x1b[${open}m`,
close: `\x1b[${close}m`, close: `\x1b[${close}m`,
regexp: new RegExp(`\\x1b\\[${close}m`, "g") regexp: new RegExp(`\\x1b\\[${close}m`, "g"),
}; };
} }

View File

@ -21,12 +21,12 @@ import {
defaultBundlerOptions, defaultBundlerOptions,
defaultRuntimeCompileOptions, defaultRuntimeCompileOptions,
defaultTranspileOptions, defaultTranspileOptions,
Host Host,
} from "./compiler/host.ts"; } from "./compiler/host.ts";
import { import {
processImports, processImports,
processLocalImports, processLocalImports,
resolveModules resolveModules,
} from "./compiler/imports.ts"; } from "./compiler/imports.ts";
import { import {
createWriteFile, createWriteFile,
@ -35,7 +35,7 @@ import {
ignoredDiagnostics, ignoredDiagnostics,
WriteFileState, WriteFileState,
processConfigureResponse, processConfigureResponse,
base64ToUint8Array base64ToUint8Array,
} from "./compiler/util.ts"; } from "./compiler/util.ts";
import { Diagnostic, DiagnosticItem } from "./diagnostics.ts"; import { Diagnostic, DiagnosticItem } from "./diagnostics.ts";
import { fromTypeScriptDiagnostic } from "./diagnostics_util.ts"; import { fromTypeScriptDiagnostic } from "./diagnostics_util.ts";
@ -93,7 +93,7 @@ async function compile(
const { bundle, config, configPath, outFile, rootNames, target } = request; const { bundle, config, configPath, outFile, rootNames, target } = request;
util.log(">>> compile start", { util.log(">>> compile start", {
rootNames, rootNames,
type: CompilerRequestType[request.type] type: CompilerRequestType[request.type],
}); });
// When a programme is emitted, TypeScript will call `writeFile` with // When a programme is emitted, TypeScript will call `writeFile` with
@ -108,14 +108,14 @@ async function compile(
bundle, bundle,
host: undefined, host: undefined,
outFile, outFile,
rootNames rootNames,
}; };
const writeFile = createWriteFile(state); const writeFile = createWriteFile(state);
const host = (state.host = new Host({ const host = (state.host = new Host({
bundle, bundle,
target, target,
writeFile writeFile,
})); }));
let diagnostics: readonly ts.Diagnostic[] | undefined; let diagnostics: readonly ts.Diagnostic[] | undefined;
@ -129,7 +129,7 @@ async function compile(
// requesting those from the privileged side, populating the in memory // requesting those from the privileged side, populating the in memory
// cache which will be used by the host, before resolving. // cache which will be used by the host, before resolving.
const resolvedRootModules = await processImports( const resolvedRootModules = await processImports(
rootNames.map(rootName => [rootName, rootName]), rootNames.map((rootName) => [rootName, rootName]),
undefined, undefined,
bundle || host.getCompilationSettings().checkJs bundle || host.getCompilationSettings().checkJs
); );
@ -143,7 +143,7 @@ async function compile(
rootNames, rootNames,
options, options,
host, host,
oldProgram: TS_SNAPSHOT_PROGRAM oldProgram: TS_SNAPSHOT_PROGRAM,
}); });
diagnostics = ts diagnostics = ts
@ -171,12 +171,12 @@ async function compile(
emitSkipped, emitSkipped,
diagnostics: diagnostics.length diagnostics: diagnostics.length
? fromTypeScriptDiagnostic(diagnostics) ? fromTypeScriptDiagnostic(diagnostics)
: undefined : undefined,
}; };
util.log("<<< compile end", { util.log("<<< compile end", {
rootNames, rootNames,
type: CompilerRequestType[request.type] type: CompilerRequestType[request.type],
}); });
return result; return result;
@ -190,7 +190,7 @@ async function runtimeCompile(
util.log(">>> runtime compile start", { util.log(">>> runtime compile start", {
rootName, rootName,
bundle, 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 // resolve the root name, if there are sources, the root name does not
@ -232,7 +232,7 @@ async function runtimeCompile(
const resolvedNames = resolveModules(additionalFiles); const resolvedNames = resolveModules(additionalFiles);
rootNames.push( rootNames.push(
...(await processImports( ...(await processImports(
resolvedNames.map(rn => [rn, rn]), resolvedNames.map((rn) => [rn, rn]),
undefined, undefined,
checkJsImports checkJsImports
)) ))
@ -246,14 +246,14 @@ async function runtimeCompile(
rootNames, rootNames,
sources, sources,
emitMap: {}, emitMap: {},
emitBundle: undefined emitBundle: undefined,
}; };
const writeFile = createWriteFile(state); const writeFile = createWriteFile(state);
const host = (state.host = new Host({ const host = (state.host = new Host({
bundle, bundle,
target, target,
writeFile writeFile,
})); }));
const compilerOptions = [defaultRuntimeCompileOptions]; const compilerOptions = [defaultRuntimeCompileOptions];
if (convertedOptions) { if (convertedOptions) {
@ -268,7 +268,7 @@ async function runtimeCompile(
rootNames, rootNames,
options: host.getCompilationSettings(), options: host.getCompilationSettings(),
host, host,
oldProgram: TS_SNAPSHOT_PROGRAM oldProgram: TS_SNAPSHOT_PROGRAM,
}); });
if (bundle) { if (bundle) {
@ -288,7 +288,7 @@ async function runtimeCompile(
rootName, rootName,
sources: sources ? Object.keys(sources) : undefined, sources: sources ? Object.keys(sources) : undefined,
bundle, bundle,
emitMap: Object.keys(state.emitMap) emitMap: Object.keys(state.emitMap),
}); });
const maybeDiagnostics = diagnostics.length const maybeDiagnostics = diagnostics.length
@ -320,7 +320,7 @@ function runtimeTranspile(
inputText, inputText,
{ {
fileName, fileName,
compilerOptions compilerOptions,
} }
); );
result[fileName] = { source, map }; result[fileName] = { source, map };
@ -329,7 +329,7 @@ function runtimeTranspile(
} }
async function tsCompilerOnMessage({ async function tsCompilerOnMessage({
data: request data: request,
}: { }: {
data: CompilerRequest; data: CompilerRequest;
}): Promise<void> { }): Promise<void> {
@ -364,7 +364,7 @@ async function tsCompilerOnMessage({
} }
async function wasmCompilerOnMessage({ async function wasmCompilerOnMessage({
data: binary data: binary,
}: { }: {
data: string; data: string;
}): Promise<void> { }): Promise<void> {
@ -411,12 +411,12 @@ Object.defineProperties(globalThis, {
value: bootstrapWasmCompilerRuntime, value: bootstrapWasmCompilerRuntime,
enumerable: false, enumerable: false,
writable: false, writable: false,
configurable: false configurable: false,
}, },
bootstrapTsCompilerRuntime: { bootstrapTsCompilerRuntime: {
value: bootstrapTsCompilerRuntime, value: bootstrapTsCompilerRuntime,
enumerable: false, enumerable: false,
writable: false, writable: false,
configurable: false configurable: false,
} },
}); });

View File

@ -157,7 +157,7 @@ export async function transpileOnly(
util.log("Deno.transpileOnly", { sources: Object.keys(sources), options }); util.log("Deno.transpileOnly", { sources: Object.keys(sources), options });
const payload = { const payload = {
sources, sources,
options: JSON.stringify(options) options: JSON.stringify(options),
}; };
const result = await runtimeCompilerOps.transpile(payload); const result = await runtimeCompilerOps.transpile(payload);
return JSON.parse(result); return JSON.parse(result);
@ -172,12 +172,12 @@ export async function compile(
rootName: sources ? rootName : checkRelative(rootName), rootName: sources ? rootName : checkRelative(rootName),
sources, sources,
options: JSON.stringify(options), options: JSON.stringify(options),
bundle: false bundle: false,
}; };
util.log("Deno.compile", { util.log("Deno.compile", {
rootName: payload.rootName, rootName: payload.rootName,
sources: !!sources, sources: !!sources,
options options,
}); });
const result = await runtimeCompilerOps.compile(payload); const result = await runtimeCompilerOps.compile(payload);
return JSON.parse(result); return JSON.parse(result);
@ -192,12 +192,12 @@ export async function bundle(
rootName: sources ? rootName : checkRelative(rootName), rootName: sources ? rootName : checkRelative(rootName),
sources, sources,
options: JSON.stringify(options), options: JSON.stringify(options),
bundle: true bundle: true,
}; };
util.log("Deno.bundle", { util.log("Deno.bundle", {
rootName: payload.rootName, rootName: payload.rootName,
sources: !!sources, sources: !!sources,
options options,
}); });
const result = await runtimeCompilerOps.compile(payload); const result = await runtimeCompilerOps.compile(payload);
return JSON.parse(result); return JSON.parse(result);

View File

@ -9,7 +9,7 @@ import { getAsset } from "./util.ts";
// load all type definitions and snapshot them. // load all type definitions and snapshot them.
const host = new Host({ const host = new Host({
target: CompilerHostTarget.Main, target: CompilerHostTarget.Main,
writeFile(): void {} writeFile(): void {},
}); });
const options = host.getCompilationSettings(); const options = host.getCompilationSettings();
@ -34,7 +34,7 @@ host.getSourceFile(
export const TS_SNAPSHOT_PROGRAM = ts.createProgram({ export const TS_SNAPSHOT_PROGRAM = ts.createProgram({
rootNames: [`${ASSETS}/bootstrap.ts`], rootNames: [`${ASSETS}/bootstrap.ts`],
options, options,
host host,
}); });
export const SYSTEM_LOADER = getAsset("system_loader.js"); export const SYSTEM_LOADER = getAsset("system_loader.js");

View File

@ -14,7 +14,7 @@ function normalizeUrl(rootName: string): string {
path, path,
false, false,
"/", "/",
code => code === CHAR_FORWARD_SLASH (code) => code === CHAR_FORWARD_SLASH
)}`; )}`;
} else { } else {
return rootName; return rootName;
@ -29,7 +29,7 @@ export function buildBundle(
// when outputting to AMD and a single outfile, TypeScript makes up the module // 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 // specifiers which are used to define the modules, and doesn't expose them
// publicly, so we have to try to replicate // 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); const sharedPath = commonPath(sources);
rootName = normalizeUrl(rootName) rootName = normalizeUrl(rootName)
.replace(sharedPath, "") .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 // 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 // out, so inspecting SymbolFlags that might be present that are type only
.filter( .filter(
sym => (sym) =>
sym.flags & ts.SymbolFlags.Class || sym.flags & ts.SymbolFlags.Class ||
!( !(
sym.flags & ts.SymbolFlags.Interface || sym.flags & ts.SymbolFlags.Interface ||
@ -94,5 +94,5 @@ export function setRootExports(program: ts.Program, rootModule: string): void {
sym.flags & ts.SymbolFlags.TypeAliasExcludes sym.flags & ts.SymbolFlags.TypeAliasExcludes
) )
) )
.map(sym => sym.getName()); .map((sym) => sym.getName());
} }

View File

@ -9,7 +9,7 @@ import * as util from "../util.ts";
export enum CompilerHostTarget { export enum CompilerHostTarget {
Main = "main", Main = "main",
Runtime = "runtime", Runtime = "runtime",
Worker = "worker" Worker = "worker",
} }
export interface CompilerHostOptions { export interface CompilerHostOptions {
@ -32,7 +32,7 @@ export const defaultBundlerOptions: ts.CompilerOptions = {
outDir: undefined, outDir: undefined,
outFile: `${OUT_DIR}/bundle.js`, outFile: `${OUT_DIR}/bundle.js`,
// disabled until we have effective way to modify source maps // disabled until we have effective way to modify source maps
sourceMap: false sourceMap: false,
}; };
export const defaultCompileOptions: ts.CompilerOptions = { export const defaultCompileOptions: ts.CompilerOptions = {
@ -47,11 +47,11 @@ export const defaultCompileOptions: ts.CompilerOptions = {
sourceMap: true, sourceMap: true,
strict: true, strict: true,
stripComments: true, stripComments: true,
target: ts.ScriptTarget.ESNext target: ts.ScriptTarget.ESNext,
}; };
export const defaultRuntimeCompileOptions: ts.CompilerOptions = { export const defaultRuntimeCompileOptions: ts.CompilerOptions = {
outDir: undefined outDir: undefined,
}; };
export const defaultTranspileOptions: ts.CompilerOptions = { export const defaultTranspileOptions: ts.CompilerOptions = {
@ -59,7 +59,7 @@ export const defaultTranspileOptions: ts.CompilerOptions = {
module: ts.ModuleKind.ESNext, module: ts.ModuleKind.ESNext,
sourceMap: true, sourceMap: true,
scriptComments: true, scriptComments: true,
target: ts.ScriptTarget.ESNext target: ts.ScriptTarget.ESNext,
}; };
const ignoredCompilerOptions: readonly string[] = [ const ignoredCompilerOptions: readonly string[] = [
@ -117,43 +117,41 @@ const ignoredCompilerOptions: readonly string[] = [
"types", "types",
"typeRoots", "typeRoots",
"version", "version",
"watch" "watch",
]; ];
export class Host implements ts.CompilerHost { function getAssetInternal(filename: string): SourceFile {
private readonly _options = defaultCompileOptions; const lastSegment = filename.split("/").pop()!;
const url = ts.libMap.has(lastSegment)
private _target: CompilerHostTarget; ? ts.libMap.get(lastSegment)!
: lastSegment;
private _writeFile: WriteFileCallback; const sourceFile = SourceFile.get(url);
if (sourceFile) {
private _getAsset(filename: string): SourceFile { return 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
});
} }
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 */ /* Deno specific APIs */
constructor({ bundle = false, target, writeFile }: CompilerHostOptions) { constructor({ bundle = false, target, writeFile }: CompilerHostOptions) {
this._target = target; this.#target = target;
this._writeFile = writeFile; this.#writeFile = writeFile;
if (bundle) { if (bundle) {
// options we need to change when we are generating a 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)) { for (const key of Object.keys(options)) {
if ( if (
ignoredCompilerOptions.includes(key) && ignoredCompilerOptions.includes(key) &&
(!(key in this._options) || options[key] !== this._options[key]) (!(key in this.#options) || options[key] !== this.#options[key])
) { ) {
ignoredOptions.push(key); ignoredOptions.push(key);
delete options[key]; delete options[key];
} }
} }
Object.assign(this._options, options); Object.assign(this.#options, options);
return { return {
ignoredOptions: ignoredOptions.length ? ignoredOptions : undefined, ignoredOptions: ignoredOptions.length ? ignoredOptions : undefined,
diagnostics: errors.length ? errors : undefined diagnostics: errors.length ? errors : undefined,
}; };
} }
mergeOptions(...options: ts.CompilerOptions[]): ts.CompilerOptions { mergeOptions(...options: ts.CompilerOptions[]): ts.CompilerOptions {
Object.assign(this._options, ...options); Object.assign(this.#options, ...options);
return Object.assign({}, this._options); return Object.assign({}, this.#options);
} }
/* TypeScript CompilerHost APIs */ /* TypeScript CompilerHost APIs */
@ -205,7 +203,7 @@ export class Host implements ts.CompilerHost {
getCompilationSettings(): ts.CompilerOptions { getCompilationSettings(): ts.CompilerOptions {
util.log("compiler::host.getCompilationSettings()"); util.log("compiler::host.getCompilationSettings()");
return this._options; return this.#options;
} }
getCurrentDirectory(): string { getCurrentDirectory(): string {
@ -214,7 +212,7 @@ export class Host implements ts.CompilerHost {
getDefaultLibFileName(_options: ts.CompilerOptions): string { getDefaultLibFileName(_options: ts.CompilerOptions): string {
util.log("compiler::host.getDefaultLibFileName()"); util.log("compiler::host.getDefaultLibFileName()");
switch (this._target) { switch (this.#target) {
case CompilerHostTarget.Main: case CompilerHostTarget.Main:
case CompilerHostTarget.Runtime: case CompilerHostTarget.Runtime:
return `${ASSETS}/lib.deno.window.d.ts`; return `${ASSETS}/lib.deno.window.d.ts`;
@ -237,7 +235,7 @@ export class Host implements ts.CompilerHost {
try { try {
assert(!shouldCreateNewSourceFile); assert(!shouldCreateNewSourceFile);
const sourceFile = fileName.startsWith(ASSETS) const sourceFile = fileName.startsWith(ASSETS)
? this._getAsset(fileName) ? getAssetInternal(fileName)
: SourceFile.get(fileName); : SourceFile.get(fileName);
assert(sourceFile != null); assert(sourceFile != null);
if (!sourceFile.tsSourceFile) { if (!sourceFile.tsSourceFile) {
@ -278,12 +276,12 @@ export class Host implements ts.CompilerHost {
): Array<ts.ResolvedModuleFull | undefined> { ): Array<ts.ResolvedModuleFull | undefined> {
util.log("compiler::host.resolveModuleNames", { util.log("compiler::host.resolveModuleNames", {
moduleNames, moduleNames,
containingFile containingFile,
}); });
return moduleNames.map(specifier => { return moduleNames.map((specifier) => {
const url = SourceFile.getUrl(specifier, containingFile); const url = SourceFile.getUrl(specifier, containingFile);
const sourceFile = specifier.startsWith(ASSETS) const sourceFile = specifier.startsWith(ASSETS)
? this._getAsset(specifier) ? getAssetInternal(specifier)
: url : url
? SourceFile.get(url) ? SourceFile.get(url)
: undefined; : undefined;
@ -293,7 +291,7 @@ export class Host implements ts.CompilerHost {
return { return {
resolvedFileName: sourceFile.url, resolvedFileName: sourceFile.url,
isExternalLibraryImport: specifier.startsWith(ASSETS), isExternalLibraryImport: specifier.startsWith(ASSETS),
extension: sourceFile.extension extension: sourceFile.extension,
}; };
}); });
} }
@ -310,6 +308,6 @@ export class Host implements ts.CompilerHost {
sourceFiles?: readonly ts.SourceFile[] sourceFiles?: readonly ts.SourceFile[]
): void { ): void {
util.log("compiler::host.writeFile", fileName); util.log("compiler::host.writeFile", fileName);
this._writeFile(fileName, data, sourceFiles); this.#writeFile(fileName, data, sourceFiles);
} }
} }

View File

@ -34,7 +34,7 @@ function resolvePath(...pathSegments: string[]): string {
resolvedPath, resolvedPath,
!resolvedAbsolute, !resolvedAbsolute,
"/", "/",
code => code === CHAR_FORWARD_SLASH (code) => code === CHAR_FORWARD_SLASH
); );
if (resolvedAbsolute) { if (resolvedAbsolute) {
@ -120,7 +120,7 @@ export function processLocalImports(
url: moduleName, url: moduleName,
filename: moduleName, filename: moduleName,
sourceCode: sources[moduleName], sourceCode: sources[moduleName],
mediaType: getMediaType(moduleName) mediaType: getMediaType(moduleName),
}); });
sourceFile.cache(specifiers[i][0], referrer); sourceFile.cache(specifiers[i][0], referrer);
if (!sourceFile.processed) { if (!sourceFile.processed) {

View File

@ -12,7 +12,7 @@ export enum MediaType {
TSX = 3, TSX = 3,
Json = 4, Json = 4,
Wasm = 5, Wasm = 5,
Unknown = 6 Unknown = 6,
} }
export interface SourceFileJson { 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 { export class SourceFile {
extension!: ts.Extension; extension!: ts.Extension;
filename!: string; filename!: string;
@ -63,20 +68,20 @@ export class SourceFile {
url!: string; url!: string;
constructor(json: SourceFileJson) { constructor(json: SourceFileJson) {
if (SourceFile._moduleCache.has(json.url)) { if (moduleCache.has(json.url)) {
throw new TypeError("SourceFile already exists"); throw new TypeError("SourceFile already exists");
} }
Object.assign(this, json); Object.assign(this, json);
this.extension = getExtension(this.url, this.mediaType); this.extension = getExtension(this.url, this.mediaType);
SourceFile._moduleCache.set(this.url, this); moduleCache.set(this.url, this);
} }
cache(moduleSpecifier: string, containingFile?: string): void { cache(moduleSpecifier: string, containingFile?: string): void {
containingFile = containingFile || ""; containingFile = containingFile || "";
let innerCache = SourceFile._specifierCache.get(containingFile); let innerCache = specifierCache.get(containingFile);
if (!innerCache) { if (!innerCache) {
innerCache = new Map(); innerCache = new Map();
SourceFile._specifierCache.set(containingFile, innerCache); specifierCache.set(containingFile, innerCache);
} }
innerCache.set(moduleSpecifier, this); innerCache.set(moduleSpecifier, this);
} }
@ -112,14 +117,14 @@ export class SourceFile {
importedFiles, importedFiles,
referencedFiles, referencedFiles,
libReferenceDirectives, libReferenceDirectives,
typeReferenceDirectives typeReferenceDirectives,
} = preProcessedFileInfo; } = preProcessedFileInfo;
const typeDirectives = parseTypeDirectives(this.sourceCode); const typeDirectives = parseTypeDirectives(this.sourceCode);
if (typeDirectives) { if (typeDirectives) {
for (const importedFile of importedFiles) { for (const importedFile of importedFiles) {
files.push([ files.push([
importedFile.fileName, importedFile.fileName,
getMappedModuleName(importedFile, typeDirectives) getMappedModuleName(importedFile, typeDirectives),
]); ]);
} }
} else if ( } else if (
@ -145,18 +150,11 @@ export class SourceFile {
return files; return files;
} }
private static _moduleCache: Map<string, SourceFile> = new Map();
private static _specifierCache: Map<
string,
Map<string, SourceFile>
> = new Map();
static getUrl( static getUrl(
moduleSpecifier: string, moduleSpecifier: string,
containingFile: string containingFile: string
): string | undefined { ): string | undefined {
const containingCache = this._specifierCache.get(containingFile); const containingCache = specifierCache.get(containingFile);
if (containingCache) { if (containingCache) {
const sourceFile = containingCache.get(moduleSpecifier); const sourceFile = containingCache.get(moduleSpecifier);
return sourceFile && sourceFile.url; return sourceFile && sourceFile.url;
@ -165,10 +163,10 @@ export class SourceFile {
} }
static get(url: string): SourceFile | undefined { static get(url: string): SourceFile | undefined {
return this._moduleCache.get(url); return moduleCache.get(url);
} }
static has(url: string): boolean { static has(url: string): boolean {
return this._moduleCache.has(url); return moduleCache.has(url);
} }
} }

View File

@ -39,7 +39,7 @@ export function parseTypeDirectives(
directives.push({ directives.push({
fileName, fileName,
pos, pos,
end: pos + matchString.length end: pos + matchString.length,
}); });
} }
if (!directives.length) { if (!directives.length) {
@ -60,7 +60,7 @@ export function parseTypeDirectives(
const target: FileReference = { const target: FileReference = {
fileName: targetFileName, fileName: targetFileName,
pos: targetPos, pos: targetPos,
end: targetPos + targetFileName.length end: targetPos + targetFileName.length,
}; };
results.set(target, fileName); results.set(target, fileName);
} }

View File

@ -33,7 +33,7 @@ export interface WriteFileState {
export enum CompilerRequestType { export enum CompilerRequestType {
Compile = 0, Compile = 0,
RuntimeCompile = 1, RuntimeCompile = 1,
RuntimeTranspile = 2 RuntimeTranspile = 2,
} }
export const OUT_DIR = "$deno$"; export const OUT_DIR = "$deno$";
@ -255,7 +255,7 @@ export function convertCompilerOptions(
} }
return { return {
options: out as ts.CompilerOptions, 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 '...'. '...' // TS7016: Could not find a declaration file for module '...'. '...'
// implicitly has an 'any' type. This is due to `allowJs` being off by // implicitly has an 'any' type. This is due to `allowJs` being off by
// default but importing of a JavaScript module. // default but importing of a JavaScript module.
7016 7016,
]; ];
export function processConfigureResponse( export function processConfigureResponse(

View File

@ -6,7 +6,7 @@ export {
readAll, readAll,
readAllSync, readAllSync,
writeAll, writeAll,
writeAllSync writeAllSync,
} from "./buffer.ts"; } from "./buffer.ts";
export { build, OperatingSystem, Arch } from "./build.ts"; export { build, OperatingSystem, Arch } from "./build.ts";
export { chmodSync, chmod } from "./ops/fs/chmod.ts"; export { chmodSync, chmod } from "./ops/fs/chmod.ts";
@ -18,7 +18,7 @@ export {
Diagnostic, Diagnostic,
DiagnosticCategory, DiagnosticCategory,
DiagnosticItem, DiagnosticItem,
DiagnosticMessageChain DiagnosticMessageChain,
} from "./diagnostics.ts"; } from "./diagnostics.ts";
export { chdir, cwd } from "./ops/fs/dir.ts"; export { chdir, cwd } from "./ops/fs/dir.ts";
export { applySourceMap, formatDiagnostics } from "./ops/errors.ts"; export { applySourceMap, formatDiagnostics } from "./ops/errors.ts";
@ -36,7 +36,7 @@ export {
seek, seek,
seekSync, seekSync,
OpenOptions, OpenOptions,
OpenMode OpenMode,
} from "./files.ts"; } from "./files.ts";
export { read, readSync, write, writeSync } from "./ops/io.ts"; export { read, readSync, write, writeSync } from "./ops/io.ts";
export { FsEvent, fsEvents } from "./ops/fs_events.ts"; export { FsEvent, fsEvents } from "./ops/fs_events.ts";
@ -57,7 +57,7 @@ export {
ReadSeeker, ReadSeeker,
WriteSeeker, WriteSeeker,
ReadWriteCloser, ReadWriteCloser,
ReadWriteSeeker ReadWriteSeeker,
} from "./io.ts"; } from "./io.ts";
export { linkSync, link } from "./ops/fs/link.ts"; export { linkSync, link } from "./ops/fs/link.ts";
export { export {
@ -65,7 +65,7 @@ export {
makeTempDir, makeTempDir,
makeTempFileSync, makeTempFileSync,
makeTempFile, makeTempFile,
MakeTempOptions MakeTempOptions,
} from "./ops/fs/make_temp.ts"; } from "./ops/fs/make_temp.ts";
export { metrics, Metrics } from "./ops/runtime.ts"; export { metrics, Metrics } from "./ops/runtime.ts";
export { mkdirSync, mkdir, MkdirOptions } from "./ops/fs/mkdir.ts"; export { mkdirSync, mkdir, MkdirOptions } from "./ops/fs/mkdir.ts";
@ -76,7 +76,7 @@ export {
Listener, Listener,
Conn, Conn,
ShutdownMode, ShutdownMode,
shutdown shutdown,
} from "./net.ts"; } from "./net.ts";
export { export {
dir, dir,
@ -85,14 +85,14 @@ export {
execPath, execPath,
hostname, hostname,
loadavg, loadavg,
osRelease osRelease,
} from "./ops/os.ts"; } from "./ops/os.ts";
export { export {
permissions, permissions,
PermissionName, PermissionName,
PermissionState, PermissionState,
PermissionStatus, PermissionStatus,
Permissions Permissions,
} from "./permissions.ts"; } from "./permissions.ts";
export { openPlugin } from "./plugins.ts"; export { openPlugin } from "./plugins.ts";
export { kill } from "./ops/process.ts"; export { kill } from "./ops/process.ts";

View File

@ -10,7 +10,7 @@ export enum DiagnosticCategory {
Info = 2, Info = 2,
Error = 3, Error = 3,
Warning = 4, Warning = 4,
Suggestion = 5 Suggestion = 5,
} }
export interface DiagnosticMessageChain { export interface DiagnosticMessageChain {

View File

@ -7,7 +7,7 @@ import {
Diagnostic, Diagnostic,
DiagnosticCategory, DiagnosticCategory,
DiagnosticMessageChain, DiagnosticMessageChain,
DiagnosticItem DiagnosticItem,
} from "./diagnostics.ts"; } from "./diagnostics.ts";
interface SourceInformation { interface SourceInformation {
@ -45,7 +45,7 @@ function getSourceInformation(
const scriptResourceName = sourceFile.fileName; const scriptResourceName = sourceFile.fileName;
const { const {
line: lineNumber, line: lineNumber,
character: startColumn character: startColumn,
} = sourceFile.getLineAndCharacterOfPosition(start); } = sourceFile.getLineAndCharacterOfPosition(start);
const endPosition = sourceFile.getLineAndCharacterOfPosition(start + length); const endPosition = sourceFile.getLineAndCharacterOfPosition(start + length);
const endColumn = const endColumn =
@ -67,7 +67,7 @@ function getSourceInformation(
lineNumber, lineNumber,
scriptResourceName, scriptResourceName,
startColumn, startColumn,
endColumn endColumn,
}; };
} }
@ -83,7 +83,7 @@ function fromDiagnosticMessageChain(
message, message,
code, code,
category: fromDiagnosticCategory(category), category: fromDiagnosticCategory(category),
next: fromDiagnosticMessageChain(next) next: fromDiagnosticMessageChain(next),
}; };
}); });
} }
@ -97,7 +97,7 @@ function parseDiagnostic(
code, code,
file, file,
start: startPosition, start: startPosition,
length length,
} = item; } = item;
const sourceInfo = const sourceInfo =
file && startPosition && length file && startPosition && length
@ -122,7 +122,7 @@ function parseDiagnostic(
code, code,
category, category,
startPosition, startPosition,
endPosition endPosition,
}; };
return sourceInfo ? { ...base, ...sourceInfo } : base; return sourceInfo ? { ...base, ...sourceInfo } : base;

View File

@ -54,7 +54,7 @@ function patchCallSite(callSite: CallSite, location: Location): CallSite {
}, },
getPromiseIndex(): number | null { getPromiseIndex(): number | null {
return callSite.getPromiseIndex(); return callSite.getPromiseIndex();
} },
}; };
} }
@ -181,7 +181,7 @@ function prepareStackTrace(
applySourceMap({ applySourceMap({
filename, filename,
line, line,
column column,
}) })
); );
} }

View File

@ -22,7 +22,7 @@ export enum ErrorKind {
Http = 19, Http = 19,
URIError = 20, URIError = 20,
TypeError = 21, TypeError = 21,
Other = 22 Other = 22,
} }
export function getErrorClass(kind: ErrorKind): { new (msg: string): Error } { export function getErrorClass(kind: ErrorKind): { new (msg: string): Error } {
@ -190,5 +190,5 @@ export const errors = {
WriteZero: WriteZero, WriteZero: WriteZero,
UnexpectedEof: UnexpectedEof, UnexpectedEof: UnexpectedEof,
BadResource: BadResource, BadResource: BadResource,
Http: Http Http: Http,
}; };

View File

@ -24,8 +24,8 @@ export interface FileInfo {
// @internal // @internal
export class FileInfoImpl implements FileInfo { export class FileInfoImpl implements FileInfo {
private readonly _isFile: boolean; readonly #isFile: boolean;
private readonly _isSymlink: boolean; readonly #isSymlink: boolean;
size: number; size: number;
modified: number | null; modified: number | null;
accessed: number | null; accessed: number | null;
@ -43,28 +43,18 @@ export class FileInfoImpl implements FileInfo {
blocks: number | null; blocks: number | null;
/* @internal */ /* @internal */
constructor(private _res: StatResponse) { constructor(res: StatResponse) {
const isUnix = build.os === "mac" || build.os === "linux"; const isUnix = build.os === "mac" || build.os === "linux";
const modified = this._res.modified; const modified = res.modified;
const accessed = this._res.accessed; const accessed = res.accessed;
const created = this._res.created; const created = res.created;
const name = this._res.name; const name = res.name;
// Unix only // Unix only
const { const { dev, ino, mode, nlink, uid, gid, rdev, blksize, blocks } = res;
dev,
ino,
mode,
nlink,
uid,
gid,
rdev,
blksize,
blocks
} = this._res;
this._isFile = this._res.isFile; this.#isFile = res.isFile;
this._isSymlink = this._res.isSymlink; this.#isSymlink = res.isSymlink;
this.size = this._res.size; this.size = res.size;
this.modified = modified ? modified : null; this.modified = modified ? modified : null;
this.accessed = accessed ? accessed : null; this.accessed = accessed ? accessed : null;
this.created = created ? created : null; this.created = created ? created : null;
@ -82,14 +72,14 @@ export class FileInfoImpl implements FileInfo {
} }
isFile(): boolean { isFile(): boolean {
return this._isFile; return this.#isFile;
} }
isDirectory(): boolean { isDirectory(): boolean {
return !this._isFile && !this._isSymlink; return !this.#isFile && !this.#isSymlink;
} }
isSymlink(): boolean { isSymlink(): boolean {
return this._isSymlink; return this.#isSymlink;
} }
} }

View File

@ -8,7 +8,7 @@ import {
SeekMode, SeekMode,
SyncReader, SyncReader,
SyncWriter, SyncWriter,
SyncSeeker SyncSeeker,
} from "./io.ts"; } from "./io.ts";
import { close } from "./ops/resources.ts"; import { close } from "./ops/resources.ts";
import { read, readSync, write, writeSync } from "./ops/io.ts"; import { read, readSync, write, writeSync } from "./ops/io.ts";
@ -18,7 +18,7 @@ import {
open as opOpen, open as opOpen,
openSync as opOpenSync, openSync as opOpenSync,
OpenOptions, OpenOptions,
OpenMode OpenMode,
} from "./ops/fs/open.ts"; } from "./ops/fs/open.ts";
export { OpenOptions, 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); export const stderr = new File(2);
function checkOpenOptions(options: OpenOptions): void { 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"); throw new Error("OpenOptions requires at least one option to be true");
} }

View File

@ -160,7 +160,7 @@ export function writable(value: unknown): PropertyDescriptor {
value, value,
writable: true, writable: true,
enumerable: true, enumerable: true,
configurable: true configurable: true,
}; };
} }
@ -168,14 +168,14 @@ export function nonEnumerable(value: unknown): PropertyDescriptor {
return { return {
value, value,
writable: true, writable: true,
configurable: true configurable: true,
}; };
} }
export function readOnly(value: unknown): PropertyDescriptor { export function readOnly(value: unknown): PropertyDescriptor {
return { return {
value, value,
enumerable: true enumerable: true,
}; };
} }
@ -183,7 +183,7 @@ export function readOnly(value: unknown): PropertyDescriptor {
export function getterOnly(getter: () => any): PropertyDescriptor { export function getterOnly(getter: () => any): PropertyDescriptor {
return { return {
get: getter, get: getter,
enumerable: true enumerable: true,
}; };
} }
@ -196,7 +196,7 @@ export const windowOrWorkerGlobalScopeMethods = {
fetch: writable(fetchTypes.fetch), fetch: writable(fetchTypes.fetch),
// queueMicrotask is bound in Rust // queueMicrotask is bound in Rust
setInterval: writable(timers.setInterval), setInterval: writable(timers.setInterval),
setTimeout: writable(timers.setTimeout) setTimeout: writable(timers.setTimeout),
}; };
// Other properties shared between WindowScope and WorkerGlobalScope // Other properties shared between WindowScope and WorkerGlobalScope
@ -216,7 +216,7 @@ export const windowOrWorkerGlobalScopeProperties = {
Request: nonEnumerable(request.Request), Request: nonEnumerable(request.Request),
Response: nonEnumerable(fetchTypes.Response), Response: nonEnumerable(fetchTypes.Response),
performance: writable(new performanceUtil.Performance()), performance: writable(new performanceUtil.Performance()),
Worker: nonEnumerable(workers.WorkerImpl) Worker: nonEnumerable(workers.WorkerImpl),
}; };
export const eventTargetProperties = { export const eventTargetProperties = {
@ -233,5 +233,5 @@ export const eventTargetProperties = {
dispatchEvent: readOnly(eventTarget.EventTarget.prototype.dispatchEvent), dispatchEvent: readOnly(eventTarget.EventTarget.prototype.dispatchEvent),
removeEventListener: readOnly( removeEventListener: readOnly(
eventTarget.EventTarget.prototype.removeEventListener eventTarget.EventTarget.prototype.removeEventListener
) ),
}; };

View File

@ -11,6 +11,6 @@ export const internalObject: { [key: string]: any } = {};
export function exposeForTest(name: string, value: any): void { export function exposeForTest(name: string, value: any): void {
Object.defineProperty(internalObject, name, { Object.defineProperty(internalObject, name, {
value, value,
enumerable: false enumerable: false,
}); });
} }

View File

@ -11,7 +11,7 @@ export type EOF = typeof EOF;
export enum SeekMode { export enum SeekMode {
SEEK_START = 0, SEEK_START = 0,
SEEK_CURRENT = 1, SEEK_CURRENT = 1,
SEEK_END = 2 SEEK_END = 2,
} }
// Reader is the interface that wraps the basic read() method. // Reader is the interface that wraps the basic read() method.
@ -99,8 +99,8 @@ export function toAsyncIterator(r: Reader): AsyncIterableIterator<Uint8Array> {
return { return {
value: b.subarray(0, result), value: b.subarray(0, result),
done: false done: false,
}; };
} },
}; };
} }

View File

@ -38,7 +38,7 @@ declare namespace Deno {
enum TestStatus { enum TestStatus {
Passed = "passed", Passed = "passed",
Failed = "failed", Failed = "failed",
Ignored = "ignored" Ignored = "ignored",
} }
interface TestResult { interface TestResult {
@ -60,7 +60,7 @@ declare namespace Deno {
Start = "start", Start = "start",
TestStart = "testStart", TestStart = "testStart",
TestEnd = "testEnd", TestEnd = "testEnd",
End = "end" End = "end",
} }
interface TestEventStart { interface TestEventStart {
@ -402,7 +402,7 @@ declare namespace Deno {
export enum SeekMode { export enum SeekMode {
SEEK_START = 0, SEEK_START = 0,
SEEK_CURRENT = 1, SEEK_CURRENT = 1,
SEEK_END = 2 SEEK_END = 2,
} }
/** **UNSTABLE**: might make `Reader` into iterator of some sort. */ /** **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). */ * Based on [Go Buffer](https://golang.org/pkg/bytes/#Buffer). */
export class Buffer implements Reader, SyncReader, Writer, SyncWriter { export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
private buf;
private off;
private _tryGrowByReslice;
private _reslice;
private _grow;
constructor(ab?: ArrayBuffer); constructor(ab?: ArrayBuffer);
/** Returns a slice holding the unread portion of the buffer. /** Returns a slice holding the unread portion of the buffer.
* *
@ -1603,7 +1597,7 @@ declare namespace Deno {
export enum ShutdownMode { export enum ShutdownMode {
Read = 0, Read = 0,
Write, Write,
ReadWrite // TODO(ry) panics on ReadWrite. ReadWrite, // TODO(ry) panics on ReadWrite.
} }
/** **UNSTABLE**: Maybe should remove `how` parameter maybe remove /** **UNSTABLE**: Maybe should remove `how` parameter maybe remove
@ -1998,7 +1992,7 @@ declare namespace Deno {
SIGWINCH = 28, SIGWINCH = 28,
SIGIO = 29, SIGIO = 29,
SIGPWR = 30, SIGPWR = 30,
SIGSYS = 31 SIGSYS = 31,
} }
enum MacOSSignal { enum MacOSSignal {
SIGHUP = 1, SIGHUP = 1,
@ -2031,7 +2025,7 @@ declare namespace Deno {
SIGWINCH = 28, SIGWINCH = 28,
SIGINFO = 29, SIGINFO = 29,
SIGUSR1 = 30, SIGUSR1 = 30,
SIGUSR2 = 31 SIGUSR2 = 31,
} }
/** **UNSTABLE**: make platform independent. /** **UNSTABLE**: make platform independent.
@ -2108,7 +2102,7 @@ declare namespace Deno {
Info = 2, Info = 2,
Error = 3, Error = 3,
Warning = 4, Warning = 4,
Suggestion = 5 Suggestion = 5,
} }
export interface DiagnosticMessageChain { export interface DiagnosticMessageChain {

View File

@ -339,12 +339,8 @@ declare namespace __domTypes {
export enum NodeType { export enum NodeType {
ELEMENT_NODE = 1, ELEMENT_NODE = 1,
TEXT_NODE = 3, 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 { export interface EventListener {
(evt: Event): void | Promise<void>; (evt: Event): void | Promise<void>;
} }
@ -358,11 +354,11 @@ declare namespace __domTypes {
callback: EventListenerOrEventListenerObject; callback: EventListenerOrEventListenerObject;
options: AddEventListenerOptions; 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 { export interface EventTarget {
[eventTargetHost]: EventTarget | null;
[eventTargetListeners]: { [type in string]: EventListener[] };
[eventTargetMode]: string;
[eventTargetNodeType]: NodeType;
addEventListener( addEventListener(
type: string, type: string,
callback: EventListenerOrEventListenerObject | null, callback: EventListenerOrEventListenerObject | null,
@ -438,7 +434,7 @@ declare namespace __domTypes {
NONE = 0, NONE = 0,
CAPTURING_PHASE = 1, CAPTURING_PHASE = 1,
AT_TARGET = 2, AT_TARGET = 2,
BUBBLING_PHASE = 3 BUBBLING_PHASE = 3,
} }
export interface EventPath { export interface EventPath {
item: EventTarget; item: EventTarget;
@ -532,17 +528,79 @@ declare namespace __domTypes {
options?: boolean | EventListenerOptions options?: boolean | EventListenerOptions
): void; ): void;
} }
export interface ReadableStream { export interface ReadableStreamReadDoneResult<T> {
readonly locked: boolean; done: true;
cancel(): Promise<void>; value?: T;
getReader(): ReadableStreamReader;
tee(): [ReadableStream, ReadableStream];
} }
export interface ReadableStreamReader { export interface ReadableStreamReadValueResult<T> {
cancel(): Promise<void>; done: false;
read(): Promise<any>; 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; 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(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 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> { export interface FormData extends DomIterable<string, FormDataEntryValue> {
append(name: string, value: string | Blob, fileName?: string): void; append(name: string, value: string | Blob, fileName?: string): void;
delete(name: string): void; delete(name: string): void;
@ -570,7 +628,7 @@ declare namespace __domTypes {
} }
export interface Body { export interface Body {
/** A simple getter used to expose a `ReadableStream` of the body contents. */ /** 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 /** Stores a `Boolean` that declares whether the body has been used in a
* response yet. * response yet.
*/ */
@ -799,58 +857,63 @@ declare namespace __domTypes {
/** Creates a clone of a `Response` object. */ /** Creates a clone of a `Response` object. */
clone(): Response; 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 { export interface Location {
/** /** Returns a DOMStringList object listing the origins of the ancestor
* Returns a DOMStringList object listing the origins of the ancestor browsing * browsing contexts, from the parent browsing context to the top-level
* contexts, from the parent browsing context to the top-level browsing * browsing context. */
* context. readonly ancestorOrigins: DOMStringList;
*/ /** Returns the Location object's URL's fragment (includes leading "#" if
readonly ancestorOrigins: string[];
/**
* Returns the Location object's URL's fragment (includes leading "#" if
* non-empty). * non-empty).
*
* Can be set, to navigate to the same URL with a changed fragment (ignores * Can be set, to navigate to the same URL with a changed fragment (ignores
* leading "#"). * leading "#"). */
*/
hash: string; hash: string;
/** /** Returns the Location object's URL's host and port (if different from the
* Returns the Location object's URL's host and port (if different from the * default port for the scheme).
* default port for the scheme). Can be set, to navigate to the same URL with *
* a changed host and port. * Can be set, to navigate to the same URL with a changed host and port. */
*/
host: string; host: string;
/** /** Returns the Location object's URL's host.
* Returns the Location object's URL's host. Can be set, to navigate to the *
* same URL with a changed host. * Can be set, to navigate to the same URL with a changed host. */
*/
hostname: string; hostname: string;
/** /** Returns the Location object's URL.
* Returns the Location object's URL. Can be set, to navigate to the given *
* URL. * Can be set, to navigate to the given URL. */
*/
href: string; href: string;
toString(): string;
/** Returns the Location object's URL's origin. */ /** Returns the Location object's URL's origin. */
readonly origin: string; readonly origin: string;
/** /** Returns the Location object's URL's path.
* Returns the Location object's URL's path. *
* Can be set, to navigate to the same URL with a changed path. * Can be set, to navigate to the same URL with a changed path. */
*/
pathname: string; pathname: string;
/** /** Returns the Location object's URL's port.
* Returns the Location object's URL's port. *
* Can be set, to navigate to the same URL with a changed port. * Can be set, to navigate to the same URL with a changed port. */
*/
port: string; port: string;
/** /** Returns the Location object's URL's scheme.
* Returns the Location object's URL's scheme. *
* Can be set, to navigate to the same URL with a changed scheme. * Can be set, to navigate to the same URL with a changed scheme. */
*/
protocol: string; protocol: string;
/** /** Returns the Location object's URL's query (includes leading "?" if
* Returns the Location object's URL's query (includes leading "?" if * non-empty).
* non-empty). Can be set, to navigate to the same URL with a changed query *
* (ignores leading "?"). * Can be set, to navigate to the same URL with a changed query (ignores
*/ * leading "?"). */
search: string; search: string;
/** /**
* Navigates to the given URL. * Navigates to the given URL.
@ -860,21 +923,14 @@ declare namespace __domTypes {
* Reloads the current page. * Reloads the current page.
*/ */
reload(): void; reload(): void;
/** @deprecated */ /** Removes the current page from the session history and navigates to the
reload(forcedReload: boolean): void; * given URL. */
/**
* Removes the current page from the session history and navigates to the
* given URL.
*/
replace(url: string): void; replace(url: string): void;
} }
} }
declare namespace __blob { declare namespace __blob {
export const bytesSymbol: unique symbol;
export const blobBytesWeakMap: WeakMap<__domTypes.Blob, Uint8Array>;
export class DenoBlob implements __domTypes.Blob { export class DenoBlob implements __domTypes.Blob {
private readonly [bytesSymbol];
readonly size: number; readonly size: number;
readonly type: string; readonly type: string;
/** A blob object represents a file-like object of immutable, raw data. */ /** A blob object represents a file-like object of immutable, raw data. */
@ -899,7 +955,6 @@ declare namespace __console {
} }
const isConsoleInstance: unique symbol; const isConsoleInstance: unique symbol;
export class Console { export class Console {
private printFunc;
indentLevel: number; indentLevel: number;
[isConsoleInstance]: boolean; [isConsoleInstance]: boolean;
/** Writes the arguments to stdout */ /** Writes the arguments to stdout */
@ -982,7 +1037,7 @@ declare namespace __event {
constructor({ constructor({
bubbles, bubbles,
cancelable, cancelable,
composed composed,
}?: { }?: {
bubbles?: boolean | undefined; bubbles?: boolean | undefined;
cancelable?: boolean | undefined; cancelable?: boolean | undefined;
@ -1053,7 +1108,7 @@ declare namespace __customEvent {
bubbles, bubbles,
cancelable, cancelable,
composed, composed,
detail detail,
}: __domTypes.CustomEventInit); }: __domTypes.CustomEventInit);
} }
export class CustomEvent extends __event.Event export class CustomEvent extends __event.Event
@ -1083,7 +1138,7 @@ declare namespace __eventTarget {
constructor({ constructor({
capture, capture,
passive, passive,
once once,
}?: { }?: {
capture?: boolean | undefined; capture?: boolean | undefined;
passive?: boolean | undefined; passive?: boolean | undefined;
@ -1123,7 +1178,7 @@ declare namespace __io {
export enum SeekMode { export enum SeekMode {
SEEK_START = 0, SEEK_START = 0,
SEEK_CURRENT = 1, SEEK_CURRENT = 1,
SEEK_END = 2 SEEK_END = 2,
} }
export interface Reader { export interface Reader {
/** Reads up to p.byteLength bytes into `p`. It resolves to the number /** Reads up to p.byteLength bytes into `p`. It resolves to the number
@ -1213,16 +1268,15 @@ declare namespace __io {
declare namespace __fetch { declare namespace __fetch {
class Body class Body
implements __domTypes.Body, __domTypes.ReadableStream, __io.ReadCloser { implements
private rid; __domTypes.Body,
__domTypes.ReadableStream<Uint8Array>,
__io.ReadCloser {
readonly contentType: string; readonly contentType: string;
bodyUsed: boolean; bodyUsed: boolean;
private _bodyPromise;
private _data;
readonly locked: boolean; readonly locked: boolean;
readonly body: null | Body; readonly body: __domTypes.ReadableStream<Uint8Array>;
constructor(rid: number, contentType: string); constructor(rid: number, contentType: string);
private _bodyBuffer;
arrayBuffer(): Promise<ArrayBuffer>; arrayBuffer(): Promise<ArrayBuffer>;
blob(): Promise<__domTypes.Blob>; blob(): Promise<__domTypes.Blob>;
formData(): Promise<__domTypes.FormData>; formData(): Promise<__domTypes.FormData>;
@ -1231,7 +1285,9 @@ declare namespace __fetch {
read(p: Uint8Array): Promise<number | Deno.EOF>; read(p: Uint8Array): Promise<number | Deno.EOF>;
close(): void; close(): void;
cancel(): Promise<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]; tee(): [__domTypes.ReadableStream, __domTypes.ReadableStream];
[Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array>; [Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array>;
} }
@ -1283,7 +1339,6 @@ declare namespace __textEncoding {
ignoreBOM?: boolean; ignoreBOM?: boolean;
} }
export class TextDecoder { export class TextDecoder {
private _encoding;
/** Returns encoding's name, lowercased. */ /** Returns encoding's name, lowercased. */
readonly encoding: string; readonly encoding: string;
/** Returns `true` if error mode is "fatal", and `false` otherwise. */ /** Returns `true` if error mode is "fatal", and `false` otherwise. */
@ -1333,10 +1388,7 @@ declare namespace __timers {
declare namespace __urlSearchParams { declare namespace __urlSearchParams {
export class URLSearchParams { export class URLSearchParams {
private params;
private url;
constructor(init?: string | string[][] | Record<string, string>); constructor(init?: string | string[][] | Record<string, string>);
private updateSteps;
/** Appends a specified key/value pair as a new search parameter. /** Appends a specified key/value pair as a new search parameter.
* *
* searchParams.append('name', 'first'); * searchParams.append('name', 'first');
@ -1431,8 +1483,6 @@ declare namespace __urlSearchParams {
* searchParams.toString(); * searchParams.toString();
*/ */
toString(): string; toString(): string;
private _handleStringInitialization;
private _handleArrayInitialization;
} }
} }
@ -1475,16 +1525,12 @@ declare namespace __workers {
name?: string; name?: string;
} }
export class WorkerImpl implements Worker { export class WorkerImpl implements Worker {
private readonly id;
private isClosing;
private readonly isClosedPromise;
onerror?: (e: Event) => void; onerror?: (e: Event) => void;
onmessage?: (data: any) => void; onmessage?: (data: any) => void;
onmessageerror?: () => void; onmessageerror?: () => void;
constructor(specifier: string, options?: WorkerOptions); constructor(specifier: string, options?: WorkerOptions);
postMessage(data: any): void; postMessage(data: any): void;
terminate(): void; terminate(): void;
private run;
} }
} }

View File

@ -13,12 +13,12 @@ Object.defineProperties(globalThis, {
value: bootstrapMainRuntime, value: bootstrapMainRuntime,
enumerable: false, enumerable: false,
writable: false, writable: false,
configurable: false configurable: false,
}, },
bootstrapWorkerRuntime: { bootstrapWorkerRuntime: {
value: bootstrapWorkerRuntime, value: bootstrapWorkerRuntime,
enumerable: false, enumerable: false,
writable: false, writable: false,
configurable: false configurable: false,
} },
}); });

View File

@ -168,7 +168,7 @@ export function listen(
res = netOps.listen({ res = netOps.listen({
transport: "tcp", transport: "tcp",
hostname: "127.0.0.1", hostname: "127.0.0.1",
...(options as ListenOptions) ...(options as ListenOptions),
}); });
} }
@ -205,7 +205,7 @@ export async function connect(
res = await netOps.connect({ res = await netOps.connect({
transport: "tcp", transport: "tcp",
hostname: "127.0.0.1", hostname: "127.0.0.1",
...options ...options,
}); });
} }

View File

@ -24,7 +24,7 @@ export function fetchSourceFiles(
> { > {
return sendAsync("op_fetch_source_files", { return sendAsync("op_fetch_source_files", {
specifiers, specifiers,
referrer referrer,
}); });
} }
@ -47,6 +47,6 @@ export function cache(
sendSync("op_cache", { sendSync("op_cache", {
extension, extension,
moduleId, moduleId,
contents contents,
}); });
} }

View File

@ -54,7 +54,7 @@ export function recordFromBufMinimal(ui8: Uint8Array): RecordMinimal {
promiseId, promiseId,
arg, arg,
result, result,
err err,
}; };
} }

View File

@ -21,11 +21,11 @@ export function applySourceMap(location: Location): Location {
const res = sendSync("op_apply_source_map", { const res = sendSync("op_apply_source_map", {
filename, filename,
line: line - 1, line: line - 1,
column: column - 1 column: column - 1,
}); });
return { return {
filename: res.filename, filename: res.filename,
line: res.line + 1, line: res.line + 1,
column: res.column + 1 column: res.column + 1,
}; };
} }

View File

@ -36,6 +36,6 @@ export function open(
path, path,
options, options,
openMode, openMode,
mode mode,
}); });
} }

View File

@ -25,7 +25,7 @@ export interface StatResponse {
export async function lstat(path: string): Promise<FileInfo> { export async function lstat(path: string): Promise<FileInfo> {
const res = (await sendAsync("op_stat", { const res = (await sendAsync("op_stat", {
path, path,
lstat: true lstat: true,
})) as StatResponse; })) as StatResponse;
return new FileInfoImpl(res); return new FileInfoImpl(res);
} }
@ -33,7 +33,7 @@ export async function lstat(path: string): Promise<FileInfo> {
export function lstatSync(path: string): FileInfo { export function lstatSync(path: string): FileInfo {
const res = sendSync("op_stat", { const res = sendSync("op_stat", {
path, path,
lstat: true lstat: true,
}) as StatResponse; }) as StatResponse;
return new FileInfoImpl(res); return new FileInfoImpl(res);
} }
@ -41,7 +41,7 @@ export function lstatSync(path: string): FileInfo {
export async function stat(path: string): Promise<FileInfo> { export async function stat(path: string): Promise<FileInfo> {
const res = (await sendAsync("op_stat", { const res = (await sendAsync("op_stat", {
path, path,
lstat: false lstat: false,
})) as StatResponse; })) as StatResponse;
return new FileInfoImpl(res); return new FileInfoImpl(res);
} }
@ -49,7 +49,7 @@ export async function stat(path: string): Promise<FileInfo> {
export function statSync(path: string): FileInfo { export function statSync(path: string): FileInfo {
const res = sendSync("op_stat", { const res = sendSync("op_stat", {
path, path,
lstat: false lstat: false,
}) as StatResponse; }) as StatResponse;
return new FileInfoImpl(res); return new FileInfoImpl(res);
} }

View File

@ -14,7 +14,7 @@ export function utimeSync(
path, path,
// TODO(ry) split atime, mtime into [seconds, nanoseconds] tuple // TODO(ry) split atime, mtime into [seconds, nanoseconds] tuple
atime: toSecondsFromEpoch(atime), atime: toSecondsFromEpoch(atime),
mtime: toSecondsFromEpoch(mtime) mtime: toSecondsFromEpoch(mtime),
}); });
} }
@ -27,6 +27,6 @@ export async function utime(
path, path,
// TODO(ry) split atime, mtime into [seconds, nanoseconds] tuple // TODO(ry) split atime, mtime into [seconds, nanoseconds] tuple
atime: toSecondsFromEpoch(atime), atime: toSecondsFromEpoch(atime),
mtime: toSecondsFromEpoch(mtime) mtime: toSecondsFromEpoch(mtime),
}); });
} }

View File

@ -17,7 +17,7 @@ class FsEvents implements AsyncIterableIterator<FsEvent> {
next(): Promise<IteratorResult<FsEvent>> { next(): Promise<IteratorResult<FsEvent>> {
return sendAsync("op_fs_events_poll", { return sendAsync("op_fs_events_poll", {
rid: this.rid rid: this.rid,
}); });
} }

View File

@ -19,7 +19,7 @@ export enum ShutdownMode {
// Corresponding to SHUT_RD, SHUT_WR, SHUT_RDWR // Corresponding to SHUT_RD, SHUT_WR, SHUT_RDWR
Read = 0, Read = 0,
Write, Write,
ReadWrite // unused ReadWrite, // unused
} }
export function shutdown(rid: number, how: ShutdownMode): void { export function shutdown(rid: number, how: ShutdownMode): void {

View File

@ -40,7 +40,7 @@ export function env(
set(obj, prop: string, value: string): boolean { set(obj, prop: string, value: string): boolean {
setEnv(prop, value); setEnv(prop, value);
return Reflect.set(obj, prop, value); return Reflect.set(obj, prop, value);
} },
}); });
} }

View File

@ -7,6 +7,6 @@ export function isatty(rid: number): boolean {
export function setRaw(rid: number, mode: boolean): void { export function setRaw(rid: number, mode: boolean): void {
sendSync("op_set_raw", { sendSync("op_set_raw", {
rid, rid,
mode mode,
}); });
} }

View File

@ -12,7 +12,7 @@ export function createWorker(
specifier, specifier,
hasSourceCode, hasSourceCode,
sourceCode, sourceCode,
name name,
}); });
} }

View File

@ -14,17 +14,21 @@ interface PluginOp {
} }
class PluginOpImpl implements PluginOp { class PluginOpImpl implements PluginOp {
constructor(private readonly opId: number) {} readonly #opId: number;
constructor(opId: number) {
this.#opId = opId;
}
dispatch( dispatch(
control: Uint8Array, control: Uint8Array,
zeroCopy?: ArrayBufferView | null zeroCopy?: ArrayBufferView | null
): Uint8Array | null { ): Uint8Array | null {
return core.dispatch(this.opId, control, zeroCopy); return core.dispatch(this.#opId, control, zeroCopy);
} }
setAsyncHandler(handler: AsyncHandler): void { setAsyncHandler(handler: AsyncHandler): void {
core.setAsyncHandler(this.opId, handler); core.setAsyncHandler(this.#opId, handler);
} }
} }
@ -37,16 +41,16 @@ interface Plugin {
} }
class PluginImpl implements 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) { for (const op in ops) {
this._ops[op] = new PluginOpImpl(ops[op]); this.#ops[op] = new PluginOpImpl(ops[op]);
} }
} }
get ops(): { [name: string]: PluginOp } { get ops(): { [name: string]: PluginOp } {
return Object.assign({}, this._ops); return Object.assign({}, this.#ops);
} }
} }

View File

@ -113,7 +113,7 @@ export function run({
env = {}, env = {},
stdout = "inherit", stdout = "inherit",
stderr = "inherit", stderr = "inherit",
stdin = "inherit" stdin = "inherit",
}: RunOptions): Process { }: RunOptions): Process {
const res = runOp({ const res = runOp({
cmd: cmd.map(String), cmd: cmd.map(String),
@ -124,7 +124,7 @@ export function run({
stderr: isRid(stderr) ? "" : stderr, stderr: isRid(stderr) ? "" : stderr,
stdinRid: isRid(stdin) ? stdin : 0, stdinRid: isRid(stdin) ? stdin : 0,
stdoutRid: isRid(stdout) ? stdout : 0, stdoutRid: isRid(stdout) ? stdout : 0,
stderrRid: isRid(stderr) ? stderr : 0 stderrRid: isRid(stderr) ? stderr : 0,
}) as RunResponse; }) as RunResponse;
return new Process(res); return new Process(res);
} }

View File

@ -1,5 +1,7 @@
// Derived from https://github.com/vadimg/js_bintrees. MIT Licensed. // Derived from https://github.com/vadimg/js_bintrees. MIT Licensed.
import { assert } from "./util.ts";
class RBNode<T> { class RBNode<T> {
public left: this | null; public left: this | null;
public right: this | null; public right: this | null;
@ -24,16 +26,18 @@ class RBNode<T> {
} }
} }
class RBTree<T> { export class RBTree<T> {
private root: RBNode<T> | null; #comparator: (a: T, b: T) => number;
#root: RBNode<T> | null;
constructor(private comparator: (a: T, b: T) => number) { constructor(comparator: (a: T, b: T) => number) {
this.root = null; this.#comparator = comparator;
this.#root = null;
} }
// returns null if tree is empty /** Returns `null` if tree is empty. */
min(): T | null { min(): T | null {
let res = this.root; let res = this.#root;
if (res === null) { if (res === null) {
return null; return null;
} }
@ -43,11 +47,11 @@ class RBTree<T> {
return res.data; return res.data;
} }
// returns node data if found, null otherwise /** Returns node `data` if found, `null` otherwise. */
find(data: T): T | null { find(data: T): T | null {
let res = this.root; let res = this.#root;
while (res !== null) { while (res !== null) {
const c = this.comparator(data, res.data!); const c = this.#comparator(data, res.data);
if (c === 0) { if (c === 0) {
return res.data; return res.data;
} else { } else {
@ -57,13 +61,13 @@ class RBTree<T> {
return null; return null;
} }
// returns true if inserted, false if duplicate /** returns `true` if inserted, `false` if duplicate. */
insert(data: T): boolean { insert(data: T): boolean {
let ret = false; let ret = false;
if (this.root === null) { if (this.#root === null) {
// empty tree // empty tree
this.root = new RBNode(data); this.#root = new RBNode(data);
ret = true; ret = true;
} else { } else {
const head = new RBNode((null as unknown) as T); // fake tree root const head = new RBNode((null as unknown) as T); // fake tree root
@ -75,8 +79,8 @@ class RBTree<T> {
let gp = null; // grandparent let gp = null; // grandparent
let ggp = head; // grand-grand-parent let ggp = head; // grand-grand-parent
let p: RBNode<T> | null = null; // parent let p: RBNode<T> | null = null; // parent
let node: RBNode<T> | null = this.root; let node: RBNode<T> | null = this.#root;
ggp.right = this.root; ggp.right = this.#root;
// search down // search down
while (true) { while (true) {
@ -96,14 +100,15 @@ class RBTree<T> {
if (isRed(node) && isRed(p)) { if (isRed(node) && isRed(p)) {
const dir2 = ggp.right === gp; const dir2 = ggp.right === gp;
assert(gp);
if (node === p!.getChild(last)) { if (node === p!.getChild(last)) {
ggp.setChild(dir2, singleRotate(gp!, !last)); ggp.setChild(dir2, singleRotate(gp, !last));
} else { } 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 // stop if found
if (cmp === 0) { if (cmp === 0) {
@ -123,24 +128,24 @@ class RBTree<T> {
} }
// update root // update root
this.root = head.right; this.#root = head.right;
} }
// make root black // make root black
this.root!.red = false; this.#root!.red = false;
return ret; return ret;
} }
// returns true if removed, false if not found /** Returns `true` if removed, `false` if not found. */
remove(data: T): boolean { remove(data: T): boolean {
if (this.root === null) { if (this.#root === null) {
return false; return false;
} }
const head = new RBNode((null as unknown) as T); // fake tree root const head = new RBNode((null as unknown) as T); // fake tree root
let node = head; let node = head;
node.right = this.root; node.right = this.#root;
let p = null; // parent let p = null; // parent
let gp = null; // grand parent let gp = null; // grand parent
let found = null; // found item let found = null; // found item
@ -154,7 +159,7 @@ class RBTree<T> {
p = node; p = node;
node = node.getChild(dir)!; node = node.getChild(dir)!;
const cmp = this.comparator(data, node.data); const cmp = this.#comparator(data, node.data);
dir = cmp > 0; dir = cmp > 0;
@ -181,7 +186,8 @@ class RBTree<T> {
sibling.red = true; sibling.red = true;
node.red = true; node.red = true;
} else { } else {
const dir2 = gp!.right === p; assert(gp);
const dir2 = gp.right === p;
if (isRed(sibling.getChild(last))) { if (isRed(sibling.getChild(last))) {
gp!.setChild(dir2, doubleRotate(p, last)); gp!.setChild(dir2, doubleRotate(p, last));
@ -190,11 +196,14 @@ class RBTree<T> {
} }
// ensure correct coloring // ensure correct coloring
const gpc = gp!.getChild(dir2)!; const gpc = gp.getChild(dir2);
assert(gpc);
gpc.red = true; gpc.red = true;
node.red = true; node.red = true;
gpc.left!.red = false; assert(gpc.left);
gpc.right!.red = false; gpc.left.red = false;
assert(gpc.right);
gpc.right.red = false;
} }
} }
} }
@ -204,13 +213,14 @@ class RBTree<T> {
// replace and remove if found // replace and remove if found
if (found !== null) { if (found !== null) {
found.data = node.data; 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 // update root and make it black
this.root = head.right; this.#root = head.right;
if (this.root !== null) { if (this.#root !== null) {
this.root.red = false; this.#root.red = false;
} }
return found !== null; 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> { 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)); root.setChild(!dir, save.getChild(dir));
save.setChild(dir, root); 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)); root.setChild(!dir, singleRotate(root.getChild(!dir)!, !dir));
return singleRotate(root, dir); return singleRotate(root, dir);
} }
export { RBTree };

View File

@ -17,20 +17,20 @@ const helpMsg = [
"_ Get last evaluation result", "_ Get last evaluation result",
"_error Get last thrown error", "_error Get last thrown error",
"exit Exit the REPL", "exit Exit the REPL",
"help Print this help message" "help Print this help message",
].join("\n"); ].join("\n");
const replCommands = { const replCommands = {
exit: { exit: {
get(): void { get(): void {
exit(0); exit(0);
} },
}, },
help: { help: {
get(): string { get(): string {
return helpMsg; return helpMsg;
} },
} },
}; };
// Error messages that allow users to continue input // Error messages that allow users to continue input
@ -42,7 +42,7 @@ const recoverableErrorMessages = [
"Missing initializer in const declaration", // const a "Missing initializer in const declaration", // const a
"Missing catch or finally after try", // try {} "Missing catch or finally after try", // try {}
"missing ) after argument list", // console.log(1 "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: // TODO(kevinkassimo): need a parser to handling errors such as:
// "Missing } in template expression" // `${ or `${ a 123 }` // "Missing } in template expression" // `${ or `${ a 123 }`
]; ];
@ -105,10 +105,10 @@ export async function replLoop(): Promise<void> {
value: value, value: value,
writable: true, writable: true,
enumerable: true, enumerable: true,
configurable: true configurable: true,
}); });
console.log("Last evaluation result is no longer saved to _."); console.log("Last evaluation result is no longer saved to _.");
} },
}); });
// Configure globalThis._error to give the last thrown error. // Configure globalThis._error to give the last thrown error.
@ -120,10 +120,10 @@ export async function replLoop(): Promise<void> {
value: value, value: value,
writable: true, writable: true,
enumerable: true, enumerable: true,
configurable: true configurable: true,
}); });
console.log("Last thrown error is no longer saved to _error."); console.log("Last thrown error is no longer saved to _error.");
} },
}); });
while (true) { while (true) {

View File

@ -17,7 +17,7 @@ import {
writable, writable,
windowOrWorkerGlobalScopeMethods, windowOrWorkerGlobalScopeMethods,
windowOrWorkerGlobalScopeProperties, windowOrWorkerGlobalScopeProperties,
eventTargetProperties eventTargetProperties,
} from "./globals.ts"; } from "./globals.ts";
import { internalObject } from "./internals.ts"; import { internalObject } from "./internals.ts";
import { setSignals } from "./signals.ts"; import { setSignals } from "./signals.ts";
@ -63,7 +63,7 @@ export const mainRuntimeGlobalProperties = {
onload: writable(undefined), onload: writable(undefined),
onunload: writable(undefined), onunload: writable(undefined),
close: writable(windowClose), close: writable(windowClose),
closed: getterOnly(() => windowIsClosing) closed: getterOnly(() => windowIsClosing),
}; };
let hasBootstrapped = false; let hasBootstrapped = false;
@ -102,7 +102,7 @@ export function bootstrapMainRuntime(): void {
Object.defineProperties(Deno, { Object.defineProperties(Deno, {
pid: readOnly(s.pid), pid: readOnly(s.pid),
noColor: readOnly(s.noColor), noColor: readOnly(s.noColor),
args: readOnly(Object.freeze(s.args)) args: readOnly(Object.freeze(s.args)),
}); });
// Setup `Deno` global - we're actually overriding already // Setup `Deno` global - we're actually overriding already
// existing global `Deno` with `Deno` namespace from "./deno.ts". // existing global `Deno` with `Deno` namespace from "./deno.ts".

View File

@ -14,7 +14,7 @@ import {
nonEnumerable, nonEnumerable,
windowOrWorkerGlobalScopeMethods, windowOrWorkerGlobalScopeMethods,
windowOrWorkerGlobalScopeProperties, windowOrWorkerGlobalScopeProperties,
eventTargetProperties eventTargetProperties,
} from "./globals.ts"; } from "./globals.ts";
import * as webWorkerOps from "./ops/web_worker.ts"; import * as webWorkerOps from "./ops/web_worker.ts";
import { LocationImpl } from "./web/location.ts"; import { LocationImpl } from "./web/location.ts";
@ -85,7 +85,7 @@ export const workerRuntimeGlobalProperties = {
// TODO: should be readonly? // TODO: should be readonly?
close: nonEnumerable(close), close: nonEnumerable(close),
postMessage: writable(postMessage), postMessage: writable(postMessage),
workerMessageRecvCallback: nonEnumerable(workerMessageRecvCallback) workerMessageRecvCallback: nonEnumerable(workerMessageRecvCallback),
}; };
export function bootstrapWorkerRuntime(name: string): void { export function bootstrapWorkerRuntime(name: string): void {

View File

@ -34,7 +34,7 @@ enum LinuxSignal {
SIGWINCH = 28, SIGWINCH = 28,
SIGIO = 29, SIGIO = 29,
SIGPWR = 30, SIGPWR = 30,
SIGSYS = 31 SIGSYS = 31,
} }
// From `kill -l` // From `kill -l`
@ -69,7 +69,7 @@ enum MacOSSignal {
SIGWINCH = 28, SIGWINCH = 28,
SIGINFO = 29, SIGINFO = 29,
SIGUSR1 = 30, SIGUSR1 = 30,
SIGUSR2 = 31 SIGUSR2 = 31,
} }
export const Signal: { [key: string]: number } = {}; export const Signal: { [key: string]: number } = {};
@ -122,39 +122,40 @@ export const signals = {
}, },
windowChange(): SignalStream { windowChange(): SignalStream {
return signal(Signal.SIGWINCH); return signal(Signal.SIGWINCH);
} },
}; };
export class SignalStream export class SignalStream
implements AsyncIterableIterator<void>, PromiseLike<void> { implements AsyncIterableIterator<void>, PromiseLike<void> {
private rid: number; #disposed = false;
private pollingPromise: Promise<boolean> = Promise.resolve(false); #pollingPromise: Promise<boolean> = Promise.resolve(false);
private disposed = false; #rid: number;
constructor(signo: number) { constructor(signo: number) {
this.rid = bindSignal(signo).rid; this.#rid = bindSignal(signo).rid;
this.loop(); this.#loop();
} }
private async pollSignal(): Promise<boolean> { #pollSignal = async (): Promise<boolean> => {
const res = await pollSignal(this.rid); const res = await pollSignal(this.#rid);
return res.done; return res.done;
} };
private async loop(): Promise<void> { #loop = async (): Promise<void> => {
do { do {
this.pollingPromise = this.pollSignal(); this.#pollingPromise = this.#pollSignal();
} while (!(await this.pollingPromise) && !this.disposed); } while (!(await this.#pollingPromise) && !this.#disposed);
} };
then<T, S>( then<T, S>(
f: (v: void) => T | Promise<T>, f: (v: void) => T | Promise<T>,
g?: (v: Error) => S | Promise<S> g?: (v: Error) => S | Promise<S>
): Promise<T | S> { ): Promise<T | S> {
return this.pollingPromise.then((_): void => {}).then(f, g); return this.#pollingPromise.then(() => {}).then(f, g);
} }
async next(): Promise<IteratorResult<void>> { async next(): Promise<IteratorResult<void>> {
return { done: await this.pollingPromise, value: undefined }; return { done: await this.#pollingPromise, value: undefined };
} }
[Symbol.asyncIterator](): AsyncIterableIterator<void> { [Symbol.asyncIterator](): AsyncIterableIterator<void> {
@ -162,10 +163,10 @@ export class SignalStream
} }
dispose(): void { dispose(): void {
if (this.disposed) { if (this.#disposed) {
throw new Error("The stream has already been disposed."); throw new Error("The stream has already been disposed.");
} }
this.disposed = true; this.#disposed = true;
unbindSignal(this.rid); unbindSignal(this.#rid);
} }
} }

View File

@ -4,5 +4,5 @@ import { customInspect } from "./web/console.ts";
export const symbols = { export const symbols = {
internal: internalSymbol, internal: internalSymbol,
customInspect customInspect,
}; };

View File

@ -11,7 +11,7 @@ import { assert } from "./util.ts";
const RED_FAILED = red("FAILED"); const RED_FAILED = red("FAILED");
const GREEN_OK = green("ok"); const GREEN_OK = green("ok");
const YELLOW_IGNORED = yellow("ignored"); const YELLOW_IGNORED = yellow("ignored");
const disabledConsole = new Console((_x: string, _isErr?: boolean): void => {}); const disabledConsole = new Console((): void => {});
function formatDuration(time = 0): string { function formatDuration(time = 0): string {
const timeStr = `(${time}ms)`; const timeStr = `(${time}ms)`;
@ -140,7 +140,7 @@ export interface RunTestsOptions {
enum TestStatus { enum TestStatus {
Passed = "passed", Passed = "passed",
Failed = "failed", Failed = "failed",
Ignored = "ignored" Ignored = "ignored",
} }
interface TestResult { interface TestResult {
@ -154,7 +154,7 @@ export enum TestEvent {
Start = "start", Start = "start",
TestStart = "testStart", TestStart = "testStart",
TestEnd = "testEnd", TestEnd = "testEnd",
End = "end" End = "end",
} }
interface TestEventStart { interface TestEventStart {
@ -188,7 +188,7 @@ class TestApi {
ignored: 0, ignored: 0,
measured: 0, measured: 0,
passed: 0, passed: 0,
failed: 0 failed: 0,
}; };
constructor( constructor(
@ -205,7 +205,7 @@ class TestApi {
> { > {
yield { yield {
kind: TestEvent.Start, kind: TestEvent.Start,
tests: this.testsToRun.length tests: this.testsToRun.length,
}; };
const results: TestResult[] = []; const results: TestResult[] = [];
@ -243,7 +243,7 @@ class TestApi {
kind: TestEvent.End, kind: TestEvent.End,
stats: this.stats, stats: this.stats,
results, results,
duration duration,
}; };
} }
} }
@ -283,33 +283,15 @@ interface TestReporter {
} }
export class ConsoleTestReporter implements 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> { start(event: TestEventStart): Promise<void> {
this.log(`running ${event.tests} tests`); ConsoleTestReporter.log(`running ${event.tests} tests`);
return Promise.resolve(); return Promise.resolve();
} }
testStart(event: TestEventTestStart): Promise<void> { testStart(event: TestEventTestStart): Promise<void> {
const { name } = event; const { name } = event;
this.log(`test ${name} ... `, true); ConsoleTestReporter.log(`test ${name} ... `, true);
return Promise.resolve(); return Promise.resolve();
} }
@ -318,13 +300,19 @@ export class ConsoleTestReporter implements TestReporter {
switch (result.status) { switch (result.status) {
case TestStatus.Passed: case TestStatus.Passed:
this.log(`${GREEN_OK} ${formatDuration(result.duration)}`); ConsoleTestReporter.log(
`${GREEN_OK} ${formatDuration(result.duration)}`
);
break; break;
case TestStatus.Failed: case TestStatus.Failed:
this.log(`${RED_FAILED} ${formatDuration(result.duration)}`); ConsoleTestReporter.log(
`${RED_FAILED} ${formatDuration(result.duration)}`
);
break; break;
case TestStatus.Ignored: case TestStatus.Ignored:
this.log(`${YELLOW_IGNORED} ${formatDuration(result.duration)}`); ConsoleTestReporter.log(
`${YELLOW_IGNORED} ${formatDuration(result.duration)}`
);
break; break;
} }
@ -334,25 +322,25 @@ export class ConsoleTestReporter implements TestReporter {
end(event: TestEventEnd): Promise<void> { end(event: TestEventEnd): Promise<void> {
const { stats, duration, results } = event; const { stats, duration, results } = event;
// Attempting to match the output of Rust's test runner. // 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) { if (failedTests.length > 0) {
this.log(`\nfailures:\n`); ConsoleTestReporter.log(`\nfailures:\n`);
for (const result of failedTests) { for (const result of failedTests) {
this.log(`${result.name}`); ConsoleTestReporter.log(`${result.name}`);
this.log(`${stringifyArgs([result.error!])}`); ConsoleTestReporter.log(`${stringifyArgs([result.error!])}`);
this.log(""); ConsoleTestReporter.log("");
} }
this.log(`failures:\n`); ConsoleTestReporter.log(`failures:\n`);
for (const result of failedTests) { 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}. ` + `\ntest result: ${stats.failed ? RED_FAILED : GREEN_OK}. ` +
`${stats.passed} passed; ${stats.failed} failed; ` + `${stats.passed} passed; ${stats.failed} failed; ` +
`${stats.ignored} ignored; ${stats.measured} measured; ` + `${stats.ignored} ignored; ${stats.measured} measured; ` +
@ -362,6 +350,20 @@ export class ConsoleTestReporter implements TestReporter {
return Promise.resolve(); 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({ export async function runTests({
@ -370,7 +372,7 @@ export async function runTests({
only = undefined, only = undefined,
skip = undefined, skip = undefined,
disableLog = false, disableLog = false,
reporter = undefined reporter = undefined,
}: RunTestsOptions = {}): Promise<{ }: RunTestsOptions = {}): Promise<{
results: TestResult[]; results: TestResult[];
stats: TestStats; stats: TestStats;

View File

@ -38,7 +38,7 @@ unitTest(function blobShouldNotThrowError(): void {
try { try {
const options1: object = { const options1: object = {
ending: "utf8", ending: "utf8",
hasOwnProperty: "hasOwnProperty" hasOwnProperty: "hasOwnProperty",
}; };
const options2: object = Object.create(null); const options2: object = Object.create(null);
new Blob(["Hello World"], options1); new Blob(["Hello World"], options1);
@ -52,7 +52,7 @@ unitTest(function blobShouldNotThrowError(): void {
unitTest(function nativeEndLine(): void { unitTest(function nativeEndLine(): void {
const options: object = { const options: object = {
ending: "native" ending: "native",
}; };
const blob = new Blob(["Hello\nWorld"], options); const blob = new Blob(["Hello\nWorld"], options);

View File

@ -5,7 +5,7 @@ import { unitTest, assertEquals, assert } from "./test_util.ts";
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
function buildBody(body: any): Body { function buildBody(body: any): Body {
const stub = new Request("", { const stub = new Request("", {
body: body body: body,
}); });
return stub as Body; return stub as Body;
} }
@ -19,7 +19,7 @@ const intArrays = [
Uint32Array, Uint32Array,
Uint8ClampedArray, Uint8ClampedArray,
Float32Array, Float32Array,
Float64Array Float64Array,
]; ];
unitTest(async function arrayBufferFromByteArrays(): Promise<void> { unitTest(async function arrayBufferFromByteArrays(): Promise<void> {
const buffer = new TextEncoder().encode("ahoyhoy8").buffer; const buffer = new TextEncoder().encode("ahoyhoy8").buffer;

View File

@ -7,7 +7,7 @@ import {
assertEquals, assertEquals,
assert, assert,
assertStrContains, assertStrContains,
unitTest unitTest,
} from "./test_util.ts"; } from "./test_util.ts";
const { Buffer, readAll, readAllSync, writeAll, writeAllSync } = Deno; const { Buffer, readAll, readAllSync, writeAll, writeAllSync } = Deno;

View File

@ -22,7 +22,7 @@ unitTest(
unitTest( unitTest(
{ {
ignore: Deno.build.os === "win", ignore: Deno.build.os === "win",
perms: { read: true, write: true } perms: { read: true, write: true },
}, },
function chmodSyncSymlinkSuccess(): void { function chmodSyncSymlinkSuccess(): void {
const enc = new TextEncoder(); const enc = new TextEncoder();
@ -94,7 +94,7 @@ unitTest(
unitTest( unitTest(
{ {
ignore: Deno.build.os === "win", ignore: Deno.build.os === "win",
perms: { read: true, write: true } perms: { read: true, write: true },
}, },
async function chmodSymlinkSuccess(): Promise<void> { async function chmodSymlinkSuccess(): Promise<void> {
const enc = new TextEncoder(); const enc = new TextEncoder();

View File

@ -7,11 +7,11 @@ if (Deno.build.os !== "win") {
// get the user ID and group ID of the current process // get the user ID and group ID of the current process
const uidProc = Deno.run({ const uidProc = Deno.run({
stdout: "piped", stdout: "piped",
cmd: ["python", "-c", "import os; print(os.getuid())"] cmd: ["python", "-c", "import os; print(os.getuid())"],
}); });
const gidProc = Deno.run({ const gidProc = Deno.run({
stdout: "piped", stdout: "piped",
cmd: ["python", "-c", "import os; print(os.getgid())"] cmd: ["python", "-c", "import os; print(os.getgid())"],
}); });
assertEquals((await uidProc.status()).code, 0); assertEquals((await uidProc.status()).code, 0);

View File

@ -6,14 +6,14 @@ import { assert, assertEquals, unitTest } from "./test_util.ts";
const { const {
inspect, inspect,
writeSync, writeSync,
stdout stdout,
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
} = Deno as any; } = Deno as any;
const customInspect = Deno.symbols.customInspect; const customInspect = Deno.symbols.customInspect;
const { const {
Console, Console,
stringifyArgs stringifyArgs,
// @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol // @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol
} = Deno[Deno.symbols.internal]; } = Deno[Deno.symbols.internal];
@ -37,7 +37,7 @@ unitTest(function consoleHasRightInstance(): void {
}); });
unitTest(function consoleTestAssertShouldNotThrowError(): void { unitTest(function consoleTestAssertShouldNotThrowError(): void {
mockConsole(console => { mockConsole((console) => {
console.assert(true); console.assert(true);
let hasThrown = undefined; let hasThrown = undefined;
try { try {
@ -92,7 +92,7 @@ unitTest(function consoleTestStringifyCircular(): void {
arrowFunc: () => {}, arrowFunc: () => {},
extendedClass: new Extended(), extendedClass: new Extended(),
nFunc: new Function(), nFunc: new Function(),
extendedCstr: Extended extendedCstr: Extended,
}; };
const circularObj = { const circularObj = {
@ -105,7 +105,7 @@ unitTest(function consoleTestStringifyCircular(): void {
nested: nestedObj, nested: nestedObj,
emptyObj: {}, emptyObj: {},
arr: [1, "s", false, null, nestedObj], arr: [1, "s", false, null, nestedObj],
baseClass: new Base() baseClass: new Base(),
}; };
nestedObj.o = circularObj; nestedObj.o = circularObj;
@ -154,7 +154,7 @@ unitTest(function consoleTestStringifyCircular(): void {
stringify( stringify(
new Map([ new Map([
[1, "one"], [1, "one"],
[2, "two"] [2, "two"],
]) ])
), ),
`Map { 1 => "one", 2 => "two" }` `Map { 1 => "one", 2 => "two" }`
@ -192,7 +192,6 @@ unitTest(function consoleTestStringifyCircular(): void {
assertEquals( assertEquals(
stringify(console), stringify(console),
`{ `{
printFunc: [Function],
log: [Function], log: [Function],
debug: [Function], debug: [Function],
info: [Function], info: [Function],
@ -261,8 +260,8 @@ unitTest(function consoleTestStringifyLargeObject(): void {
g: 10, g: 10,
asd: 2, asd: 2,
asda: 3, asda: 3,
x: { a: "asd", x: 3 } x: { a: "asd", x: 3 },
} },
}; };
assertEquals( assertEquals(
stringify(obj), stringify(obj),
@ -394,14 +393,14 @@ unitTest(function consoleTestWithVariousOrInvalidFormatSpecifier(): void {
unitTest(function consoleTestCallToStringOnLabel(): void { unitTest(function consoleTestCallToStringOnLabel(): void {
const methods = ["count", "countReset", "time", "timeLog", "timeEnd"]; const methods = ["count", "countReset", "time", "timeLog", "timeEnd"];
mockConsole(console => { mockConsole((console) => {
for (const method of methods) { for (const method of methods) {
let hasCalled = false; let hasCalled = false;
// @ts-ignore // @ts-ignore
console[method]({ console[method]({
toString(): void { toString(): void {
hasCalled = true; hasCalled = true;
} },
}); });
assertEquals(hasCalled, true); assertEquals(hasCalled, true);
} }
@ -446,7 +445,7 @@ unitTest(function consoleTestClear(): void {
// Test bound this issue // Test bound this issue
unitTest(function consoleDetachedLog(): void { unitTest(function consoleDetachedLog(): void {
mockConsole(console => { mockConsole((console) => {
const log = console.log; const log = console.log;
const dir = console.dir; const dir = console.dir;
const dirxml = console.dirxml; const dirxml = console.dirxml;
@ -635,7 +634,7 @@ unitTest(function consoleTable(): void {
console.table( console.table(
new Map([ new Map([
[1, "one"], [1, "one"],
[2, "two"] [2, "two"],
]) ])
); );
assertEquals( assertEquals(
@ -655,7 +654,7 @@ unitTest(function consoleTable(): void {
b: { c: { d: 10 }, e: [1, 2, [5, 6]] }, b: { c: { d: 10 }, e: [1, 2, [5, 6]] },
f: "test", f: "test",
g: new Set([1, 2, 3, "test"]), g: new Set([1, 2, 3, "test"]),
h: new Map([[1, "one"]]) h: new Map([[1, "one"]]),
}); });
assertEquals( assertEquals(
out.toString(), out.toString(),
@ -677,7 +676,7 @@ unitTest(function consoleTable(): void {
"test", "test",
false, false,
{ a: 10 }, { a: 10 },
["test", { b: 20, c: "test" }] ["test", { b: 20, c: "test" }],
]); ]);
assertEquals( assertEquals(
out.toString(), out.toString(),
@ -745,7 +744,7 @@ unitTest(function consoleTable(): void {
// console.log(Error) test // console.log(Error) test
unitTest(function consoleLogShouldNotThrowError(): void { unitTest(function consoleLogShouldNotThrowError(): void {
mockConsole(console => { mockConsole((console) => {
let result = 0; let result = 0;
try { try {
console.log(new Error("foo")); console.log(new Error("foo"));

View File

@ -7,7 +7,7 @@ unitTest(function customEventInitializedWithDetail(): void {
const customEventInit = { const customEventInit = {
bubbles: true, bubbles: true,
cancelable: true, cancelable: true,
detail detail,
} as CustomEventInit; } as CustomEventInit;
const event = new CustomEvent(type, customEventInit); const event = new CustomEvent(type, customEventInit);

View File

@ -3,7 +3,7 @@ import {
assertEquals, assertEquals,
assertMatch, assertMatch,
unitTest, unitTest,
unreachable unreachable,
} from "./test_util.ts"; } from "./test_util.ts";
const readErrorStackPattern = new RegExp( const readErrorStackPattern = new RegExp(

View File

@ -5,7 +5,7 @@ import { unitTest, assert, assertEquals } from "./test_util.ts";
function setup() { function setup() {
const dataSymbol = Symbol("data symbol"); const dataSymbol = Symbol("data symbol");
class Base { class Base {
private [dataSymbol] = new Map<string, number>(); [dataSymbol] = new Map<string, number>();
constructor( constructor(
data: Array<[string, number]> | IterableIterator<[string, number]> 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 // This is using an internal API we don't want published as types, so having
// to cast to any to "trick" TypeScript // to cast to any to "trick" TypeScript
// @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol // @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]> = [ const fixture: Array<[string, number]> = [
["foo", 1], ["foo", 1],
["bar", 2] ["bar", 2],
]; ];
const domIterable = new DomIterable(fixture); const domIterable = new DomIterable(fixture);

View File

@ -76,7 +76,7 @@ function getMockCallSite(
}, },
getPromiseIndex(): null { getPromiseIndex(): null {
return null; return null;
} },
}; };
} }
@ -90,7 +90,7 @@ unitTest(function prepareStackTrace(): void {
structuredStackTrace: CallSite[] structuredStackTrace: CallSite[]
) => string = MockError.prepareStackTrace; ) => string = MockError.prepareStackTrace;
const result = prepareStackTrace(new Error("foo"), [ 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.startsWith("Error: foo\n"));
assert(result.includes(".ts:"), "should remap to something in 'js/'"); assert(result.includes(".ts:"), "should remap to something in 'js/'");
@ -100,7 +100,7 @@ unitTest(function applySourceMap(): void {
const result = Deno.applySourceMap({ const result = Deno.applySourceMap({
filename: "CLI_SNAPSHOT.js", filename: "CLI_SNAPSHOT.js",
line: 23, line: 23,
column: 0 column: 0,
}); });
assert(result.filename.endsWith(".ts")); assert(result.filename.endsWith(".ts"));
assert(result.line != null); assert(result.line != null);

View File

@ -114,7 +114,7 @@ unitTest(function dispatchEventShouldNotThrowError(): void {
const target = new EventTarget(); const target = new EventTarget();
const event = new Event("hasOwnProperty", { const event = new Event("hasOwnProperty", {
bubbles: true, bubbles: true,
cancelable: false cancelable: false,
}); });
const listener = (): void => {}; const listener = (): void => {};
target.addEventListener("hasOwnProperty", listener); target.addEventListener("hasOwnProperty", listener);
@ -130,7 +130,7 @@ unitTest(function eventTargetThisShouldDefaultToWindow(): void {
const { const {
addEventListener, addEventListener,
dispatchEvent, dispatchEvent,
removeEventListener removeEventListener,
} = EventTarget.prototype; } = EventTarget.prototype;
let n = 1; let n = 1;
const event = new Event("hello"); const event = new Event("hello");
@ -164,7 +164,7 @@ unitTest(function eventTargetShouldAcceptEventListenerObject(): void {
handleEvent(e: Event): void { handleEvent(e: Event): void {
assertEquals(e, event); assertEquals(e, event);
++callCount; ++callCount;
} },
}; };
target.addEventListener("foo", listener); target.addEventListener("foo", listener);
@ -213,7 +213,7 @@ unitTest(
handleEvent(e: Event): void { handleEvent(e: Event): void {
assertEquals(e, event); assertEquals(e, event);
++callCount; ++callCount;
} },
}; };
target.addEventListener("foo", listener); target.addEventListener("foo", listener);

View File

@ -5,7 +5,7 @@ import {
assertEquals, assertEquals,
assertStrContains, assertStrContains,
assertThrows, assertThrows,
fail fail,
} from "./test_util.ts"; } from "./test_util.ts";
unitTest({ perms: { net: true } }, async function fetchProtocolError(): Promise< unitTest({ perms: { net: true } }, async function fetchProtocolError(): Promise<
@ -174,7 +174,7 @@ unitTest(
unitTest( unitTest(
{ {
perms: { net: true } perms: { net: true },
}, },
async function fetchWithRedirection(): Promise<void> { async function fetchWithRedirection(): Promise<void> {
const response = await fetch("http://localhost:4546/"); // will redirect to http://localhost:4545/ const response = await fetch("http://localhost:4546/"); // will redirect to http://localhost:4545/
@ -188,7 +188,7 @@ unitTest(
unitTest( unitTest(
{ {
perms: { net: true } perms: { net: true },
}, },
async function fetchWithRelativeRedirection(): Promise<void> { async function fetchWithRelativeRedirection(): Promise<void> {
const response = await fetch("http://localhost:4545/cli/tests"); // will redirect to /cli/tests/ const response = await fetch("http://localhost:4545/cli/tests"); // will redirect to /cli/tests/
@ -204,7 +204,7 @@ unitTest(
// FIXME(bartlomieju): // FIXME(bartlomieju):
// The feature below is not implemented, but the test should work after implementation // The feature below is not implemented, but the test should work after implementation
ignore: true, ignore: true,
perms: { net: true } perms: { net: true },
}, },
async function fetchWithInfRedirection(): Promise<void> { async function fetchWithInfRedirection(): Promise<void> {
const response = await fetch("http://localhost:4549/cli/tests"); // will redirect to the same place 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 data = "Hello World";
const response = await fetch("http://localhost:4545/echo_server", { const response = await fetch("http://localhost:4545/echo_server", {
method: "POST", method: "POST",
body: data body: data,
}); });
const text = await response.text(); const text = await response.text();
assertEquals(text, data); assertEquals(text, data);
@ -232,7 +232,7 @@ unitTest(
const data = "Hello World"; const data = "Hello World";
const req = new Request("http://localhost:4545/echo_server", { const req = new Request("http://localhost:4545/echo_server", {
method: "POST", method: "POST",
body: data body: data,
}); });
const response = await fetch(req); const response = await fetch(req);
const text = await response.text(); const text = await response.text();
@ -246,7 +246,7 @@ unitTest(
const data = "Hello World"; const data = "Hello World";
const response = await fetch("http://localhost:4545/echo_server", { const response = await fetch("http://localhost:4545/echo_server", {
method: "POST", method: "POST",
body: new TextEncoder().encode(data) body: new TextEncoder().encode(data),
}); });
const text = await response.text(); const text = await response.text();
assertEquals(text, data); assertEquals(text, data);
@ -260,7 +260,7 @@ unitTest(
const params = new URLSearchParams(data); const params = new URLSearchParams(data);
const response = await fetch("http://localhost:4545/echo_server", { const response = await fetch("http://localhost:4545/echo_server", {
method: "POST", method: "POST",
body: params body: params,
}); });
const text = await response.text(); const text = await response.text();
assertEquals(text, data); assertEquals(text, data);
@ -277,11 +277,11 @@ unitTest({ perms: { net: true } }, async function fetchInitBlobBody(): Promise<
> { > {
const data = "const a = 1"; const data = "const a = 1";
const blob = new Blob([data], { const blob = new Blob([data], {
type: "text/javascript" type: "text/javascript",
}); });
const response = await fetch("http://localhost:4545/echo_server", { const response = await fetch("http://localhost:4545/echo_server", {
method: "POST", method: "POST",
body: blob body: blob,
}); });
const text = await response.text(); const text = await response.text();
assertEquals(text, data); assertEquals(text, data);
@ -295,7 +295,7 @@ unitTest(
form.append("field", "value"); form.append("field", "value");
const response = await fetch("http://localhost:4545/echo_server", { const response = await fetch("http://localhost:4545/echo_server", {
method: "POST", method: "POST",
body: form body: form,
}); });
const resultForm = await response.formData(); const resultForm = await response.formData();
assertEquals(form.get("field"), resultForm.get("field")); assertEquals(form.get("field"), resultForm.get("field"));
@ -308,7 +308,7 @@ unitTest({ perms: { net: true } }, async function fetchUserAgent(): Promise<
const data = "Hello World"; const data = "Hello World";
const response = await fetch("http://localhost:4545/echo_server", { const response = await fetch("http://localhost:4545/echo_server", {
method: "POST", method: "POST",
body: new TextEncoder().encode(data) body: new TextEncoder().encode(data),
}); });
assertEquals(response.headers.get("user-agent"), `Deno/${Deno.version.deno}`); assertEquals(response.headers.get("user-agent"), `Deno/${Deno.version.deno}`);
await response.text(); await response.text();
@ -337,7 +337,7 @@ function bufferServer(addr: string): Deno.Buffer {
const [hostname, port] = addr.split(":"); const [hostname, port] = addr.split(":");
const listener = Deno.listen({ const listener = Deno.listen({
hostname, hostname,
port: Number(port) port: Number(port),
}) as Deno.Listener; }) as Deno.Listener;
const buf = new Deno.Buffer(); const buf = new Deno.Buffer();
listener.accept().then(async (conn: Deno.Conn) => { listener.accept().then(async (conn: Deno.Conn) => {
@ -364,7 +364,7 @@ unitTest(
{ {
// FIXME(bartlomieju) // FIXME(bartlomieju)
ignore: true, ignore: true,
perms: { net: true } perms: { net: true },
}, },
async function fetchRequest(): Promise<void> { async function fetchRequest(): Promise<void> {
const addr = "127.0.0.1:4501"; const addr = "127.0.0.1:4501";
@ -373,8 +373,8 @@ unitTest(
method: "POST", method: "POST",
headers: [ headers: [
["Hello", "World"], ["Hello", "World"],
["Foo", "Bar"] ["Foo", "Bar"],
] ],
}); });
assertEquals(response.status, 404); assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2"); assertEquals(response.headers.get("Content-Length"), "2");
@ -384,7 +384,7 @@ unitTest(
"POST /blah HTTP/1.1\r\n", "POST /blah HTTP/1.1\r\n",
"hello: World\r\n", "hello: World\r\n",
"foo: Bar\r\n", "foo: Bar\r\n",
`host: ${addr}\r\n\r\n` `host: ${addr}\r\n\r\n`,
].join(""); ].join("");
assertEquals(actual, expected); assertEquals(actual, expected);
} }
@ -394,7 +394,7 @@ unitTest(
{ {
// FIXME(bartlomieju) // FIXME(bartlomieju)
ignore: true, ignore: true,
perms: { net: true } perms: { net: true },
}, },
async function fetchPostBodyString(): Promise<void> { async function fetchPostBodyString(): Promise<void> {
const addr = "127.0.0.1:4502"; const addr = "127.0.0.1:4502";
@ -404,9 +404,9 @@ unitTest(
method: "POST", method: "POST",
headers: [ headers: [
["Hello", "World"], ["Hello", "World"],
["Foo", "Bar"] ["Foo", "Bar"],
], ],
body body,
}); });
assertEquals(response.status, 404); assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2"); assertEquals(response.headers.get("Content-Length"), "2");
@ -418,7 +418,7 @@ unitTest(
"foo: Bar\r\n", "foo: Bar\r\n",
`host: ${addr}\r\n`, `host: ${addr}\r\n`,
`content-length: ${body.length}\r\n\r\n`, `content-length: ${body.length}\r\n\r\n`,
body body,
].join(""); ].join("");
assertEquals(actual, expected); assertEquals(actual, expected);
} }
@ -428,7 +428,7 @@ unitTest(
{ {
// FIXME(bartlomieju) // FIXME(bartlomieju)
ignore: true, ignore: true,
perms: { net: true } perms: { net: true },
}, },
async function fetchPostBodyTypedArray(): Promise<void> { async function fetchPostBodyTypedArray(): Promise<void> {
const addr = "127.0.0.1:4503"; const addr = "127.0.0.1:4503";
@ -439,9 +439,9 @@ unitTest(
method: "POST", method: "POST",
headers: [ headers: [
["Hello", "World"], ["Hello", "World"],
["Foo", "Bar"] ["Foo", "Bar"],
], ],
body body,
}); });
assertEquals(response.status, 404); assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2"); assertEquals(response.headers.get("Content-Length"), "2");
@ -453,7 +453,7 @@ unitTest(
"foo: Bar\r\n", "foo: Bar\r\n",
`host: ${addr}\r\n`, `host: ${addr}\r\n`,
`content-length: ${body.byteLength}\r\n\r\n`, `content-length: ${body.byteLength}\r\n\r\n`,
bodyStr bodyStr,
].join(""); ].join("");
assertEquals(actual, expected); assertEquals(actual, expected);
} }
@ -461,11 +461,11 @@ unitTest(
unitTest( unitTest(
{ {
perms: { net: true } perms: { net: true },
}, },
async function fetchWithManualRedirection(): Promise<void> { async function fetchWithManualRedirection(): Promise<void> {
const response = await fetch("http://localhost:4546/", { const response = await fetch("http://localhost:4546/", {
redirect: "manual" redirect: "manual",
}); // will redirect to http://localhost:4545/ }); // will redirect to http://localhost:4545/
assertEquals(response.status, 0); assertEquals(response.status, 0);
assertEquals(response.statusText, ""); assertEquals(response.statusText, "");
@ -484,11 +484,11 @@ unitTest(
unitTest( unitTest(
{ {
perms: { net: true } perms: { net: true },
}, },
async function fetchWithErrorRedirection(): Promise<void> { async function fetchWithErrorRedirection(): Promise<void> {
const response = await fetch("http://localhost:4546/", { const response = await fetch("http://localhost:4546/", {
redirect: "error" redirect: "error",
}); // will redirect to http://localhost:4545/ }); // will redirect to http://localhost:4545/
assertEquals(response.status, 0); assertEquals(response.status, 0);
assertEquals(response.statusText, ""); assertEquals(response.statusText, "");

View File

@ -58,7 +58,7 @@ unitTest(function fileVariousFileBits(): void {
new Blob(), new Blob(),
new Uint8Array([0x50, 0x41]), new Uint8Array([0x50, 0x41]),
new Uint16Array([0x5353]), new Uint16Array([0x5353]),
new Uint32Array([0x53534150]) new Uint32Array([0x53534150]),
], ],
16 16
); );

View File

@ -3,7 +3,7 @@ import {
unitTest, unitTest,
assert, assert,
assertEquals, assertEquals,
assertStrContains assertStrContains,
} from "./test_util.ts"; } from "./test_util.ts";
unitTest(function filesStdioFileDescriptors(): void { unitTest(function filesStdioFileDescriptors(): void {
@ -46,15 +46,17 @@ unitTest(async function readerToAsyncIterator(): Promise<void> {
const encoder = new TextEncoder(); const encoder = new TextEncoder();
class TestReader implements Deno.Reader { class TestReader implements Deno.Reader {
private offset = 0; #offset = 0;
private buf = new Uint8Array(encoder.encode(this.s)); #buf: Uint8Array;
constructor(private readonly s: string) {} constructor(s: string) {
this.#buf = new Uint8Array(encoder.encode(s));
}
read(p: Uint8Array): Promise<number | Deno.EOF> { read(p: Uint8Array): Promise<number | Deno.EOF> {
const n = Math.min(p.byteLength, this.buf.byteLength - this.offset); const n = Math.min(p.byteLength, this.#buf.byteLength - this.#offset);
p.set(this.buf.slice(this.offset, this.offset + n)); p.set(this.#buf.slice(this.#offset, this.#offset + n));
this.offset += n; this.#offset += n;
if (n === 0) { if (n === 0) {
return Promise.resolve(Deno.EOF); return Promise.resolve(Deno.EOF);
@ -76,14 +78,14 @@ unitTest(async function readerToAsyncIterator(): Promise<void> {
unitTest( unitTest(
{ {
perms: { read: true, write: true } perms: { read: true, write: true },
}, },
function openSyncMode(): void { function openSyncMode(): void {
const path = Deno.makeTempDirSync() + "/test_openSync.txt"; const path = Deno.makeTempDirSync() + "/test_openSync.txt";
const file = Deno.openSync(path, { const file = Deno.openSync(path, {
write: true, write: true,
createNew: true, createNew: true,
mode: 0o626 mode: 0o626,
}); });
file.close(); file.close();
const pathInfo = Deno.statSync(path); const pathInfo = Deno.statSync(path);
@ -95,14 +97,14 @@ unitTest(
unitTest( unitTest(
{ {
perms: { read: true, write: true } perms: { read: true, write: true },
}, },
async function openMode(): Promise<void> { async function openMode(): Promise<void> {
const path = (await Deno.makeTempDir()) + "/test_open.txt"; const path = (await Deno.makeTempDir()) + "/test_open.txt";
const file = await Deno.open(path, { const file = await Deno.open(path, {
write: true, write: true,
createNew: true, createNew: true,
mode: 0o626 mode: 0o626,
}); });
file.close(); file.close();
const pathInfo = Deno.statSync(path); const pathInfo = Deno.statSync(path);
@ -198,7 +200,7 @@ unitTest(
const w = { const w = {
write: true, write: true,
truncate: true, truncate: true,
create: true create: true,
}; };
const file = await Deno.open(filename, w); const file = await Deno.open(filename, w);

View File

@ -88,7 +88,7 @@ unitTest(function formDataSetEmptyBlobSuccess(): void {
unitTest(function formDataParamsForEachSuccess(): void { unitTest(function formDataParamsForEachSuccess(): void {
const init = [ const init = [
["a", "54"], ["a", "54"],
["b", "true"] ["b", "true"],
]; ];
const formData = new FormData(); const formData = new FormData();
for (const [name, value] of init) { for (const [name, value] of init) {
@ -110,7 +110,7 @@ unitTest(function formDataParamsArgumentsCheck(): void {
"getAll", "getAll",
"get", "get",
"has", "has",
"forEach" "forEach",
] as const; ] as const;
const methodRequireTwoParams = ["append", "set"] as const; const methodRequireTwoParams = ["append", "set"] as const;

View File

@ -11,8 +11,8 @@ unitTest(function formatDiagnosticBasic() {
scriptResourceName: "foo.ts", scriptResourceName: "foo.ts",
startColumn: 1, startColumn: 1,
endColumn: 2, endColumn: 2,
code: 4000 code: 4000,
} },
]; ];
const out = Deno.formatDiagnostics(fixture); const out = Deno.formatDiagnostics(fixture);
assert(out.includes("Example error")); assert(out.includes("Example error"));

View File

@ -1,7 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts"; import { unitTest, assert, assertEquals } from "./test_util.ts";
const { const {
stringifyArgs stringifyArgs,
// @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol // @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol
} = Deno[Deno.symbols.internal]; } = Deno[Deno.symbols.internal];
@ -29,7 +29,7 @@ const headerDict: Record<string, string> = {
name3: "value3", name3: "value3",
// @ts-ignore // @ts-ignore
name4: undefined, name4: undefined,
"Content-Type": "value4" "Content-Type": "value4",
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const headerSeq: any[] = []; const headerSeq: any[] = [];
@ -142,7 +142,7 @@ const headerEntriesDict: Record<string, string> = {
name: "value3", name: "value3",
"content-Type": "value4", "content-Type": "value4",
"Content-Typ": "value5", "Content-Typ": "value5",
"Content-Types": "value6" "Content-Types": "value6",
}; };
unitTest(function headerForEachSuccess(): void { unitTest(function headerForEachSuccess(): void {
@ -346,7 +346,7 @@ unitTest(function customInspectReturnsCorrectHeadersFormat(): void {
); );
const multiParamHeader = new Headers([ const multiParamHeader = new Headers([
["Content-Type", "application/json"], ["Content-Type", "application/json"],
["Content-Length", "1337"] ["Content-Length", "1337"],
]); ]);
assertEquals( assertEquals(
stringify(multiParamHeader), stringify(multiParamHeader),

View File

@ -3,7 +3,7 @@ import { unitTest, assert } from "./test_util.ts";
unitTest(function internalsExists(): void { unitTest(function internalsExists(): void {
const { const {
stringifyArgs stringifyArgs,
// @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol // @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol
} = Deno[Deno.symbols.internal]; } = Deno[Deno.symbols.internal];
assert(!!stringifyArgs); assert(!!stringifyArgs);

View File

@ -3,7 +3,7 @@ import {
unitTest, unitTest,
assert, assert,
assertEquals, assertEquals,
createResolvable createResolvable,
} from "./test_util.ts"; } from "./test_util.ts";
unitTest({ perms: { net: true } }, function netTcpListenClose(): void { unitTest({ perms: { net: true } }, function netTcpListenClose(): void {
@ -18,13 +18,13 @@ unitTest(
{ {
perms: { net: true }, perms: { net: true },
// TODO: // TODO:
ignore: Deno.build.os === "win" ignore: Deno.build.os === "win",
}, },
function netUdpListenClose(): void { function netUdpListenClose(): void {
const socket = Deno.listen({ const socket = Deno.listen({
hostname: "127.0.0.1", hostname: "127.0.0.1",
port: 4500, port: 4500,
transport: "udp" transport: "udp",
}); });
assert(socket.addr.transport === "udp"); assert(socket.addr.transport === "udp");
assertEquals(socket.addr.hostname, "127.0.0.1"); assertEquals(socket.addr.hostname, "127.0.0.1");
@ -39,7 +39,7 @@ unitTest(
const filePath = Deno.makeTempFileSync(); const filePath = Deno.makeTempFileSync();
const socket = Deno.listen({ const socket = Deno.listen({
address: filePath, address: filePath,
transport: "unix" transport: "unix",
}); });
assert(socket.addr.transport === "unix"); assert(socket.addr.transport === "unix");
assertEquals(socket.addr.address, filePath); assertEquals(socket.addr.address, filePath);
@ -53,7 +53,7 @@ unitTest(
const filePath = Deno.makeTempFileSync(); const filePath = Deno.makeTempFileSync();
const socket = Deno.listen({ const socket = Deno.listen({
address: filePath, address: filePath,
transport: "unixpacket" transport: "unixpacket",
}); });
assert(socket.addr.transport === "unixpacket"); assert(socket.addr.transport === "unixpacket");
assertEquals(socket.addr.address, filePath); assertEquals(socket.addr.address, filePath);
@ -63,7 +63,7 @@ unitTest(
unitTest( unitTest(
{ {
perms: { net: true } perms: { net: true },
}, },
async function netTcpCloseWhileAccept(): Promise<void> { async function netTcpCloseWhileAccept(): Promise<void> {
const listener = Deno.listen({ port: 4501 }); const listener = Deno.listen({ port: 4501 });
@ -87,7 +87,7 @@ unitTest(
const filePath = await Deno.makeTempFile(); const filePath = await Deno.makeTempFile();
const listener = Deno.listen({ const listener = Deno.listen({
address: filePath, address: filePath,
transport: "unix" transport: "unix",
}); });
const p = listener.accept(); const p = listener.accept();
listener.close(); listener.close();
@ -337,7 +337,7 @@ unitTest(
{ {
// FIXME(bartlomieju) // FIXME(bartlomieju)
ignore: true, ignore: true,
perms: { net: true } perms: { net: true },
}, },
async function netListenAsyncIterator(): Promise<void> { async function netListenAsyncIterator(): Promise<void> {
const addr = { hostname: "127.0.0.1", port: 4500 }; const addr = { hostname: "127.0.0.1", port: 4500 };
@ -372,14 +372,14 @@ unitTest(
{ {
// FIXME(bartlomieju) // FIXME(bartlomieju)
ignore: true, ignore: true,
perms: { net: true } perms: { net: true },
}, },
async function netCloseReadSuccess() { async function netCloseReadSuccess() {
const addr = { hostname: "127.0.0.1", port: 4500 }; const addr = { hostname: "127.0.0.1", port: 4500 };
const listener = Deno.listen(addr); const listener = Deno.listen(addr);
const closeDeferred = createResolvable(); const closeDeferred = createResolvable();
const closeReadDeferred = createResolvable(); const closeReadDeferred = createResolvable();
listener.accept().then(async conn => { listener.accept().then(async (conn) => {
await closeReadDeferred; await closeReadDeferred;
await conn.write(new Uint8Array([1, 2, 3])); await conn.write(new Uint8Array([1, 2, 3]));
const buf = new Uint8Array(1024); const buf = new Uint8Array(1024);
@ -409,13 +409,13 @@ unitTest(
{ {
// FIXME(bartlomieju) // FIXME(bartlomieju)
ignore: true, ignore: true,
perms: { net: true } perms: { net: true },
}, },
async function netDoubleCloseRead() { async function netDoubleCloseRead() {
const addr = { hostname: "127.0.0.1", port: 4500 }; const addr = { hostname: "127.0.0.1", port: 4500 };
const listener = Deno.listen(addr); const listener = Deno.listen(addr);
const closeDeferred = createResolvable(); const closeDeferred = createResolvable();
listener.accept().then(async conn => { listener.accept().then(async (conn) => {
await conn.write(new Uint8Array([1, 2, 3])); await conn.write(new Uint8Array([1, 2, 3]));
await closeDeferred; await closeDeferred;
conn.close(); conn.close();
@ -441,13 +441,13 @@ unitTest(
{ {
// FIXME(bartlomieju) // FIXME(bartlomieju)
ignore: true, ignore: true,
perms: { net: true } perms: { net: true },
}, },
async function netCloseWriteSuccess() { async function netCloseWriteSuccess() {
const addr = { hostname: "127.0.0.1", port: 4500 }; const addr = { hostname: "127.0.0.1", port: 4500 };
const listener = Deno.listen(addr); const listener = Deno.listen(addr);
const closeDeferred = createResolvable(); const closeDeferred = createResolvable();
listener.accept().then(async conn => { listener.accept().then(async (conn) => {
await conn.write(new Uint8Array([1, 2, 3])); await conn.write(new Uint8Array([1, 2, 3]));
await closeDeferred; await closeDeferred;
conn.close(); conn.close();
@ -480,13 +480,13 @@ unitTest(
{ {
// FIXME(bartlomieju) // FIXME(bartlomieju)
ignore: true, ignore: true,
perms: { net: true } perms: { net: true },
}, },
async function netDoubleCloseWrite() { async function netDoubleCloseWrite() {
const addr = { hostname: "127.0.0.1", port: 4500 }; const addr = { hostname: "127.0.0.1", port: 4500 };
const listener = Deno.listen(addr); const listener = Deno.listen(addr);
const closeDeferred = createResolvable(); const closeDeferred = createResolvable();
listener.accept().then(async conn => { listener.accept().then(async (conn) => {
await closeDeferred; await closeDeferred;
conn.close(); conn.close();
}); });
@ -509,7 +509,7 @@ unitTest(
unitTest( unitTest(
{ {
perms: { net: true } perms: { net: true },
}, },
async function netHangsOnClose() { async function netHangsOnClose() {
let acceptedConn: Deno.Conn; let acceptedConn: Deno.Conn;

View File

@ -4,7 +4,7 @@ import {
assertEquals, assertEquals,
assertNotEquals, assertNotEquals,
assertThrows, assertThrows,
unitTest unitTest,
} from "./test_util.ts"; } from "./test_util.ts";
unitTest({ perms: { env: true } }, function envSuccess(): void { unitTest({ perms: { env: true } }, function envSuccess(): void {
@ -67,7 +67,7 @@ unitTest(
const proc = Deno.run({ const proc = Deno.run({
cmd: [Deno.execPath(), "eval", src], cmd: [Deno.execPath(), "eval", src],
env: inputEnv, env: inputEnv,
stdout: "piped" stdout: "piped",
}); });
const status = await proc.status(); const status = await proc.status();
assertEquals(status.success, true); assertEquals(status.success, true);
@ -134,121 +134,121 @@ unitTest({ perms: { env: true } }, function getDir(): void {
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: true } { os: "linux", shouldHaveValue: true },
] ],
}, },
{ {
kind: "cache", kind: "cache",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: true } { os: "linux", shouldHaveValue: true },
] ],
}, },
{ {
kind: "executable", kind: "executable",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: false }, { os: "mac", shouldHaveValue: false },
{ os: "win", shouldHaveValue: false }, { os: "win", shouldHaveValue: false },
{ os: "linux", shouldHaveValue: true } { os: "linux", shouldHaveValue: true },
] ],
}, },
{ {
kind: "data", kind: "data",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: true } { os: "linux", shouldHaveValue: true },
] ],
}, },
{ {
kind: "data_local", kind: "data_local",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: true } { os: "linux", shouldHaveValue: true },
] ],
}, },
{ {
kind: "audio", kind: "audio",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false } { os: "linux", shouldHaveValue: false },
] ],
}, },
{ {
kind: "desktop", kind: "desktop",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false } { os: "linux", shouldHaveValue: false },
] ],
}, },
{ {
kind: "document", kind: "document",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false } { os: "linux", shouldHaveValue: false },
] ],
}, },
{ {
kind: "download", kind: "download",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false } { os: "linux", shouldHaveValue: false },
] ],
}, },
{ {
kind: "font", kind: "font",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: false }, { os: "win", shouldHaveValue: false },
{ os: "linux", shouldHaveValue: true } { os: "linux", shouldHaveValue: true },
] ],
}, },
{ {
kind: "picture", kind: "picture",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false } { os: "linux", shouldHaveValue: false },
] ],
}, },
{ {
kind: "public", kind: "public",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false } { os: "linux", shouldHaveValue: false },
] ],
}, },
{ {
kind: "template", kind: "template",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: false }, { os: "mac", shouldHaveValue: false },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false } { os: "linux", shouldHaveValue: false },
] ],
}, },
{ {
kind: "tmp", kind: "tmp",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: true } { os: "linux", shouldHaveValue: true },
] ],
}, },
{ {
kind: "video", kind: "video",
runtime: [ runtime: [
{ os: "mac", shouldHaveValue: true }, { os: "mac", shouldHaveValue: true },
{ os: "win", shouldHaveValue: true }, { os: "win", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false } { os: "linux", shouldHaveValue: false },
] ],
} },
]; ];
for (const s of scenes) { for (const s of scenes) {

View File

@ -3,7 +3,7 @@ import {
assert, assert,
assertEquals, assertEquals,
assertStrContains, assertStrContains,
unitTest unitTest,
} from "./test_util.ts"; } from "./test_util.ts";
const { kill, run, readFile, open, makeTempDir, writeFile } = Deno; const { kill, run, readFile, open, makeTempDir, writeFile } = Deno;
@ -22,7 +22,7 @@ unitTest({ perms: { run: true } }, async function runSuccess(): Promise<void> {
const p = run({ const p = run({
cmd: ["python", "-c", "print('hello world')"], cmd: ["python", "-c", "print('hello world')"],
stdout: "piped", stdout: "piped",
stderr: "null" stderr: "null",
}); });
const status = await p.status(); const status = await p.status();
assertEquals(status.success, true); assertEquals(status.success, true);
@ -36,7 +36,7 @@ unitTest(
{ perms: { run: true } }, { perms: { run: true } },
async function runCommandFailedWithCode(): Promise<void> { async function runCommandFailedWithCode(): Promise<void> {
const p = run({ 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(); const status = await p.status();
assertEquals(status.success, false); assertEquals(status.success, false);
@ -50,11 +50,11 @@ unitTest(
{ {
// No signals on windows. // No signals on windows.
ignore: Deno.build.os === "win", ignore: Deno.build.os === "win",
perms: { run: true } perms: { run: true },
}, },
async function runCommandFailedWithSignal(): Promise<void> { async function runCommandFailedWithSignal(): Promise<void> {
const p = run({ 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(); const status = await p.status();
assertEquals(status.success, false); assertEquals(status.success, false);
@ -102,7 +102,7 @@ while True:
Deno.writeFileSync(`${cwd}/${pyProgramFile}.py`, enc.encode(pyProgram)); Deno.writeFileSync(`${cwd}/${pyProgramFile}.py`, enc.encode(pyProgram));
const p = run({ const p = run({
cwd, cwd,
cmd: ["python", `${pyProgramFile}.py`] cmd: ["python", `${pyProgramFile}.py`],
}); });
// Write the expected exit code *after* starting python. // Write the expected exit code *after* starting python.
@ -123,7 +123,7 @@ unitTest({ perms: { run: true } }, async function runStdinPiped(): Promise<
> { > {
const p = run({ const p = run({
cmd: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"], cmd: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"],
stdin: "piped" stdin: "piped",
}); });
assert(p.stdin); assert(p.stdin);
assert(!p.stdout); assert(!p.stdout);
@ -147,7 +147,7 @@ unitTest({ perms: { run: true } }, async function runStdoutPiped(): Promise<
> { > {
const p = run({ const p = run({
cmd: ["python", "-c", "import sys; sys.stdout.write('hello')"], cmd: ["python", "-c", "import sys; sys.stdout.write('hello')"],
stdout: "piped" stdout: "piped",
}); });
assert(!p.stdin); assert(!p.stdin);
assert(!p.stderr); assert(!p.stderr);
@ -176,7 +176,7 @@ unitTest({ perms: { run: true } }, async function runStderrPiped(): Promise<
> { > {
const p = run({ const p = run({
cmd: ["python", "-c", "import sys; sys.stderr.write('hello')"], cmd: ["python", "-c", "import sys; sys.stderr.write('hello')"],
stderr: "piped" stderr: "piped",
}); });
assert(!p.stdin); assert(!p.stdin);
assert(!p.stdout); assert(!p.stdout);
@ -203,7 +203,7 @@ unitTest({ perms: { run: true } }, async function runStderrPiped(): Promise<
unitTest({ perms: { run: true } }, async function runOutput(): Promise<void> { unitTest({ perms: { run: true } }, async function runOutput(): Promise<void> {
const p = run({ const p = run({
cmd: ["python", "-c", "import sys; sys.stdout.write('hello')"], cmd: ["python", "-c", "import sys; sys.stdout.write('hello')"],
stdout: "piped" stdout: "piped",
}); });
const output = await p.output(); const output = await p.output();
const s = new TextDecoder().decode(output); const s = new TextDecoder().decode(output);
@ -216,7 +216,7 @@ unitTest({ perms: { run: true } }, async function runStderrOutput(): Promise<
> { > {
const p = run({ const p = run({
cmd: ["python", "-c", "import sys; sys.stderr.write('error')"], cmd: ["python", "-c", "import sys; sys.stderr.write('error')"],
stderr: "piped" stderr: "piped",
}); });
const error = await p.stderrOutput(); const error = await p.stderrOutput();
const s = new TextDecoder().decode(error); const s = new TextDecoder().decode(error);
@ -235,10 +235,10 @@ unitTest(
cmd: [ cmd: [
"python", "python",
"-c", "-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, stdout: file.rid,
stderr: file.rid stderr: file.rid,
}); });
await p.status(); await p.status();
@ -265,7 +265,7 @@ unitTest(
const p = run({ const p = run({
cmd: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"], cmd: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"],
stdin: file.rid stdin: file.rid,
}); });
const status = await p.status(); const status = await p.status();
@ -280,13 +280,13 @@ unitTest({ perms: { run: true } }, async function runEnv(): Promise<void> {
cmd: [ cmd: [
"python", "python",
"-c", "-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: { env: {
FOO: "0123", FOO: "0123",
BAR: "4567" BAR: "4567",
}, },
stdout: "piped" stdout: "piped",
}); });
const output = await p.output(); const output = await p.output();
const s = new TextDecoder().decode(output); const s = new TextDecoder().decode(output);
@ -299,9 +299,9 @@ unitTest({ perms: { run: true } }, async function runClose(): Promise<void> {
cmd: [ cmd: [
"python", "python",
"-c", "-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.stdin);
assert(!p.stdout); assert(!p.stdout);
@ -343,7 +343,7 @@ if (Deno.build.os !== "win") {
void void
> { > {
const p = run({ 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); assertEquals(Deno.Signal.SIGINT, 2);
@ -361,7 +361,7 @@ if (Deno.build.os !== "win") {
unitTest({ perms: { run: true } }, function killFailed(): void { unitTest({ perms: { run: true } }, function killFailed(): void {
const p = run({ 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.stdin);
assert(!p.stdout); assert(!p.stdout);

View File

@ -15,7 +15,7 @@ unitTest({ perms: { read: true } }, function realpathSyncSuccess(): void {
unitTest( unitTest(
{ {
ignore: Deno.build.os === "win", ignore: Deno.build.os === "win",
perms: { read: true, write: true } perms: { read: true, write: true },
}, },
function realpathSyncSymlink(): void { function realpathSyncSymlink(): void {
const testDir = Deno.makeTempDirSync(); const testDir = Deno.makeTempDirSync();
@ -67,7 +67,7 @@ unitTest({ perms: { read: true } }, async function realpathSuccess(): Promise<
unitTest( unitTest(
{ {
ignore: Deno.build.os === "win", ignore: Deno.build.os === "win",
perms: { read: true, write: true } perms: { read: true, write: true },
}, },
async function realpathSymlink(): Promise<void> { async function realpathSymlink(): Promise<void> {
const testDir = Deno.makeTempDirSync(); const testDir = Deno.makeTempDirSync();

View File

@ -6,8 +6,8 @@ unitTest(function fromInit(): void {
body: "ahoyhoy", body: "ahoyhoy",
method: "POST", method: "POST",
headers: { headers: {
"test-header": "value" "test-header": "value",
} },
}); });
// @ts-ignore // @ts-ignore
@ -34,7 +34,7 @@ unitTest(async function cloneRequestBodyStream(): Promise<void> {
// hack to get a stream // hack to get a stream
const stream = new Request("", { body: "a test body" }).body; const stream = new Request("", { body: "a test body" }).body;
const r1 = new Request("https://example.com", { const r1 = new Request("https://example.com", {
body: stream body: stream,
}); });
const r2 = r1.clone(); const r2 = r1.clone();

View File

@ -4,7 +4,7 @@ import {
assert, assert,
assertEquals, assertEquals,
assertThrows, assertThrows,
createResolvable createResolvable,
} from "./test_util.ts"; } from "./test_util.ts";
function defer(n: number): Promise<void> { function defer(n: number): Promise<void> {

View File

@ -10,7 +10,7 @@ export {
assertStrictEq, assertStrictEq,
assertStrContains, assertStrContains,
unreachable, unreachable,
fail fail,
} from "../../../std/testing/asserts.ts"; } from "../../../std/testing/asserts.ts";
export { readLines } from "../../../std/io/bufio.ts"; export { readLines } from "../../../std/io/bufio.ts";
export { parse as parseArgs } from "../../../std/flags/mod.ts"; export { parse as parseArgs } from "../../../std/flags/mod.ts";
@ -28,7 +28,7 @@ export interface Permissions {
export function fmtPerms(perms: Permissions): string { export function fmtPerms(perms: Permissions): string {
const p = Object.keys(perms) const p = Object.keys(perms)
.filter((e): boolean => perms[e as keyof Permissions] === true) .filter((e): boolean => perms[e as keyof Permissions] === true)
.map(key => `--allow-${key}`); .map((key) => `--allow-${key}`);
if (p.length) { if (p.length) {
return p.join(" "); return p.join(" ");
@ -48,7 +48,7 @@ export async function getProcessPermissions(): Promise<Permissions> {
net: await isGranted("net"), net: await isGranted("net"),
env: await isGranted("env"), env: await isGranted("env"),
plugin: await isGranted("plugin"), plugin: await isGranted("plugin"),
hrtime: await isGranted("hrtime") hrtime: await isGranted("hrtime"),
}; };
} }
@ -108,7 +108,7 @@ function normalizeTestPermissions(perms: UnitTestPermissions): Permissions {
run: !!perms.run, run: !!perms.run,
env: !!perms.env, env: !!perms.env,
plugin: !!perms.plugin, plugin: !!perms.plugin,
hrtime: !!perms.hrtime hrtime: !!perms.hrtime,
}; };
} }
@ -170,7 +170,7 @@ export function unitTest(
name, name,
fn, fn,
ignore: !!options.ignore, ignore: !!options.ignore,
perms: normalizedPerms perms: normalizedPerms,
}; };
REGISTERED_UNIT_TESTS.push(unitTestDefinition); REGISTERED_UNIT_TESTS.push(unitTestDefinition);
@ -194,17 +194,19 @@ export function createResolvable<T>(): Resolvable<T> {
return Object.assign(promise, methods!) as Resolvable<T>; return Object.assign(promise, methods!) as Resolvable<T>;
} }
export class SocketReporter implements Deno.TestReporter { const encoder = new TextEncoder();
private encoder: TextEncoder;
constructor(private conn: Deno.Conn) { export class SocketReporter implements Deno.TestReporter {
this.encoder = new TextEncoder(); #conn: Deno.Conn;
constructor(conn: Deno.Conn) {
this.#conn = conn;
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
async write(msg: any): Promise<void> { async write(msg: any): Promise<void> {
const encodedMsg = this.encoder.encode(JSON.stringify(msg) + "\n"); const encodedMsg = encoder.encode(JSON.stringify(msg) + "\n");
await Deno.writeAll(this.conn, encodedMsg); await Deno.writeAll(this.#conn, encodedMsg);
} }
async start(msg: Deno.TestEventStart): Promise<void> { async start(msg: Deno.TestEventStart): Promise<void> {
@ -229,9 +231,9 @@ export class SocketReporter implements Deno.TestReporter {
} }
async end(msg: Deno.TestEventEnd): Promise<void> { async end(msg: Deno.TestEventEnd): Promise<void> {
const encodedMsg = this.encoder.encode(JSON.stringify(msg)); const encodedMsg = encoder.encode(JSON.stringify(msg));
await Deno.writeAll(this.conn, encodedMsg); await Deno.writeAll(this.#conn, encodedMsg);
this.conn.closeWrite(); this.#conn.closeWrite();
} }
} }
@ -245,7 +247,7 @@ unitTest(function permissionsMatches(): void {
env: false, env: false,
run: false, run: false,
plugin: false, plugin: false,
hrtime: false hrtime: false,
}, },
normalizeTestPermissions({ read: true }) normalizeTestPermissions({ read: true })
) )
@ -260,7 +262,7 @@ unitTest(function permissionsMatches(): void {
env: false, env: false,
run: false, run: false,
plugin: false, plugin: false,
hrtime: false hrtime: false,
}, },
normalizeTestPermissions({}) normalizeTestPermissions({})
) )
@ -275,7 +277,7 @@ unitTest(function permissionsMatches(): void {
env: true, env: true,
run: true, run: true,
plugin: true, plugin: true,
hrtime: true hrtime: true,
}, },
normalizeTestPermissions({ read: true }) normalizeTestPermissions({ read: true })
), ),
@ -291,7 +293,7 @@ unitTest(function permissionsMatches(): void {
env: false, env: false,
run: false, run: false,
plugin: false, plugin: false,
hrtime: false hrtime: false,
}, },
normalizeTestPermissions({ read: true }) normalizeTestPermissions({ read: true })
), ),
@ -307,7 +309,7 @@ unitTest(function permissionsMatches(): void {
env: true, env: true,
run: true, run: true,
plugin: true, plugin: true,
hrtime: true hrtime: true,
}, },
{ {
read: true, read: true,
@ -316,7 +318,7 @@ unitTest(function permissionsMatches(): void {
env: true, env: true,
run: true, run: true,
plugin: true, plugin: true,
hrtime: true hrtime: true,
} }
) )
); );
@ -330,9 +332,9 @@ unitTest(
{ perms: { read: true } }, { perms: { read: true } },
function assertAllUnitTestFilesImported(): void { function assertAllUnitTestFilesImported(): void {
const directoryTestFiles = Deno.readdirSync("./cli/js/tests/") const directoryTestFiles = Deno.readdirSync("./cli/js/tests/")
.map(k => k.name) .map((k) => k.name)
.filter( .filter(
file => (file) =>
file!.endsWith(".ts") && file!.endsWith(".ts") &&
!file!.endsWith("unit_tests.ts") && !file!.endsWith("unit_tests.ts") &&
!file!.endsWith("test_util.ts") && !file!.endsWith("test_util.ts") &&
@ -344,12 +346,12 @@ unitTest(
const importLines = new TextDecoder("utf-8") const importLines = new TextDecoder("utf-8")
.decode(unitTestsFile) .decode(unitTestsFile)
.split("\n") .split("\n")
.filter(line => line.startsWith("import")); .filter((line) => line.startsWith("import"));
const importedTestFiles = importLines.map( const importedTestFiles = importLines.map(
relativeFilePath => relativeFilePath.match(/\/([^\/]+)";/)![1] (relativeFilePath) => relativeFilePath.match(/\/([^\/]+)";/)![1]
); );
directoryTestFiles.forEach(dirFile => { directoryTestFiles.forEach((dirFile) => {
if (!importedTestFiles.includes(dirFile!)) { if (!importedTestFiles.includes(dirFile!)) {
throw new Error( throw new Error(
"cil/js/tests/unit_tests.ts is missing import of test file: cli/js/" + "cil/js/tests/unit_tests.ts is missing import of test file: cli/js/" +

View File

@ -18,7 +18,7 @@ unitTest(function nameOfTestCaseCantBeEmpty(): void {
() => { () => {
Deno.test({ Deno.test({
name: "", name: "",
fn: () => {} fn: () => {},
}); });
}, },
TypeError, TypeError,
@ -29,7 +29,7 @@ unitTest(function nameOfTestCaseCantBeEmpty(): void {
unitTest(function testFnCantBeAnonymous(): void { unitTest(function testFnCantBeAnonymous(): void {
assertThrows( assertThrows(
() => { () => {
Deno.test(function() {}); Deno.test(function () {});
}, },
TypeError, TypeError,
"The test function can't be anonymous" "The test function can't be anonymous"

View File

@ -21,7 +21,7 @@ unitTest(function atobWithAsciiWhitespace(): void {
"aGVsbG8gd29ybGQ=\n", "aGVsbG8gd29ybGQ=\n",
"aGVsbG\t8gd29ybGQ=", "aGVsbG\t8gd29ybGQ=",
`aGVsbG\t8g `aGVsbG\t8g
d29ybGQ=` d29ybGQ=`,
]; ];
for (const encoded of encodedList) { for (const encoded of encodedList) {

View File

@ -4,7 +4,7 @@ import {
createResolvable, createResolvable,
assert, assert,
assertEquals, assertEquals,
assertNotEquals assertNotEquals,
} from "./test_util.ts"; } from "./test_util.ts";
function deferred(): { function deferred(): {
@ -23,7 +23,7 @@ function deferred(): {
return { return {
promise, promise,
resolve: resolve!, resolve: resolve!,
reject: reject! reject: reject!,
}; };
} }
@ -180,7 +180,7 @@ unitTest(async function timeoutCallbackThis(): Promise<void> {
foo(): void { foo(): void {
assertEquals(this, window); assertEquals(this, window);
resolve(); resolve();
} },
}; };
setTimeout(obj.foo, 1); setTimeout(obj.foo, 1);
await promise; await promise;
@ -198,7 +198,7 @@ unitTest(async function timeoutBindThis(): Promise<void> {
[], [],
"foo", "foo",
(): void => {}, (): void => {},
Object.prototype Object.prototype,
]; ];
for (const thisArg of thisCheckPassed) { for (const thisArg of thisCheckPassed) {
@ -240,7 +240,7 @@ unitTest(function clearTimeoutShouldConvertToNumber(): void {
valueOf(): number { valueOf(): number {
called = true; called = true;
return 1; return 1;
} },
}; };
clearTimeout((obj as unknown) as number); clearTimeout((obj as unknown) as number);
assert(called); assert(called);

View File

@ -3,7 +3,7 @@ import {
assert, assert,
assertEquals, assertEquals,
createResolvable, createResolvable,
unitTest unitTest,
} from "./test_util.ts"; } from "./test_util.ts";
import { BufWriter, BufReader } from "../../../std/io/bufio.ts"; import { BufWriter, BufReader } from "../../../std/io/bufio.ts";
import { TextProtoReader } from "../../../std/textproto/mod.ts"; import { TextProtoReader } from "../../../std/textproto/mod.ts";
@ -28,7 +28,7 @@ unitTest(async function connectTLSCertFileNoReadPerm(): Promise<void> {
await Deno.connectTLS({ await Deno.connectTLS({
hostname: "github.com", hostname: "github.com",
port: 443, port: 443,
certFile: "cli/tests/tls/RootCA.crt" certFile: "cli/tests/tls/RootCA.crt",
}); });
} catch (e) { } catch (e) {
err = e; err = e;
@ -45,13 +45,13 @@ unitTest(
hostname: "localhost", hostname: "localhost",
port: 4500, port: 4500,
certFile: "cli/tests/tls/localhost.crt", certFile: "cli/tests/tls/localhost.crt",
keyFile: "cli/tests/tls/localhost.key" keyFile: "cli/tests/tls/localhost.key",
}; };
try { try {
Deno.listenTLS({ Deno.listenTLS({
...options, ...options,
certFile: "./non/existent/file" certFile: "./non/existent/file",
}); });
} catch (e) { } catch (e) {
err = e; err = e;
@ -61,7 +61,7 @@ unitTest(
try { try {
Deno.listenTLS({ Deno.listenTLS({
...options, ...options,
keyFile: "./non/existent/file" keyFile: "./non/existent/file",
}); });
} catch (e) { } catch (e) {
err = e; err = e;
@ -77,7 +77,7 @@ unitTest({ perms: { net: true } }, function listenTLSNoReadPerm(): void {
hostname: "localhost", hostname: "localhost",
port: 4500, port: 4500,
certFile: "cli/tests/tls/localhost.crt", certFile: "cli/tests/tls/localhost.crt",
keyFile: "cli/tests/tls/localhost.key" keyFile: "cli/tests/tls/localhost.key",
}); });
} catch (e) { } catch (e) {
err = e; err = e;
@ -88,7 +88,7 @@ unitTest({ perms: { net: true } }, function listenTLSNoReadPerm(): void {
unitTest( unitTest(
{ {
perms: { read: true, write: true, net: true } perms: { read: true, write: true, net: true },
}, },
function listenTLSEmptyKeyFile(): void { function listenTLSEmptyKeyFile(): void {
let err; let err;
@ -96,19 +96,19 @@ unitTest(
hostname: "localhost", hostname: "localhost",
port: 4500, port: 4500,
certFile: "cli/tests/tls/localhost.crt", certFile: "cli/tests/tls/localhost.crt",
keyFile: "cli/tests/tls/localhost.key" keyFile: "cli/tests/tls/localhost.key",
}; };
const testDir = Deno.makeTempDirSync(); const testDir = Deno.makeTempDirSync();
const keyFilename = testDir + "/key.pem"; const keyFilename = testDir + "/key.pem";
Deno.writeFileSync(keyFilename, new Uint8Array([]), { Deno.writeFileSync(keyFilename, new Uint8Array([]), {
mode: 0o666 mode: 0o666,
}); });
try { try {
Deno.listenTLS({ Deno.listenTLS({
...options, ...options,
keyFile: keyFilename keyFile: keyFilename,
}); });
} catch (e) { } catch (e) {
err = e; err = e;
@ -125,19 +125,19 @@ unitTest(
hostname: "localhost", hostname: "localhost",
port: 4500, port: 4500,
certFile: "cli/tests/tls/localhost.crt", certFile: "cli/tests/tls/localhost.crt",
keyFile: "cli/tests/tls/localhost.key" keyFile: "cli/tests/tls/localhost.key",
}; };
const testDir = Deno.makeTempDirSync(); const testDir = Deno.makeTempDirSync();
const certFilename = testDir + "/cert.crt"; const certFilename = testDir + "/cert.crt";
Deno.writeFileSync(certFilename, new Uint8Array([]), { Deno.writeFileSync(certFilename, new Uint8Array([]), {
mode: 0o666 mode: 0o666,
}); });
try { try {
Deno.listenTLS({ Deno.listenTLS({
...options, ...options,
certFile: certFilename certFile: certFilename,
}); });
} catch (e) { } catch (e) {
err = e; err = e;
@ -157,7 +157,7 @@ unitTest(
hostname, hostname,
port, port,
certFile: "cli/tests/tls/localhost.crt", certFile: "cli/tests/tls/localhost.crt",
keyFile: "cli/tests/tls/localhost.key" keyFile: "cli/tests/tls/localhost.key",
}); });
const response = encoder.encode( const response = encoder.encode(
@ -180,7 +180,7 @@ unitTest(
const conn = await Deno.connectTLS({ const conn = await Deno.connectTLS({
hostname, hostname,
port, port,
certFile: "cli/tests/tls/RootCA.pem" certFile: "cli/tests/tls/RootCA.pem",
}); });
assert(conn.rid > 0); assert(conn.rid > 0);
const w = new BufWriter(conn); const w = new BufWriter(conn);

View File

@ -3,7 +3,7 @@ import { unitTest, assertEquals } from "./test_util.ts";
unitTest( unitTest(
{ {
ignore: Deno.build.os === "win" ignore: Deno.build.os === "win",
}, },
function umaskSuccess(): void { function umaskSuccess(): void {
const prevMask = Deno.umask(0o020); const prevMask = Deno.umask(0o020);

View File

@ -8,7 +8,7 @@ import {
registerUnitTests, registerUnitTests,
SocketReporter, SocketReporter,
fmtPerms, fmtPerms,
parseArgs parseArgs,
} from "./test_util.ts"; } from "./test_util.ts";
interface PermissionSetTestResult { interface PermissionSetTestResult {
@ -27,7 +27,7 @@ const PERMISSIONS: Deno.PermissionName[] = [
"env", "env",
"run", "run",
"plugin", "plugin",
"hrtime" "hrtime",
]; ];
/** /**
@ -69,7 +69,7 @@ async function workerRunnerMain(
failFast: false, failFast: false,
exitOnFail: false, exitOnFail: false,
reporter: socketReporter, reporter: socketReporter,
only: filter only: filter,
}); });
} }
@ -93,7 +93,7 @@ function spawnWorkerRunner(
"cli/js/tests/unit_test_runner.ts", "cli/js/tests/unit_test_runner.ts",
"--worker", "--worker",
`--addr=${addr}`, `--addr=${addr}`,
`--perms=${permStr}` `--perms=${permStr}`,
]; ];
if (filter) { if (filter) {
@ -107,7 +107,7 @@ function spawnWorkerRunner(
cmd, cmd,
stdin: ioMode, stdin: ioMode,
stdout: ioMode, stdout: ioMode,
stderr: ioMode stderr: ioMode,
}); });
return p; return p;
@ -177,7 +177,7 @@ async function runTestsForPermissionSet(
permsStr: permsFmt, permsStr: permsFmt,
duration: endEvent.duration, duration: endEvent.duration,
stats: endEvent.stats, stats: endEvent.stats,
results: endEvent.results results: endEvent.results,
}; };
} }
@ -223,7 +223,7 @@ async function masterRunnerMain(
kind: Deno.TestEvent.End, kind: Deno.TestEvent.End,
stats, stats,
duration, duration,
results results,
}); });
testsPassed = testsPassed && testResult.passed; testsPassed = testsPassed && testResult.passed;
} }
@ -288,7 +288,7 @@ function assertOrHelp(expr: unknown): asserts expr {
async function main(): Promise<void> { async function main(): Promise<void> {
const args = parseArgs(Deno.args, { const args = parseArgs(Deno.args, {
boolean: ["master", "worker", "verbose"], boolean: ["master", "worker", "verbose"],
"--": true "--": true,
}); });
if (args.help) { if (args.help) {
@ -315,7 +315,7 @@ async function main(): Promise<void> {
await Deno.runTests({ await Deno.runTests({
failFast: false, failFast: false,
exitOnFail: true, exitOnFail: true,
only: filter only: filter,
}); });
} }

View File

@ -13,7 +13,7 @@ unitTest(function urlSearchParamsInitString(): void {
unitTest(function urlSearchParamsInitIterable(): void { unitTest(function urlSearchParamsInitIterable(): void {
const init = [ const init = [
["a", "54"], ["a", "54"],
["b", "true"] ["b", "true"],
]; ];
const searchParams = new URLSearchParams(init); const searchParams = new URLSearchParams(init);
assertEquals(searchParams.toString(), "a=54&b=true"); assertEquals(searchParams.toString(), "a=54&b=true");
@ -94,7 +94,7 @@ unitTest(function urlSearchParamsSortSuccess(): void {
unitTest(function urlSearchParamsForEachSuccess(): void { unitTest(function urlSearchParamsForEachSuccess(): void {
const init = [ const init = [
["a", "54"], ["a", "54"],
["b", "true"] ["b", "true"],
]; ];
const searchParams = new URLSearchParams(init); const searchParams = new URLSearchParams(init);
let callNum = 0; 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 // ref: https://github.com/web-platform-tests/wpt/blob/master/url/urlsearchparams-constructor.any.js#L176-L182
unitTest(function urlSearchParamsCustomSymbolIterator(): void { unitTest(function urlSearchParamsCustomSymbolIterator(): void {
const params = new URLSearchParams(); const params = new URLSearchParams();
params[Symbol.iterator] = function*(): IterableIterator<[string, string]> { params[Symbol.iterator] = function* (): IterableIterator<[string, string]> {
yield ["a", "b"]; yield ["a", "b"];
}; };
const params1 = new URLSearchParams((params as unknown) as string[][]); const params1 = new URLSearchParams((params as unknown) as string[][]);
@ -236,7 +236,7 @@ unitTest(
function urlSearchParamsCustomSymbolIteratorWithNonStringParams(): void { function urlSearchParamsCustomSymbolIteratorWithNonStringParams(): void {
const params = {}; const params = {};
// @ts-ignore // @ts-ignore
params[Symbol.iterator] = function*(): IterableIterator<[number, number]> { params[Symbol.iterator] = function* (): IterableIterator<[number, number]> {
yield [1, 2]; yield [1, 2];
}; };
const params1 = new URLSearchParams((params as unknown) as string[][]); const params1 = new URLSearchParams((params as unknown) as string[][]);

View File

@ -98,6 +98,12 @@ unitTest(function urlModifyHref(): void {
assertEquals(url.hash, "#qux"); 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 { unitTest(function urlModifyPathname(): void {
const url = new URL("http://foo.bar/baz%qat/qux%quux"); const url = new URL("http://foo.bar/baz%qat/qux%quux");
assertEquals(url.pathname, "/baz%qat/qux%quux"); assertEquals(url.pathname, "/baz%qat/qux%quux");
@ -183,7 +189,7 @@ unitTest(function sortingNonExistentParamRemovesQuestionMarkFromURL(): void {
unitTest( unitTest(
{ {
// FIXME(bartlomieju) // FIXME(bartlomieju)
ignore: true ignore: true,
}, },
function customInspectFunction(): void { function customInspectFunction(): void {
const url = new URL("http://example.com/?"); const url = new URL("http://example.com/?");

View File

@ -15,7 +15,7 @@ unitTest(
const testDir = Deno.makeTempDirSync(); const testDir = Deno.makeTempDirSync();
const filename = testDir + "/file.txt"; const filename = testDir + "/file.txt";
Deno.writeFileSync(filename, new TextEncoder().encode("hello"), { Deno.writeFileSync(filename, new TextEncoder().encode("hello"), {
mode: 0o666 mode: 0o666,
}); });
const atime = 1000; const atime = 1000;
@ -115,7 +115,7 @@ unitTest(
const testDir = Deno.makeTempDirSync(); const testDir = Deno.makeTempDirSync();
const filename = testDir + "/file.txt"; const filename = testDir + "/file.txt";
Deno.writeFileSync(filename, new TextEncoder().encode("hello"), { Deno.writeFileSync(filename, new TextEncoder().encode("hello"), {
mode: 0o666 mode: 0o666,
}); });
const atime = 1000; const atime = 1000;

View File

@ -15,13 +15,13 @@ export async function connectTLS({
port, port,
hostname = "127.0.0.1", hostname = "127.0.0.1",
transport = "tcp", transport = "tcp",
certFile = undefined certFile = undefined,
}: ConnectTLSOptions): Promise<Conn> { }: ConnectTLSOptions): Promise<Conn> {
const res = await tlsOps.connectTLS({ const res = await tlsOps.connectTLS({
port, port,
hostname, hostname,
transport, transport,
certFile certFile,
}); });
return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!); return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!);
} }
@ -46,14 +46,14 @@ export function listenTLS({
certFile, certFile,
keyFile, keyFile,
hostname = "0.0.0.0", hostname = "0.0.0.0",
transport = "tcp" transport = "tcp",
}: ListenTLSOptions): Listener { }: ListenTLSOptions): Listener {
const res = tlsOps.listenTLS({ const res = tlsOps.listenTLS({
port, port,
certFile, certFile,
keyFile, keyFile,
hostname, hostname,
transport transport,
}); });
return new TLSListenerImpl(res.rid, res.localAddr); return new TLSListenerImpl(res.rid, res.localAddr);
} }

View File

@ -67,6 +67,6 @@ export function immutableDefine(
Object.defineProperty(o, p, { Object.defineProperty(o, p, {
value, value,
configurable: false, configurable: false,
writable: false writable: false,
}); });
} }

View File

@ -8,7 +8,7 @@ interface Version {
export const version: Version = { export const version: Version = {
deno: "", deno: "",
v8: "", v8: "",
typescript: "" typescript: "",
}; };
export function setVersions( export function setVersions(

View File

@ -124,12 +124,8 @@ function processBlobParts(
return bytes; 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 { export class DenoBlob implements domTypes.Blob {
private readonly [bytesSymbol]: Uint8Array; [bytesSymbol]: Uint8Array;
readonly size: number = 0; readonly size: number = 0;
readonly type: string = ""; readonly type: string = "";
@ -165,14 +161,11 @@ export class DenoBlob implements domTypes.Blob {
this[bytesSymbol] = bytes; this[bytesSymbol] = bytes;
this.size = bytes.byteLength; this.size = bytes.byteLength;
this.type = normalizedType; this.type = normalizedType;
// Register bytes for internal private use.
blobBytesWeakMap.set(this, bytes);
} }
slice(start?: number, end?: number, contentType?: string): DenoBlob { slice(start?: number, end?: number, contentType?: string): DenoBlob {
return new DenoBlob([this[bytesSymbol].slice(start, end)], { return new DenoBlob([this[bytesSymbol].slice(start, end)], {
type: contentType || this.type type: contentType || this.type,
}); });
} }
} }

View File

@ -124,7 +124,7 @@ export const BodyUsedError =
"Failed to execute 'clone' on 'Body': body is already used"; "Failed to execute 'clone' on 'Body': body is already used";
export class Body implements domTypes.Body { 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) { constructor(protected _bodySource: BodySource, readonly contentType: string) {
validateBodyType(this, _bodySource); validateBodyType(this, _bodySource);
@ -148,8 +148,8 @@ export class Body implements domTypes.Body {
start(controller: ReadableStreamController): void { start(controller: ReadableStreamController): void {
controller.enqueue(bodySource); controller.enqueue(bodySource);
controller.close(); controller.close();
} },
}); }) as domTypes.ReadableStream<ArrayBuffer | string>;
} }
return this._stream; return this._stream;
} }
@ -247,7 +247,7 @@ export class Body implements domTypes.Body {
if (dispositionParams.has("filename")) { if (dispositionParams.has("filename")) {
const filename = dispositionParams.get("filename")!; const filename = dispositionParams.get("filename")!;
const blob = new DenoBlob([enc.encode(octets)], { const blob = new DenoBlob([enc.encode(octets)], {
type: partContentType type: partContentType,
}); });
// TODO: based on spec // TODO: based on spec
// https://xhr.spec.whatwg.org/#dom-formdata-append // https://xhr.spec.whatwg.org/#dom-formdata-append

View File

@ -174,7 +174,7 @@ function createArrayString(
displayName: "", displayName: "",
delims: ["[", "]"], delims: ["[", "]"],
entryHandler: (el, ctx, level, maxLevel): string => 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); return createIterableString(value, ctx, level, maxLevel, printConfig);
} }
@ -191,7 +191,7 @@ function createTypedArrayString(
displayName: typedArrayName, displayName: typedArrayName,
delims: ["[", "]"], delims: ["[", "]"],
entryHandler: (el, ctx, level, maxLevel): string => 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); return createIterableString(value, ctx, level, maxLevel, printConfig);
} }
@ -207,7 +207,7 @@ function createSetString(
displayName: "Set", displayName: "Set",
delims: ["{", "}"], delims: ["{", "}"],
entryHandler: (el, ctx, level, maxLevel): string => 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); return createIterableString(value, ctx, level, maxLevel, printConfig);
} }
@ -230,7 +230,7 @@ function createMapString(
level + 1, level + 1,
maxLevel maxLevel
)} => ${stringifyWithQuotes(val, ctx, level + 1, maxLevel)}`; )} => ${stringifyWithQuotes(val, ctx, level + 1, maxLevel)}`;
} },
}; };
return createIterableString(value, ctx, level, maxLevel, printConfig); return createIterableString(value, ctx, level, maxLevel, printConfig);
} }
@ -494,10 +494,12 @@ const timerMap = new Map<string, number>();
const isConsoleInstance = Symbol("isConsoleInstance"); const isConsoleInstance = Symbol("isConsoleInstance");
export class Console { export class Console {
#printFunc: PrintFunc;
indentLevel: number; indentLevel: number;
[isConsoleInstance] = false; [isConsoleInstance] = false;
constructor(private printFunc: PrintFunc) { constructor(printFunc: PrintFunc) {
this.#printFunc = printFunc;
this.indentLevel = 0; this.indentLevel = 0;
this[isConsoleInstance] = true; this[isConsoleInstance] = true;
@ -511,9 +513,9 @@ export class Console {
} }
log = (...args: unknown[]): void => { log = (...args: unknown[]): void => {
this.printFunc( this.#printFunc(
stringifyArgs(args, { stringifyArgs(args, {
indentLevel: this.indentLevel indentLevel: this.indentLevel,
}) + "\n", }) + "\n",
false false
); );
@ -523,15 +525,15 @@ export class Console {
info = this.log; info = this.log;
dir = (obj: unknown, options: InspectOptions = {}): void => { dir = (obj: unknown, options: InspectOptions = {}): void => {
this.printFunc(stringifyArgs([obj], options) + "\n", false); this.#printFunc(stringifyArgs([obj], options) + "\n", false);
}; };
dirxml = this.dir; dirxml = this.dir;
warn = (...args: unknown[]): void => { warn = (...args: unknown[]): void => {
this.printFunc( this.#printFunc(
stringifyArgs(args, { stringifyArgs(args, {
indentLevel: this.indentLevel indentLevel: this.indentLevel,
}) + "\n", }) + "\n",
true true
); );
@ -604,7 +606,7 @@ export class Console {
this.log(cliTable(header, body)); this.log(cliTable(header, body));
const createColumn = (value: unknown, shift?: number): string[] => [ const createColumn = (value: unknown, shift?: number): string[] => [
...(shift ? [...new Array(shift)].map((): string => "") : []), ...(shift ? [...new Array(shift)].map((): string => "") : []),
stringifyValue(value) stringifyValue(value),
]; ];
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -660,8 +662,8 @@ export class Console {
indexKey, indexKey,
...(properties || [ ...(properties || [
...headerKeys, ...headerKeys,
!isMap && values.length > 0 && valuesKey !isMap && values.length > 0 && valuesKey,
]) ]),
].filter(Boolean) as string[]; ].filter(Boolean) as string[];
const body = [indexKeys, ...bodyValues, values]; const body = [indexKeys, ...bodyValues, values];
@ -733,7 +735,7 @@ export class Console {
const message = stringifyArgs(args, { indentLevel: 0 }); const message = stringifyArgs(args, { indentLevel: 0 });
const err = { const err = {
name: "Trace", name: "Trace",
message message,
}; };
// @ts-ignore // @ts-ignore
Error.captureStackTrace(err, this.trace); Error.captureStackTrace(err, this.trace);

View File

@ -19,7 +19,7 @@ const tableChars = {
rightMiddle: "┤", rightMiddle: "┤",
left: "│ ", left: "│ ",
right: " │", right: " │",
middle: " │ " middle: " │ ",
}; };
const colorRegExp = /\u001b\[\d\d?m/g; const colorRegExp = /\u001b\[\d\d?m/g;

View File

@ -1,32 +1,31 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import * as domTypes from "./dom_types.ts"; import * as domTypes from "./dom_types.ts";
import * as event from "./event.ts"; import * as event from "./event.ts";
import { getPrivateValue, requiredArguments } from "./util.ts"; import { 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();
export class CustomEvent extends event.Event implements domTypes.CustomEvent { export class CustomEvent extends event.Event implements domTypes.CustomEvent {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
#detail: any;
constructor( constructor(
type: string, type: string,
customEventInitDict: domTypes.CustomEventInit = {} customEventInitDict: domTypes.CustomEventInit = {}
) { ) {
requiredArguments("CustomEvent", arguments.length, 1);
super(type, customEventInitDict); super(type, customEventInitDict);
requiredArguments("CustomEvent", arguments.length, 1);
const { detail = null } = customEventInitDict; const { detail = null } = customEventInitDict;
customEventAttributes.set(this, { detail }); this.#detail = detail;
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
get detail(): any { get detail(): any {
return getPrivateValue(this, customEventAttributes, "detail"); return this.#detail;
} }
initCustomEvent( initCustomEvent(
type: string, _type: string,
bubbles?: boolean, _bubbles?: boolean,
cancelable?: boolean, _cancelable?: boolean,
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
detail?: any detail?: any
): void { ): void {
@ -34,7 +33,7 @@ export class CustomEvent extends event.Event implements domTypes.CustomEvent {
return; return;
} }
customEventAttributes.set(this, { detail }); this.#detail = detail;
} }
get [Symbol.toStringTag](): string { get [Symbol.toStringTag](): string {

View File

@ -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. // we want the Base class name to be the name of the class.
Object.defineProperty(DomIterable, "name", { Object.defineProperty(DomIterable, "name", {
value: Base.name, value: Base.name,
configurable: true configurable: true,
}); });
return DomIterable; return DomIterable;

View File

@ -68,7 +68,7 @@ interface AbortSignalEventMap {
export enum NodeType { export enum NodeType {
ELEMENT_NODE = 1, ELEMENT_NODE = 1,
TEXT_NODE = 3, TEXT_NODE = 3,
DOCUMENT_FRAGMENT_NODE = 11 DOCUMENT_FRAGMENT_NODE = 11,
} }
export const eventTargetHost: unique symbol = Symbol(); export const eventTargetHost: unique symbol = Symbol();
@ -153,7 +153,7 @@ export enum EventPhase {
NONE = 0, NONE = 0,
CAPTURING_PHASE = 1, CAPTURING_PHASE = 1,
AT_TARGET = 2, AT_TARGET = 2,
BUBBLING_PHASE = 3 BUBBLING_PHASE = 3,
} }
export interface EventPath { export interface EventPath {
@ -280,7 +280,7 @@ export interface Blob {
} }
export interface Body { export interface Body {
readonly body: ReadableStream | null; readonly body: ReadableStream<Uint8Array> | null;
readonly bodyUsed: boolean; readonly bodyUsed: boolean;
arrayBuffer(): Promise<ArrayBuffer>; arrayBuffer(): Promise<ArrayBuffer>;
blob(): Promise<Blob>; blob(): Promise<Blob>;
@ -289,11 +289,78 @@ export interface Body {
text(): Promise<string>; 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; readonly locked: boolean;
cancel(reason?: any): Promise<void>; cancel(reason?: any): Promise<void>;
getReader(): ReadableStreamReader; getReader(options: { mode: "byob" }): ReadableStreamBYOBReader;
tee(): ReadableStream[]; 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> { export interface UnderlyingSource<R = any> {
@ -311,9 +378,9 @@ export interface UnderlyingByteSource {
type: "bytes"; type: "bytes";
} }
export interface ReadableStreamReader { export interface ReadableStreamReader<R = any> {
cancel(reason?: any): Promise<void>; cancel(reason: any): Promise<void>;
read(): Promise<any>; read(): Promise<ReadableStreamReadResult<R>>;
releaseLock(): void; releaseLock(): void;
} }
@ -530,12 +597,20 @@ export interface Response extends Body {
clone(): Response; clone(): Response;
} }
export interface DOMStringList {
readonly length: number;
contains(string: string): boolean;
item(index: number): string | null;
[index: number]: string;
}
export interface Location { export interface Location {
readonly ancestorOrigins: string[]; readonly ancestorOrigins: DOMStringList;
hash: string; hash: string;
host: string; host: string;
hostname: string; hostname: string;
href: string; href: string;
toString(): string;
readonly origin: string; readonly origin: string;
pathname: string; pathname: string;
port: string; port: string;
@ -543,6 +618,72 @@ export interface Location {
search: string; search: string;
assign(url: string): void; assign(url: string): void;
reload(): void; reload(): void;
reload(forcedReload: boolean): void;
replace(url: string): 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>;
}

View File

@ -2,6 +2,23 @@
// Utility functions for DOM nodes // Utility functions for DOM nodes
import * as domTypes from "./dom_types.ts"; 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 { export function isNode(nodeImpl: domTypes.EventTarget | null): boolean {
return Boolean(nodeImpl && "nodeType" in nodeImpl); return Boolean(nodeImpl && "nodeType" in nodeImpl);
} }

View File

@ -39,11 +39,11 @@ export class Event implements domTypes.Event {
isTrusted: false, isTrusted: false,
relatedTarget: null, relatedTarget: null,
target: null, target: null,
timeStamp: Date.now() timeStamp: Date.now(),
}); });
Reflect.defineProperty(this, "isTrusted", { Reflect.defineProperty(this, "isTrusted", {
enumerable: true, enumerable: true,
get: isTrusted get: isTrusted,
}); });
} }
@ -90,7 +90,7 @@ export class Event implements domTypes.Event {
isTrusted: this.isTrusted, isTrusted: this.isTrusted,
relatedTarget: this.relatedTarget, relatedTarget: this.relatedTarget,
target: this.target, target: this.target,
timeStamp: this.timeStamp timeStamp: this.timeStamp,
}); });
} }
@ -121,7 +121,7 @@ export class Event implements domTypes.Event {
isTrusted: this.isTrusted, isTrusted: this.isTrusted,
relatedTarget: this.relatedTarget, relatedTarget: this.relatedTarget,
target: this.target, target: this.target,
timeStamp: this.timeStamp timeStamp: this.timeStamp,
}); });
} }
@ -156,7 +156,7 @@ export class Event implements domTypes.Event {
isTrusted: this.isTrusted, isTrusted: this.isTrusted,
relatedTarget: value, relatedTarget: value,
target: this.target, target: this.target,
timeStamp: this.timeStamp timeStamp: this.timeStamp,
}); });
} }
@ -175,7 +175,7 @@ export class Event implements domTypes.Event {
isTrusted: this.isTrusted, isTrusted: this.isTrusted,
relatedTarget: this.relatedTarget, relatedTarget: this.relatedTarget,
target: value, target: value,
timeStamp: this.timeStamp timeStamp: this.timeStamp,
}); });
} }
@ -200,8 +200,8 @@ export class Event implements domTypes.Event {
rootOfClosedTree: false, rootOfClosedTree: false,
slotInClosedTree: false, slotInClosedTree: false,
target: null, target: null,
touchTargetList: [] touchTargetList: [],
} },
]; ];
let currentTargetIndex = 0; let currentTargetIndex = 0;
@ -242,7 +242,7 @@ export class Event implements domTypes.Event {
rootOfClosedTree: false, rootOfClosedTree: false,
slotInClosedTree: false, slotInClosedTree: false,
target: null, target: null,
touchTargetList: [] touchTargetList: [],
}); });
} }
@ -277,7 +277,7 @@ export class Event implements domTypes.Event {
rootOfClosedTree: false, rootOfClosedTree: false,
slotInClosedTree: false, slotInClosedTree: false,
target: null, 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, "composed", { enumerable: true });
Reflect.defineProperty(Event.prototype, "currentTarget", { enumerable: true }); Reflect.defineProperty(Event.prototype, "currentTarget", { enumerable: true });
Reflect.defineProperty(Event.prototype, "defaultPrevented", { Reflect.defineProperty(Event.prototype, "defaultPrevented", {
enumerable: true enumerable: true,
}); });
Reflect.defineProperty(Event.prototype, "dispatched", { enumerable: true }); Reflect.defineProperty(Event.prototype, "dispatched", { enumerable: true });
Reflect.defineProperty(Event.prototype, "eventPhase", { enumerable: true }); Reflect.defineProperty(Event.prototype, "eventPhase", { enumerable: true });

View File

@ -7,7 +7,7 @@ import {
isShadowRoot, isShadowRoot,
isShadowInclusiveAncestor, isShadowInclusiveAncestor,
isSlotable, isSlotable,
retarget retarget,
} from "./dom_util.ts"; } from "./dom_util.ts";
// https://dom.spec.whatwg.org/#get-the-parent // https://dom.spec.whatwg.org/#get-the-parent
@ -70,7 +70,7 @@ export class EventTarget implements domTypes.EventTarget {
listeners[type].push({ listeners[type].push({
callback, callback,
options: normalizedOptions options: normalizedOptions,
}); });
} }
@ -438,7 +438,7 @@ const eventTargetHelpers = {
const returnValue: domTypes.AddEventListenerOptions = { const returnValue: domTypes.AddEventListenerOptions = {
capture: Boolean(options), capture: Boolean(options),
once: false, once: false,
passive: false passive: false,
}; };
return returnValue; return returnValue;
@ -452,7 +452,7 @@ const eventTargetHelpers = {
): domTypes.EventListenerOptions { ): domTypes.EventListenerOptions {
if (typeof options === "boolean" || typeof options === "undefined") { if (typeof options === "boolean" || typeof options === "undefined") {
const returnValue: domTypes.EventListenerOptions = { const returnValue: domTypes.EventListenerOptions = {
capture: Boolean(options) capture: Boolean(options),
}; };
return returnValue; return returnValue;
@ -481,17 +481,17 @@ const eventTargetHelpers = {
relatedTarget, relatedTarget,
touchTargetList: touchTargets, touchTargetList: touchTargets,
rootOfClosedTree, rootOfClosedTree,
slotInClosedTree slotInClosedTree,
}); });
} },
}; };
Reflect.defineProperty(EventTarget.prototype, "addEventListener", { Reflect.defineProperty(EventTarget.prototype, "addEventListener", {
enumerable: true enumerable: true,
}); });
Reflect.defineProperty(EventTarget.prototype, "removeEventListener", { Reflect.defineProperty(EventTarget.prototype, "removeEventListener", {
enumerable: true enumerable: true,
}); });
Reflect.defineProperty(EventTarget.prototype, "dispatchEvent", { Reflect.defineProperty(EventTarget.prototype, "dispatchEvent", {
enumerable: true enumerable: true,
}); });

View File

@ -32,53 +32,58 @@ function hasHeaderValueOf(s: string, value: string): boolean {
return new RegExp(`^${value}[\t\s]*;?`).test(s); return new RegExp(`^${value}[\t\s]*;?`).test(s);
} }
class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser { class Body
private _bodyUsed = false; implements domTypes.Body, domTypes.ReadableStream<Uint8Array>, io.ReadCloser {
private _bodyPromise: null | Promise<ArrayBuffer> = null; #bodyUsed = false;
private _data: ArrayBuffer | null = null; #bodyPromise: Promise<ArrayBuffer> | null = null;
#data: ArrayBuffer | null = null;
#rid: number;
readonly locked: boolean = false; // TODO 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> { #bodyBuffer = async (): Promise<ArrayBuffer> => {
assert(this._bodyPromise == null); assert(this.#bodyPromise == null);
const buf = new Buffer(); const buf = new Buffer();
try { try {
const nread = await buf.readFrom(this); const nread = await buf.readFrom(this);
const ui8 = buf.bytes(); const ui8 = buf.bytes();
assert(ui8.byteLength === nread); assert(ui8.byteLength === nread);
this._data = ui8.buffer.slice( this.#data = ui8.buffer.slice(
ui8.byteOffset, ui8.byteOffset,
ui8.byteOffset + nread ui8.byteOffset + nread
) as ArrayBuffer; ) as ArrayBuffer;
assert(this._data.byteLength === nread); assert(this.#data.byteLength === nread);
} finally { } finally {
this.close(); this.close();
} }
return this._data; return this.#data;
} };
// eslint-disable-next-line require-await // eslint-disable-next-line require-await
async arrayBuffer(): Promise<ArrayBuffer> { async arrayBuffer(): Promise<ArrayBuffer> {
// If we've already bufferred the response, just return it. // If we've already bufferred the response, just return it.
if (this._data != null) { if (this.#data != null) {
return this._data; return this.#data;
} }
// If there is no _bodyPromise yet, start it. // If there is no _bodyPromise yet, start it.
if (this._bodyPromise == null) { if (this.#bodyPromise == null) {
this._bodyPromise = this._bodyBuffer(); this.#bodyPromise = this.#bodyBuffer();
} }
return this._bodyPromise; return this.#bodyPromise;
} }
async blob(): Promise<domTypes.Blob> { async blob(): Promise<domTypes.Blob> {
const arrayBuffer = await this.arrayBuffer(); const arrayBuffer = await this.arrayBuffer();
return new DenoBlob([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")) { if (dispositionParams.has("filename")) {
const filename = dispositionParams.get("filename")!; const filename = dispositionParams.get("filename")!;
const blob = new DenoBlob([enc.encode(octets)], { const blob = new DenoBlob([enc.encode(octets)], {
type: partContentType type: partContentType,
}); });
// TODO: based on spec // TODO: based on spec
// https://xhr.spec.whatwg.org/#dom-formdata-append // 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> { read(p: Uint8Array): Promise<number | io.EOF> {
this._bodyUsed = true; this.#bodyUsed = true;
return read(this.rid, p); return read(this.#rid, p);
} }
close(): Promise<void> { close(): Promise<void> {
close(this.rid); close(this.#rid);
return Promise.resolve(); return Promise.resolve();
} }
@ -233,7 +238,11 @@ class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser {
return notImplemented(); return notImplemented();
} }
getReader(): domTypes.ReadableStreamReader { getReader(options: { mode: "byob" }): domTypes.ReadableStreamBYOBReader;
getReader(): domTypes.ReadableStreamDefaultReader<Uint8Array>;
getReader():
| domTypes.ReadableStreamBYOBReader
| domTypes.ReadableStreamDefaultReader<Uint8Array> {
return notImplemented(); return notImplemented();
} }
@ -246,7 +255,24 @@ class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser {
} }
get bodyUsed(): boolean { 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; readonly redirected: boolean;
headers: domTypes.Headers; headers: domTypes.Headers;
readonly trailer: Promise<domTypes.Headers>; readonly trailer: Promise<domTypes.Headers>;
readonly body: null | Body; readonly body: Body | null;
constructor( constructor(
readonly url: string, readonly url: string,
@ -308,7 +334,7 @@ export class Response implements domTypes.Response {
"Content-Type", "Content-Type",
"Expires", "Expires",
"Last-Modified", "Last-Modified",
"Pragma" "Pragma",
].map((c: string) => c.toLowerCase()); ].map((c: string) => c.toLowerCase());
for (const h of this.headers) { for (const h of this.headers) {
/* Technically this is still not standards compliant because we are /* Technically this is still not standards compliant because we are
@ -337,35 +363,36 @@ export class Response implements domTypes.Response {
this.redirected = redirected_; this.redirected = redirected_;
} }
private bodyViewable(): boolean { #bodyViewable = (): boolean => {
if ( if (
this.type == "error" || this.type == "error" ||
this.type == "opaque" || this.type == "opaque" ||
this.type == "opaqueredirect" || this.type == "opaqueredirect" ||
this.body == undefined this.body == undefined
) ) {
return true; return true;
}
return false; return false;
} };
arrayBuffer(): Promise<ArrayBuffer> { arrayBuffer(): Promise<ArrayBuffer> {
/* You have to do the null check here and not in the function because /* You have to do the null check here and not in the function because
* otherwise TS complains about this.body potentially being null */ * 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 Promise.reject(new Error("Response body is null"));
} }
return this.body.arrayBuffer(); return this.body.arrayBuffer();
} }
blob(): Promise<domTypes.Blob> { 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 Promise.reject(new Error("Response body is null"));
} }
return this.body.blob(); return this.body.blob();
} }
formData(): Promise<domTypes.FormData> { 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 Promise.reject(new Error("Response body is null"));
} }
return this.body.formData(); return this.body.formData();
@ -373,14 +400,14 @@ export class Response implements domTypes.Response {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
json(): Promise<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 Promise.reject(new Error("Response body is null"));
} }
return this.body.json(); return this.body.json();
} }
text(): Promise<string> { 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 Promise.reject(new Error("Response body is null"));
} }
return this.body.text(); return this.body.text();
@ -453,7 +480,7 @@ function sendFetchReq(
const args = { const args = {
method, method,
url, url,
headers: headerArray headers: headerArray,
}; };
return opFetch(args, body); return opFetch(args, body);
@ -527,8 +554,9 @@ export async function fetch(
} }
part += "\r\n"; part += "\r\n";
if (fieldValue instanceof DomFileImpl) { if (fieldValue instanceof DomFileImpl) {
part += `Content-Type: ${fieldValue.type || part += `Content-Type: ${
"application/octet-stream"}\r\n`; fieldValue.type || "application/octet-stream"
}\r\n`;
} }
part += "\r\n"; part += "\r\n";
if (fieldValue instanceof DomFileImpl) { if (fieldValue instanceof DomFileImpl) {

View File

@ -8,7 +8,7 @@ import { requiredArguments } from "./util.ts";
const dataSymbol = Symbol("data"); const dataSymbol = Symbol("data");
class FormDataBase { class FormDataBase {
private [dataSymbol]: Array<[string, domTypes.FormDataEntryValue]> = []; [dataSymbol]: Array<[string, domTypes.FormDataEntryValue]> = [];
append(name: string, value: string): void; append(name: string, value: string): void;
append(name: string, value: blob.DenoBlob, filename?: string): void; append(name: string, value: blob.DenoBlob, filename?: string): void;
@ -17,7 +17,7 @@ class FormDataBase {
name = String(name); name = String(name);
if (value instanceof blob.DenoBlob) { if (value instanceof blob.DenoBlob) {
const dfile = new domFile.DomFileImpl([value], filename || name, { const dfile = new domFile.DomFileImpl([value], filename || name, {
type: value.type type: value.type,
}); });
this[dataSymbol].push([name, dfile]); this[dataSymbol].push([name, dfile]);
} else { } else {
@ -84,7 +84,7 @@ class FormDataBase {
if (!found) { if (!found) {
if (value instanceof blob.DenoBlob) { if (value instanceof blob.DenoBlob) {
const dfile = new domFile.DomFileImpl([value], filename || name, { const dfile = new domFile.DomFileImpl([value], filename || name, {
type: value.type type: value.type,
}); });
this[dataSymbol][i][1] = dfile; this[dataSymbol][i][1] = dfile;
} else { } else {
@ -103,7 +103,7 @@ class FormDataBase {
if (!found) { if (!found) {
if (value instanceof blob.DenoBlob) { if (value instanceof blob.DenoBlob) {
const dfile = new domFile.DomFileImpl([value], filename || name, { const dfile = new domFile.DomFileImpl([value], filename || name, {
type: value.type type: value.type,
}); });
this[dataSymbol].push([name, dfile]); this[dataSymbol].push([name, dfile]);
} else { } else {

View File

@ -17,32 +17,32 @@ function isHeaders(value: any): value is domTypes.Headers {
const headerMap = Symbol("header map"); const headerMap = Symbol("header map");
// 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.
function validateName(name: string): void {
if (invalidTokenRegex.test(name) || name === "") {
throw new TypeError(`${name} is not a legal HTTP header name`);
}
}
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 // ref: https://fetch.spec.whatwg.org/#dom-headers
class HeadersBase { class HeadersBase {
private [headerMap]: Map<string, string>; [headerMap]: Map<string, string>;
// TODO: headerGuard? Investigate if it is needed
// node-fetch did not implement this but it is in the spec
private _normalizeParams(name: string, value?: string): string[] {
name = String(name).toLowerCase();
value = String(value).trim();
return [name, value];
}
// The following name/value validations are copied from
// https://github.com/bitinn/node-fetch/blob/master/src/headers.js
// Copyright (c) 2016 David Frank. MIT License.
private _validateName(name: string): void {
if (invalidTokenRegex.test(name) || name === "") {
throw new TypeError(`${name} is not a legal HTTP header name`);
}
}
private _validateValue(value: string): void {
if (invalidHeaderCharRegex.test(value)) {
throw new TypeError(`${value} is not a legal HTTP header value`);
}
}
constructor(init?: domTypes.HeadersInit) { constructor(init?: domTypes.HeadersInit) {
if (init === null) { if (init === null) {
@ -64,9 +64,9 @@ class HeadersBase {
2 2
); );
const [name, value] = this._normalizeParams(tuple[0], tuple[1]); const [name, value] = normalizeParams(tuple[0], tuple[1]);
this._validateName(name); validateName(name);
this._validateValue(value); validateValue(value);
const existingValue = this[headerMap].get(name); const existingValue = this[headerMap].get(name);
this[headerMap].set( this[headerMap].set(
name, name,
@ -77,9 +77,9 @@ class HeadersBase {
const names = Object.keys(init); const names = Object.keys(init);
for (const rawName of names) { for (const rawName of names) {
const rawValue = init[rawName]; const rawValue = init[rawName];
const [name, value] = this._normalizeParams(rawName, rawValue); const [name, value] = normalizeParams(rawName, rawValue);
this._validateName(name); validateName(name);
this._validateValue(value); validateValue(value);
this[headerMap].set(name, value); this[headerMap].set(name, value);
} }
} }
@ -101,9 +101,9 @@ class HeadersBase {
// ref: https://fetch.spec.whatwg.org/#concept-headers-append // ref: https://fetch.spec.whatwg.org/#concept-headers-append
append(name: string, value: string): void { append(name: string, value: string): void {
requiredArguments("Headers.append", arguments.length, 2); requiredArguments("Headers.append", arguments.length, 2);
const [newname, newvalue] = this._normalizeParams(name, value); const [newname, newvalue] = normalizeParams(name, value);
this._validateName(newname); validateName(newname);
this._validateValue(newvalue); validateValue(newvalue);
const v = this[headerMap].get(newname); const v = this[headerMap].get(newname);
const str = v ? `${v}, ${newvalue}` : newvalue; const str = v ? `${v}, ${newvalue}` : newvalue;
this[headerMap].set(newname, str); this[headerMap].set(newname, str);
@ -111,31 +111,31 @@ class HeadersBase {
delete(name: string): void { delete(name: string): void {
requiredArguments("Headers.delete", arguments.length, 1); requiredArguments("Headers.delete", arguments.length, 1);
const [newname] = this._normalizeParams(name); const [newname] = normalizeParams(name);
this._validateName(newname); validateName(newname);
this[headerMap].delete(newname); this[headerMap].delete(newname);
} }
get(name: string): string | null { get(name: string): string | null {
requiredArguments("Headers.get", arguments.length, 1); requiredArguments("Headers.get", arguments.length, 1);
const [newname] = this._normalizeParams(name); const [newname] = normalizeParams(name);
this._validateName(newname); validateName(newname);
const value = this[headerMap].get(newname); const value = this[headerMap].get(newname);
return value || null; return value || null;
} }
has(name: string): boolean { has(name: string): boolean {
requiredArguments("Headers.has", arguments.length, 1); requiredArguments("Headers.has", arguments.length, 1);
const [newname] = this._normalizeParams(name); const [newname] = normalizeParams(name);
this._validateName(newname); validateName(newname);
return this[headerMap].has(newname); return this[headerMap].has(newname);
} }
set(name: string, value: string): void { set(name: string, value: string): void {
requiredArguments("Headers.set", arguments.length, 2); requiredArguments("Headers.set", arguments.length, 2);
const [newname, newvalue] = this._normalizeParams(name, value); const [newname, newvalue] = normalizeParams(name, value);
this._validateName(newname); validateName(newname);
this._validateValue(newvalue); validateValue(newvalue);
this[headerMap].set(newname, newvalue); this[headerMap].set(newname, newvalue);
} }

View File

@ -1,12 +1,15 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { URL } from "./url.ts"; import { URL } from "./url.ts";
import { notImplemented } from "../util.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 { export class LocationImpl implements Location {
#url: URL;
constructor(url: string) { constructor(url: string) {
const u = new URL(url); const u = new URL(url);
this.url = u; this.#url = u;
this.hash = u.hash; this.hash = u.hash;
this.host = u.host; this.host = u.host;
this.href = u.href; this.href = u.href;
@ -18,13 +21,11 @@ export class LocationImpl implements Location {
this.search = u.search; this.search = u.search;
} }
private url: URL;
toString(): string { toString(): string {
return this.url.toString(); return this.#url.toString();
} }
readonly ancestorOrigins: string[] = []; readonly ancestorOrigins: DOMStringList = getDOMStringList([]);
hash: string; hash: string;
host: string; host: string;
hostname: 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 { export function setLocation(url: string): void {
globalThis.location = new LocationImpl(url); globalThis.location = new LocationImpl(url);
Object.freeze(globalThis.location); Object.freeze(globalThis.location);

View File

@ -136,7 +136,7 @@ export class Request extends body.Body implements domTypes.Request {
body: body2, body: body2,
method: this.method, method: this.method,
headers: new Headers(headersList), headers: new Headers(headersList),
credentials: this.credentials credentials: this.credentials,
}); });
return cloned; return cloned;
} }

View File

@ -148,7 +148,7 @@ export class ReadableByteStreamController
bytesFilled: 0, bytesFilled: 0,
elementSize: 1, elementSize: 1,
ctor: Uint8Array, ctor: Uint8Array,
readerType: "default" readerType: "default",
}; };
this[rs.pendingPullIntos_].push(pullIntoDescriptor); this[rs.pendingPullIntos_].push(pullIntoDescriptor);
} }

View File

@ -10,7 +10,7 @@ import {
QueuingStrategy, QueuingStrategy,
QueuingStrategySizeCallback, QueuingStrategySizeCallback,
UnderlyingSource, UnderlyingSource,
UnderlyingByteSource UnderlyingByteSource,
} from "../dom_types.ts"; } from "../dom_types.ts";
// ReadableStreamDefaultController // ReadableStreamDefaultController
@ -345,7 +345,7 @@ export function readableStreamCancel<OutputType>(
const sourceCancelPromise = stream[readableStreamController_][cancelSteps_]( const sourceCancelPromise = stream[readableStreamController_][cancelSteps_](
reason reason
); );
return sourceCancelPromise.then(_ => undefined); return sourceCancelPromise.then((_) => undefined);
} }
export function readableStreamClose<OutputType>( export function readableStreamClose<OutputType>(
@ -558,13 +558,13 @@ export function setUpReadableStreamDefaultController<OutputType>(
const startResult = startAlgorithm(); const startResult = startAlgorithm();
Promise.resolve(startResult).then( Promise.resolve(startResult).then(
_ => { (_) => {
controller[started_] = true; controller[started_] = true;
// Assert: controller.[[pulling]] is false. // Assert: controller.[[pulling]] is false.
// Assert: controller.[[pullAgain]] is false. // Assert: controller.[[pullAgain]] is false.
readableStreamDefaultControllerCallPullIfNeeded(controller); readableStreamDefaultControllerCallPullIfNeeded(controller);
}, },
error => { (error) => {
readableStreamDefaultControllerError(controller, error); readableStreamDefaultControllerError(controller, error);
} }
); );
@ -678,14 +678,14 @@ export function readableStreamDefaultControllerCallPullIfNeeded<OutputType>(
controller[pulling_] = true; controller[pulling_] = true;
controller[pullAlgorithm_](controller).then( controller[pullAlgorithm_](controller).then(
_ => { (_) => {
controller[pulling_] = false; controller[pulling_] = false;
if (controller[pullAgain_]) { if (controller[pullAgain_]) {
controller[pullAgain_] = false; controller[pullAgain_] = false;
readableStreamDefaultControllerCallPullIfNeeded(controller); readableStreamDefaultControllerCallPullIfNeeded(controller);
} }
}, },
error => { (error) => {
readableStreamDefaultControllerError(controller, error); readableStreamDefaultControllerError(controller, error);
} }
); );
@ -768,13 +768,13 @@ export function setUpReadableByteStreamController(
// Let startResult be the result of performing startAlgorithm. // Let startResult be the result of performing startAlgorithm.
const startResult = startAlgorithm(); const startResult = startAlgorithm();
Promise.resolve(startResult).then( Promise.resolve(startResult).then(
_ => { (_) => {
controller[started_] = true; controller[started_] = true;
// Assert: controller.[[pulling]] is false. // Assert: controller.[[pulling]] is false.
// Assert: controller.[[pullAgain]] is false. // Assert: controller.[[pullAgain]] is false.
readableByteStreamControllerCallPullIfNeeded(controller); readableByteStreamControllerCallPullIfNeeded(controller);
}, },
error => { (error) => {
readableByteStreamControllerError(controller, error); readableByteStreamControllerError(controller, error);
} }
); );
@ -811,14 +811,14 @@ export function readableByteStreamControllerCallPullIfNeeded(
// Assert: controller.[[pullAgain]] is false. // Assert: controller.[[pullAgain]] is false.
controller[pulling_] = true; controller[pulling_] = true;
controller[pullAlgorithm_](controller).then( controller[pullAlgorithm_](controller).then(
_ => { (_) => {
controller[pulling_] = false; controller[pulling_] = false;
if (controller[pullAgain_]) { if (controller[pullAgain_]) {
controller[pullAgain_] = false; controller[pullAgain_] = false;
readableByteStreamControllerCallPullIfNeeded(controller); readableByteStreamControllerCallPullIfNeeded(controller);
} }
}, },
error => { (error) => {
readableByteStreamControllerError(controller, error); readableByteStreamControllerError(controller, error);
} }
); );
@ -1122,7 +1122,7 @@ export function readableByteStreamControllerPullInto(
bytesFilled: 0, bytesFilled: 0,
elementSize, elementSize,
ctor, ctor,
readerType: "byob" readerType: "byob",
}; };
if (controller[pendingPullIntos_].length > 0) { if (controller[pendingPullIntos_].length > 0) {

Some files were not shown because too many files have changed in this diff Show More