From 6443e4aed16868c17111a56634aa733211430f46 Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Tue, 10 Mar 2020 16:08:58 +0000 Subject: [PATCH] refactor: Cleanup options object parameters (#4296) --- cli/js/compiler_api.ts | 12 ++--- cli/js/compiler_host.ts | 3 +- cli/js/console.ts | 32 ++++------- cli/js/lib.deno.shared_globals.d.ts | 6 +-- cli/js/net.ts | 24 +++++---- cli/js/ops/tls.ts | 2 +- cli/js/process.ts | 83 +++++++---------------------- cli/js/tests/console_test.ts | 2 +- cli/js/tls.ts | 34 ++++++++---- cli/js/web/blob.ts | 20 +++---- cli/js/web/dom_file.ts | 6 +-- cli/js/web/dom_types.ts | 6 +-- cli/js/web/text_encoding.ts | 9 ++-- cli/js/workers.ts | 9 +--- std/flags/mod.ts | 16 +++--- std/fs/move.ts | 8 +-- std/testing/bench.ts | 2 +- 17 files changed, 110 insertions(+), 164 deletions(-) diff --git a/cli/js/compiler_api.ts b/cli/js/compiler_api.ts index b7c4e83e83..8282f0717d 100644 --- a/cli/js/compiler_api.ts +++ b/cli/js/compiler_api.ts @@ -302,12 +302,12 @@ export interface TranspileOnlyResult { */ export async function transpileOnly( sources: Record, - options?: CompilerOptions + options: CompilerOptions = {} ): Promise> { util.log("Deno.transpileOnly", { sources: Object.keys(sources), options }); const payload = { sources, - options: options ? JSON.stringify(options) : undefined + options: JSON.stringify(options) }; const result = await runtimeCompilerOps.transpile(payload); return JSON.parse(result); @@ -343,12 +343,12 @@ export async function transpileOnly( export async function compile( rootName: string, sources?: Record, - options?: CompilerOptions + options: CompilerOptions = {} ): Promise<[DiagnosticItem[] | undefined, Record]> { const payload = { rootName: sources ? rootName : checkRelative(rootName), sources, - options: options ? JSON.stringify(options) : undefined, + options: JSON.stringify(options), bundle: false }; util.log("Deno.compile", { @@ -391,12 +391,12 @@ export async function compile( export async function bundle( rootName: string, sources?: Record, - options?: CompilerOptions + options: CompilerOptions = {} ): Promise<[DiagnosticItem[] | undefined, string]> { const payload = { rootName: sources ? rootName : checkRelative(rootName), sources, - options: options ? JSON.stringify(options) : undefined, + options: JSON.stringify(options), bundle: true }; util.log("Deno.bundle", { diff --git a/cli/js/compiler_host.ts b/cli/js/compiler_host.ts index b89c7163c0..413ffa6e1a 100644 --- a/cli/js/compiler_host.ts +++ b/cli/js/compiler_host.ts @@ -165,8 +165,7 @@ export class Host implements ts.CompilerHost { /* Deno specific APIs */ /** Provides the `ts.HostCompiler` interface for Deno. */ - constructor(options: CompilerHostOptions) { - const { bundle = false, target, writeFile } = options; + constructor({ bundle = false, target, writeFile }: CompilerHostOptions) { this._target = target; this._writeFile = writeFile; if (bundle) { diff --git a/cli/js/console.ts b/cli/js/console.ts index 05e983ec70..60329ab00a 100644 --- a/cli/js/console.ts +++ b/cli/js/console.ts @@ -367,7 +367,7 @@ function createObjectString( /** @internal */ export function stringifyArgs( args: unknown[], - options: ConsoleOptions = {} + { depth = DEFAULT_MAX_DEPTH, indentLevel = 0 }: ConsoleOptions = {} ): string { const first = args[0]; let a = 0; @@ -411,12 +411,7 @@ export function stringifyArgs( case CHAR_LOWERCASE_O: case CHAR_UPPERCASE_O: // format as an object - tempStr = stringify( - args[++a], - new Set(), - 0, - options.depth != undefined ? options.depth : DEFAULT_MAX_DEPTH - ); + tempStr = stringify(args[++a], new Set(), 0, depth); break; case CHAR_PERCENT: str += first.slice(lastPos, i); @@ -459,19 +454,13 @@ export function stringifyArgs( str += value; } else { // use default maximum depth for null or undefined argument - str += stringify( - value, - new Set(), - 0, - options.depth != undefined ? options.depth : DEFAULT_MAX_DEPTH - ); + str += stringify(value, new Set(), 0, depth); } join = " "; a++; } - const { indentLevel } = options; - if (indentLevel != null && indentLevel > 0) { + if (indentLevel > 0) { const groupIndent = " ".repeat(indentLevel); if (str.indexOf("\n") !== -1) { str = str.replace(/\n/g, `\n${groupIndent}`); @@ -771,17 +760,14 @@ export const customInspect = Symbol.for("Deno.customInspect"); * `inspect()` converts input into string that has the same format * as printed by `console.log(...)`; */ -export function inspect(value: unknown, options?: ConsoleOptions): string { - const opts = options || {}; +export function inspect( + value: unknown, + { depth = DEFAULT_MAX_DEPTH }: ConsoleOptions = {} +): string { if (typeof value === "string") { return value; } else { - return stringify( - value, - new Set(), - 0, - opts.depth != undefined ? opts.depth : DEFAULT_MAX_DEPTH - ); + return stringify(value, new Set(), 0, depth); } } diff --git a/cli/js/lib.deno.shared_globals.d.ts b/cli/js/lib.deno.shared_globals.d.ts index 9ec045a8ea..ea8bf08ecc 100644 --- a/cli/js/lib.deno.shared_globals.d.ts +++ b/cli/js/lib.deno.shared_globals.d.ts @@ -503,11 +503,11 @@ declare namespace __domTypes { readonly total: number; } export interface EventListenerOptions { - capture: boolean; + capture?: boolean; } export interface AddEventListenerOptions extends EventListenerOptions { - once: boolean; - passive: boolean; + once?: boolean; + passive?: boolean; } interface AbortSignal extends EventTarget { readonly aborted: boolean; diff --git a/cli/js/net.ts b/cli/js/net.ts index ccc5bf89ea..3771a13237 100644 --- a/cli/js/net.ts +++ b/cli/js/net.ts @@ -206,8 +206,6 @@ export interface ListenOptions { transport?: Transport; } -const listenDefaults = { hostname: "0.0.0.0", transport: "tcp" }; - /** Listen announces on the local transport address. * * @param options @@ -229,11 +227,14 @@ export function listen( options: ListenOptions & { transport?: "tcp" } ): Listener; export function listen(options: ListenOptions & { transport: "udp" }): UDPConn; -export function listen(options: ListenOptions): Listener | UDPConn { - const args = { ...listenDefaults, ...options }; - const res = netOps.listen(args as netOps.ListenRequest); +export function listen({ + port, + hostname = "0.0.0.0", + transport = "tcp" +}: ListenOptions): Listener | UDPConn { + const res = netOps.listen({ port, hostname, transport }); - if (args.transport === "tcp") { + if (transport === "tcp") { return new ListenerImpl(res.rid, res.localAddr); } else { return new UDPConnImpl(res.rid, res.localAddr); @@ -246,8 +247,6 @@ export interface ConnectOptions { transport?: Transport; } -const connectDefaults = { hostname: "127.0.0.1", transport: "tcp" }; - /** Connects to the address on the named transport. * * @param options @@ -265,8 +264,11 @@ const connectDefaults = { hostname: "127.0.0.1", transport: "tcp" }; * connect({ hostname: "[2001:db8::1]", port: 80 }); * connect({ hostname: "golang.org", port: 80, transport: "tcp" }) */ -export async function connect(options: ConnectOptions): Promise { - options = Object.assign(connectDefaults, options); - const res = await netOps.connect(options as netOps.ConnectRequest); +export async function connect({ + port, + hostname = "127.0.0.1", + transport = "tcp" +}: ConnectOptions): Promise { + const res = await netOps.connect({ port, hostname, transport }); return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!); } diff --git a/cli/js/ops/tls.ts b/cli/js/ops/tls.ts index 3a9d70385d..3e49c1c936 100644 --- a/cli/js/ops/tls.ts +++ b/cli/js/ops/tls.ts @@ -6,7 +6,7 @@ export interface ConnectTLSRequest { transport: Transport; hostname: string; port: number; - cert_file?: string; + certFile?: string; } interface ConnectTLSResponse { diff --git a/cli/js/process.ts b/cli/js/process.ts index 3e5cc8ea01..6462086eef 100644 --- a/cli/js/process.ts +++ b/cli/js/process.ts @@ -3,7 +3,6 @@ import { File } from "./files.ts"; import { close } from "./ops/resources.ts"; import { ReadCloser, WriteCloser } from "./io.ts"; import { readAll } from "./buffer.ts"; -import { assert, unreachable } from "./util.ts"; import { build } from "./build.ts"; import { kill, runStatus as runStatusOp, run as runOp } from "./ops/process.ts"; @@ -117,18 +116,6 @@ export interface ProcessStatus { signal?: number; // TODO: Make this a string, e.g. 'SIGTERM'. } -// TODO: this method is only used to validate proper option, probably can be renamed -function stdioMap(s: string): string { - switch (s) { - case "inherit": - case "piped": - case "null": - return s; - default: - return unreachable(); - } -} - function isRid(arg: unknown): arg is number { return !isNaN(arg as number); } @@ -153,57 +140,25 @@ interface RunResponse { * `opt.stdout`, `opt.stderr` and `opt.stdin` can be specified independently - * they can be set to either `ProcessStdio` or `rid` of open file. */ -export function run(opt: RunOptions): Process { - assert(opt.args.length > 0); - let env: Array<[string, string]> = []; - if (opt.env) { - env = Array.from(Object.entries(opt.env)); - } - - let stdin = stdioMap("inherit"); - let stdout = stdioMap("inherit"); - let stderr = stdioMap("inherit"); - let stdinRid = 0; - let stdoutRid = 0; - let stderrRid = 0; - - if (opt.stdin) { - if (isRid(opt.stdin)) { - stdinRid = opt.stdin; - } else { - stdin = stdioMap(opt.stdin); - } - } - - if (opt.stdout) { - if (isRid(opt.stdout)) { - stdoutRid = opt.stdout; - } else { - stdout = stdioMap(opt.stdout); - } - } - - if (opt.stderr) { - if (isRid(opt.stderr)) { - stderrRid = opt.stderr; - } else { - stderr = stdioMap(opt.stderr); - } - } - - const req = { - args: opt.args.map(String), - cwd: opt.cwd, - env, - stdin, - stdout, - stderr, - stdinRid, - stdoutRid, - stderrRid - }; - - const res = runOp(req); +export function run({ + args, + cwd = undefined, + env = {}, + stdout = "inherit", + stderr = "inherit", + stdin = "inherit" +}: RunOptions): Process { + const res = runOp({ + args: args.map(String), + cwd, + env: Object.entries(env), + stdin: isRid(stdin) ? "" : stdin, + stdout: isRid(stdout) ? "" : stdout, + stderr: isRid(stderr) ? "" : stderr, + stdinRid: isRid(stdin) ? stdin : 0, + stdoutRid: isRid(stdout) ? stdout : 0, + stderrRid: isRid(stderr) ? stderr : 0 + }) as RunResponse; return new Process(res); } diff --git a/cli/js/tests/console_test.ts b/cli/js/tests/console_test.ts index 34a61c25ff..256c7da80e 100644 --- a/cli/js/tests/console_test.ts +++ b/cli/js/tests/console_test.ts @@ -186,7 +186,7 @@ unitTest(function consoleTestStringifyWithDepth(): void { ); assertEquals(stringifyArgs([nestedObj], { depth: 0 }), "[Object]"); assertEquals( - stringifyArgs([nestedObj], { depth: null }), + stringifyArgs([nestedObj]), "{ a: { b: { c: { d: [Object] } } } }" ); // test inspect is working the same way diff --git a/cli/js/tls.ts b/cli/js/tls.ts index 8fff562d28..d7d12ac35d 100644 --- a/cli/js/tls.ts +++ b/cli/js/tls.ts @@ -10,14 +10,22 @@ interface ConnectTLSOptions { hostname?: string; certFile?: string; } -const connectTLSDefaults = { hostname: "127.0.0.1", transport: "tcp" }; /** * Establishes a secure connection over TLS (transport layer security). */ -export async function connectTLS(options: ConnectTLSOptions): Promise { - options = Object.assign(connectTLSDefaults, options); - const res = await tlsOps.connectTLS(options as tlsOps.ConnectTLSRequest); +export async function connectTLS({ + port, + hostname = "127.0.0.1", + transport = "tcp", + certFile = undefined +}: ConnectTLSOptions): Promise { + const res = await tlsOps.connectTLS({ + port, + hostname, + transport, + certFile + }); return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!); } @@ -49,15 +57,19 @@ export interface ListenTLSOptions { * * Deno.listenTLS({ port: 443, certFile: "./my_server.crt", keyFile: "./my_server.key" }) */ -export function listenTLS(options: ListenTLSOptions): Listener { - const hostname = options.hostname || "0.0.0.0"; - const transport = options.transport || "tcp"; +export function listenTLS({ + port, + certFile, + keyFile, + hostname = "0.0.0.0", + transport = "tcp" +}: ListenTLSOptions): Listener { const res = tlsOps.listenTLS({ + port, + certFile, + keyFile, hostname, - port: options.port, - transport, - certFile: options.certFile, - keyFile: options.keyFile + transport }); return new TLSListenerImpl(res.rid, res.localAddr); } diff --git a/cli/js/web/blob.ts b/cli/js/web/blob.ts index 896337b103..1309ddff0a 100644 --- a/cli/js/web/blob.ts +++ b/cli/js/web/blob.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import * as domTypes from "./dom_types.ts"; -import { hasOwnProperty } from "../util.ts"; import { TextEncoder } from "./text_encoding.ts"; import { build } from "../build.ts"; @@ -144,34 +143,29 @@ export class DenoBlob implements domTypes.Blob { return; } - options = options || {}; - // Set ending property's default value to "transparent". - if (!hasOwnProperty(options, "ending")) { - options.ending = "transparent"; - } - - if (options.type && !containsOnlyASCII(options.type)) { + const { ending = "transparent", type = "" } = options ?? {}; + if (!containsOnlyASCII(type)) { const errMsg = "The 'type' property must consist of ASCII characters."; throw new SyntaxError(errMsg); } - const bytes = processBlobParts(blobParts!, options); + const bytes = processBlobParts(blobParts!, { ending, type }); // Normalize options.type. - let type = options.type ? options.type : ""; + let normalizedType = type; if (type.length) { for (let i = 0; i < type.length; ++i) { const char = type[i]; if (char < "\u0020" || char > "\u007E") { - type = ""; + normalizedType = ""; break; } } - type = type.toLowerCase(); + normalizedType = type.toLowerCase(); } // Set Blob object's properties. this[bytesSymbol] = bytes; this.size = bytes.byteLength; - this.type = type; + this.type = normalizedType; // Register bytes for internal private use. blobBytesWeakMap.set(this, bytes); diff --git a/cli/js/web/dom_file.ts b/cli/js/web/dom_file.ts index 2b9dbff241..cf2a40398e 100644 --- a/cli/js/web/dom_file.ts +++ b/cli/js/web/dom_file.ts @@ -11,14 +11,14 @@ export class DomFileImpl extends blob.DenoBlob implements domTypes.DomFile { fileName: string, options?: domTypes.FilePropertyBag ) { - options = options || {}; - super(fileBits, options); + const { lastModified = Date.now(), ...blobPropertyBag } = options ?? {}; + super(fileBits, blobPropertyBag); // 4.1.2.1 Replace any "/" character (U+002F SOLIDUS) // with a ":" (U + 003A COLON) this.name = String(fileName).replace(/\u002F/g, "\u003A"); // 4.1.3.3 If lastModified is not provided, set lastModified to the current // date and time represented in number of milliseconds since the Unix Epoch. - this.lastModified = options.lastModified || Date.now(); + this.lastModified = lastModified; } } diff --git a/cli/js/web/dom_types.ts b/cli/js/web/dom_types.ts index cdd6816153..23347ce66d 100644 --- a/cli/js/web/dom_types.ts +++ b/cli/js/web/dom_types.ts @@ -258,12 +258,12 @@ interface ProgressEvent extends Event { } export interface EventListenerOptions { - capture: boolean; + capture?: boolean; } export interface AddEventListenerOptions extends EventListenerOptions { - once: boolean; - passive: boolean; + once?: boolean; + passive?: boolean; } export interface AbortSignal extends EventTarget { diff --git a/cli/js/web/text_encoding.ts b/cli/js/web/text_encoding.ts index 0709e7123f..928cbe7e1e 100644 --- a/cli/js/web/text_encoding.ts +++ b/cli/js/web/text_encoding.ts @@ -154,11 +154,14 @@ class SingleByteDecoder implements Decoder { private _index: number[]; private _fatal: boolean; - constructor(index: number[], options: DecoderOptions) { - if (options.ignoreBOM) { + constructor( + index: number[], + { ignoreBOM = false, fatal = false }: DecoderOptions = {} + ) { + if (ignoreBOM) { throw new TypeError("Ignoring the BOM is available only with utf-8."); } - this._fatal = options.fatal || false; + this._fatal = fatal; this._index = index; } handler(stream: Stream, byte: number): number { diff --git a/cli/js/workers.ts b/cli/js/workers.ts index 4f8cf54ae6..818c0ecf44 100644 --- a/cli/js/workers.ts +++ b/cli/js/workers.ts @@ -58,12 +58,7 @@ export class WorkerImpl extends EventTarget implements Worker { constructor(specifier: string, options?: WorkerOptions) { super(); - - let type = "classic"; - - if (options?.type) { - type = options.type; - } + const { type = "classic", name = "unknown" } = options ?? {}; if (type !== "module") { throw new Error( @@ -71,7 +66,7 @@ export class WorkerImpl extends EventTarget implements Worker { ); } - this.name = options?.name ?? "unknown"; + this.name = name; const hasSourceCode = false; const sourceCode = decoder.decode(new Uint8Array()); diff --git a/std/flags/mod.ts b/std/flags/mod.ts index 59cae5d158..18727a6654 100644 --- a/std/flags/mod.ts +++ b/std/flags/mod.ts @@ -27,31 +27,31 @@ export interface ArgParsingOptions { * * Defaults to `false`. */ - "--": boolean; + "--"?: boolean; /** An object mapping string names to strings or arrays of string argument * names to use as aliases */ - alias: Record; + alias?: Record; /** A boolean, string or array of strings to always treat as booleans. If * `true` will treat all double hyphenated arguments without equal signs as * `boolean` (e.g. affects `--foo`, not `-f` or `--foo=bar`) */ - boolean: boolean | string | string[]; + boolean?: boolean | string | string[]; /** An object mapping string argument names to default values. */ - default: Record; + default?: Record; /** When `true`, populate the result `_` with everything after the first * non-option. */ - stopEarly: boolean; + stopEarly?: boolean; /** A string or array of strings argument names to always treat as strings. */ - string: string | string[]; + string?: string | string[]; /** A function which is invoked with a command line parameter not defined in * the `options` configuration object. If the function returns `false`, the * unknown option is not added to `parsedArgs`. */ - unknown: (i: unknown) => unknown; + unknown?: (i: unknown) => unknown; } interface Flags { @@ -108,7 +108,7 @@ export function parse( stopEarly = false, string = [], unknown = (i: unknown): unknown => i - }: Partial = {} + }: ArgParsingOptions = {} ): Args { const flags: Flags = { bools: {}, diff --git a/std/fs/move.ts b/std/fs/move.ts index e87d59c6e6..48b1ef5f2c 100644 --- a/std/fs/move.ts +++ b/std/fs/move.ts @@ -10,7 +10,7 @@ interface MoveOptions { export async function move( src: string, dest: string, - options?: MoveOptions + { overwrite = false }: MoveOptions = {} ): Promise { const srcStat = await Deno.stat(src); @@ -20,7 +20,7 @@ export async function move( ); } - if (options && options.overwrite) { + if (overwrite) { await Deno.remove(dest, { recursive: true }); await Deno.rename(src, dest); } else { @@ -37,7 +37,7 @@ export async function move( export function moveSync( src: string, dest: string, - options?: MoveOptions + { overwrite = false }: MoveOptions = {} ): void { const srcStat = Deno.statSync(src); @@ -47,7 +47,7 @@ export function moveSync( ); } - if (options && options.overwrite) { + if (overwrite) { Deno.removeSync(dest, { recursive: true }); Deno.renameSync(src, dest); } else { diff --git a/std/testing/bench.ts b/std/testing/bench.ts index c76c1bd7c1..5cec3ea396 100644 --- a/std/testing/bench.ts +++ b/std/testing/bench.ts @@ -171,7 +171,7 @@ export async function runBenchmarks({ /** Runs specified benchmarks if the enclosing script is main. */ export async function runIfMain( meta: ImportMeta, - opts?: BenchmarkRunOptions + opts: BenchmarkRunOptions = {} ): Promise { if (meta.main) { return runBenchmarks(opts);