refactor: Cleanup options object parameters (#4296)

This commit is contained in:
Nayeem Rahman 2020-03-10 16:08:58 +00:00 committed by GitHub
parent fbc4731256
commit 6443e4aed1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 110 additions and 164 deletions

View file

@ -302,12 +302,12 @@ export interface TranspileOnlyResult {
*/ */
export async function transpileOnly( export async function transpileOnly(
sources: Record<string, string>, sources: Record<string, string>,
options?: CompilerOptions options: CompilerOptions = {}
): Promise<Record<string, TranspileOnlyResult>> { ): Promise<Record<string, TranspileOnlyResult>> {
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: options ? JSON.stringify(options) : undefined options: JSON.stringify(options)
}; };
const result = await runtimeCompilerOps.transpile(payload); const result = await runtimeCompilerOps.transpile(payload);
return JSON.parse(result); return JSON.parse(result);
@ -343,12 +343,12 @@ export async function transpileOnly(
export async function compile( export async function compile(
rootName: string, rootName: string,
sources?: Record<string, string>, sources?: Record<string, string>,
options?: CompilerOptions options: CompilerOptions = {}
): Promise<[DiagnosticItem[] | undefined, Record<string, string>]> { ): Promise<[DiagnosticItem[] | undefined, Record<string, string>]> {
const payload = { const payload = {
rootName: sources ? rootName : checkRelative(rootName), rootName: sources ? rootName : checkRelative(rootName),
sources, sources,
options: options ? JSON.stringify(options) : undefined, options: JSON.stringify(options),
bundle: false bundle: false
}; };
util.log("Deno.compile", { util.log("Deno.compile", {
@ -391,12 +391,12 @@ export async function compile(
export async function bundle( export async function bundle(
rootName: string, rootName: string,
sources?: Record<string, string>, sources?: Record<string, string>,
options?: CompilerOptions options: CompilerOptions = {}
): Promise<[DiagnosticItem[] | undefined, string]> { ): Promise<[DiagnosticItem[] | undefined, string]> {
const payload = { const payload = {
rootName: sources ? rootName : checkRelative(rootName), rootName: sources ? rootName : checkRelative(rootName),
sources, sources,
options: options ? JSON.stringify(options) : undefined, options: JSON.stringify(options),
bundle: true bundle: true
}; };
util.log("Deno.bundle", { util.log("Deno.bundle", {

View file

@ -165,8 +165,7 @@ export class Host implements ts.CompilerHost {
/* Deno specific APIs */ /* Deno specific APIs */
/** Provides the `ts.HostCompiler` interface for Deno. */ /** Provides the `ts.HostCompiler` interface for Deno. */
constructor(options: CompilerHostOptions) { constructor({ bundle = false, target, writeFile }: CompilerHostOptions) {
const { bundle = false, target, writeFile } = options;
this._target = target; this._target = target;
this._writeFile = writeFile; this._writeFile = writeFile;
if (bundle) { if (bundle) {

View file

@ -367,7 +367,7 @@ function createObjectString(
/** @internal */ /** @internal */
export function stringifyArgs( export function stringifyArgs(
args: unknown[], args: unknown[],
options: ConsoleOptions = {} { depth = DEFAULT_MAX_DEPTH, indentLevel = 0 }: ConsoleOptions = {}
): string { ): string {
const first = args[0]; const first = args[0];
let a = 0; let a = 0;
@ -411,12 +411,7 @@ export function stringifyArgs(
case CHAR_LOWERCASE_O: case CHAR_LOWERCASE_O:
case CHAR_UPPERCASE_O: case CHAR_UPPERCASE_O:
// format as an object // format as an object
tempStr = stringify( tempStr = stringify(args[++a], new Set<unknown>(), 0, depth);
args[++a],
new Set<unknown>(),
0,
options.depth != undefined ? options.depth : DEFAULT_MAX_DEPTH
);
break; break;
case CHAR_PERCENT: case CHAR_PERCENT:
str += first.slice(lastPos, i); str += first.slice(lastPos, i);
@ -459,19 +454,13 @@ export function stringifyArgs(
str += value; str += value;
} else { } else {
// use default maximum depth for null or undefined argument // use default maximum depth for null or undefined argument
str += stringify( str += stringify(value, new Set<unknown>(), 0, depth);
value,
new Set<unknown>(),
0,
options.depth != undefined ? options.depth : DEFAULT_MAX_DEPTH
);
} }
join = " "; join = " ";
a++; a++;
} }
const { indentLevel } = options; if (indentLevel > 0) {
if (indentLevel != null && indentLevel > 0) {
const groupIndent = " ".repeat(indentLevel); const groupIndent = " ".repeat(indentLevel);
if (str.indexOf("\n") !== -1) { if (str.indexOf("\n") !== -1) {
str = str.replace(/\n/g, `\n${groupIndent}`); 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 * `inspect()` converts input into string that has the same format
* as printed by `console.log(...)`; * as printed by `console.log(...)`;
*/ */
export function inspect(value: unknown, options?: ConsoleOptions): string { export function inspect(
const opts = options || {}; value: unknown,
{ depth = DEFAULT_MAX_DEPTH }: ConsoleOptions = {}
): string {
if (typeof value === "string") { if (typeof value === "string") {
return value; return value;
} else { } else {
return stringify( return stringify(value, new Set<unknown>(), 0, depth);
value,
new Set<unknown>(),
0,
opts.depth != undefined ? opts.depth : DEFAULT_MAX_DEPTH
);
} }
} }

View file

@ -503,11 +503,11 @@ declare namespace __domTypes {
readonly total: number; readonly total: number;
} }
export interface EventListenerOptions { export interface EventListenerOptions {
capture: boolean; capture?: boolean;
} }
export interface AddEventListenerOptions extends EventListenerOptions { export interface AddEventListenerOptions extends EventListenerOptions {
once: boolean; once?: boolean;
passive: boolean; passive?: boolean;
} }
interface AbortSignal extends EventTarget { interface AbortSignal extends EventTarget {
readonly aborted: boolean; readonly aborted: boolean;

View file

@ -206,8 +206,6 @@ export interface ListenOptions {
transport?: Transport; transport?: Transport;
} }
const listenDefaults = { hostname: "0.0.0.0", transport: "tcp" };
/** Listen announces on the local transport address. /** Listen announces on the local transport address.
* *
* @param options * @param options
@ -229,11 +227,14 @@ export function listen(
options: ListenOptions & { transport?: "tcp" } options: ListenOptions & { transport?: "tcp" }
): Listener; ): Listener;
export function listen(options: ListenOptions & { transport: "udp" }): UDPConn; export function listen(options: ListenOptions & { transport: "udp" }): UDPConn;
export function listen(options: ListenOptions): Listener | UDPConn { export function listen({
const args = { ...listenDefaults, ...options }; port,
const res = netOps.listen(args as netOps.ListenRequest); 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); return new ListenerImpl(res.rid, res.localAddr);
} else { } else {
return new UDPConnImpl(res.rid, res.localAddr); return new UDPConnImpl(res.rid, res.localAddr);
@ -246,8 +247,6 @@ export interface ConnectOptions {
transport?: Transport; transport?: Transport;
} }
const connectDefaults = { hostname: "127.0.0.1", transport: "tcp" };
/** Connects to the address on the named transport. /** Connects to the address on the named transport.
* *
* @param options * @param options
@ -265,8 +264,11 @@ const connectDefaults = { hostname: "127.0.0.1", transport: "tcp" };
* connect({ hostname: "[2001:db8::1]", port: 80 }); * connect({ hostname: "[2001:db8::1]", port: 80 });
* connect({ hostname: "golang.org", port: 80, transport: "tcp" }) * connect({ hostname: "golang.org", port: 80, transport: "tcp" })
*/ */
export async function connect(options: ConnectOptions): Promise<Conn> { export async function connect({
options = Object.assign(connectDefaults, options); port,
const res = await netOps.connect(options as netOps.ConnectRequest); hostname = "127.0.0.1",
transport = "tcp"
}: ConnectOptions): Promise<Conn> {
const res = await netOps.connect({ port, hostname, transport });
return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!); return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!);
} }

View file

@ -6,7 +6,7 @@ export interface ConnectTLSRequest {
transport: Transport; transport: Transport;
hostname: string; hostname: string;
port: number; port: number;
cert_file?: string; certFile?: string;
} }
interface ConnectTLSResponse { interface ConnectTLSResponse {

View file

@ -3,7 +3,6 @@ import { File } from "./files.ts";
import { close } from "./ops/resources.ts"; import { close } from "./ops/resources.ts";
import { ReadCloser, WriteCloser } from "./io.ts"; import { ReadCloser, WriteCloser } from "./io.ts";
import { readAll } from "./buffer.ts"; import { readAll } from "./buffer.ts";
import { assert, unreachable } from "./util.ts";
import { build } from "./build.ts"; import { build } from "./build.ts";
import { kill, runStatus as runStatusOp, run as runOp } from "./ops/process.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'. 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 { function isRid(arg: unknown): arg is number {
return !isNaN(arg as number); return !isNaN(arg as number);
} }
@ -153,57 +140,25 @@ interface RunResponse {
* `opt.stdout`, `opt.stderr` and `opt.stdin` can be specified independently - * `opt.stdout`, `opt.stderr` and `opt.stdin` can be specified independently -
* they can be set to either `ProcessStdio` or `rid` of open file. * they can be set to either `ProcessStdio` or `rid` of open file.
*/ */
export function run(opt: RunOptions): Process { export function run({
assert(opt.args.length > 0); args,
let env: Array<[string, string]> = []; cwd = undefined,
if (opt.env) { env = {},
env = Array.from(Object.entries(opt.env)); stdout = "inherit",
} stderr = "inherit",
stdin = "inherit"
let stdin = stdioMap("inherit"); }: RunOptions): Process {
let stdout = stdioMap("inherit"); const res = runOp({
let stderr = stdioMap("inherit"); args: args.map(String),
let stdinRid = 0; cwd,
let stdoutRid = 0; env: Object.entries(env),
let stderrRid = 0; stdin: isRid(stdin) ? "" : stdin,
stdout: isRid(stdout) ? "" : stdout,
if (opt.stdin) { stderr: isRid(stderr) ? "" : stderr,
if (isRid(opt.stdin)) { stdinRid: isRid(stdin) ? stdin : 0,
stdinRid = opt.stdin; stdoutRid: isRid(stdout) ? stdout : 0,
} else { stderrRid: isRid(stderr) ? stderr : 0
stdin = stdioMap(opt.stdin); }) as RunResponse;
}
}
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);
return new Process(res); return new Process(res);
} }

View file

@ -186,7 +186,7 @@ unitTest(function consoleTestStringifyWithDepth(): void {
); );
assertEquals(stringifyArgs([nestedObj], { depth: 0 }), "[Object]"); assertEquals(stringifyArgs([nestedObj], { depth: 0 }), "[Object]");
assertEquals( assertEquals(
stringifyArgs([nestedObj], { depth: null }), stringifyArgs([nestedObj]),
"{ a: { b: { c: { d: [Object] } } } }" "{ a: { b: { c: { d: [Object] } } } }"
); );
// test inspect is working the same way // test inspect is working the same way

View file

@ -10,14 +10,22 @@ interface ConnectTLSOptions {
hostname?: string; hostname?: string;
certFile?: string; certFile?: string;
} }
const connectTLSDefaults = { hostname: "127.0.0.1", transport: "tcp" };
/** /**
* Establishes a secure connection over TLS (transport layer security). * Establishes a secure connection over TLS (transport layer security).
*/ */
export async function connectTLS(options: ConnectTLSOptions): Promise<Conn> { export async function connectTLS({
options = Object.assign(connectTLSDefaults, options); port,
const res = await tlsOps.connectTLS(options as tlsOps.ConnectTLSRequest); hostname = "127.0.0.1",
transport = "tcp",
certFile = undefined
}: ConnectTLSOptions): Promise<Conn> {
const res = await tlsOps.connectTLS({
port,
hostname,
transport,
certFile
});
return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!); 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" }) * Deno.listenTLS({ port: 443, certFile: "./my_server.crt", keyFile: "./my_server.key" })
*/ */
export function listenTLS(options: ListenTLSOptions): Listener { export function listenTLS({
const hostname = options.hostname || "0.0.0.0"; port,
const transport = options.transport || "tcp"; certFile,
keyFile,
hostname = "0.0.0.0",
transport = "tcp"
}: ListenTLSOptions): Listener {
const res = tlsOps.listenTLS({ const res = tlsOps.listenTLS({
port,
certFile,
keyFile,
hostname, hostname,
port: options.port, transport
transport,
certFile: options.certFile,
keyFile: options.keyFile
}); });
return new TLSListenerImpl(res.rid, res.localAddr); return new TLSListenerImpl(res.rid, res.localAddr);
} }

View file

@ -1,6 +1,5 @@
// 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 { hasOwnProperty } from "../util.ts";
import { TextEncoder } from "./text_encoding.ts"; import { TextEncoder } from "./text_encoding.ts";
import { build } from "../build.ts"; import { build } from "../build.ts";
@ -144,34 +143,29 @@ export class DenoBlob implements domTypes.Blob {
return; return;
} }
options = options || {}; const { ending = "transparent", type = "" } = options ?? {};
// Set ending property's default value to "transparent". if (!containsOnlyASCII(type)) {
if (!hasOwnProperty(options, "ending")) {
options.ending = "transparent";
}
if (options.type && !containsOnlyASCII(options.type)) {
const errMsg = "The 'type' property must consist of ASCII characters."; const errMsg = "The 'type' property must consist of ASCII characters.";
throw new SyntaxError(errMsg); throw new SyntaxError(errMsg);
} }
const bytes = processBlobParts(blobParts!, options); const bytes = processBlobParts(blobParts!, { ending, type });
// Normalize options.type. // Normalize options.type.
let type = options.type ? options.type : ""; let normalizedType = type;
if (type.length) { if (type.length) {
for (let i = 0; i < type.length; ++i) { for (let i = 0; i < type.length; ++i) {
const char = type[i]; const char = type[i];
if (char < "\u0020" || char > "\u007E") { if (char < "\u0020" || char > "\u007E") {
type = ""; normalizedType = "";
break; break;
} }
} }
type = type.toLowerCase(); normalizedType = type.toLowerCase();
} }
// Set Blob object's properties. // Set Blob object's properties.
this[bytesSymbol] = bytes; this[bytesSymbol] = bytes;
this.size = bytes.byteLength; this.size = bytes.byteLength;
this.type = type; this.type = normalizedType;
// Register bytes for internal private use. // Register bytes for internal private use.
blobBytesWeakMap.set(this, bytes); blobBytesWeakMap.set(this, bytes);

View file

@ -11,14 +11,14 @@ export class DomFileImpl extends blob.DenoBlob implements domTypes.DomFile {
fileName: string, fileName: string,
options?: domTypes.FilePropertyBag options?: domTypes.FilePropertyBag
) { ) {
options = options || {}; const { lastModified = Date.now(), ...blobPropertyBag } = options ?? {};
super(fileBits, options); super(fileBits, blobPropertyBag);
// 4.1.2.1 Replace any "/" character (U+002F SOLIDUS) // 4.1.2.1 Replace any "/" character (U+002F SOLIDUS)
// with a ":" (U + 003A COLON) // with a ":" (U + 003A COLON)
this.name = String(fileName).replace(/\u002F/g, "\u003A"); this.name = String(fileName).replace(/\u002F/g, "\u003A");
// 4.1.3.3 If lastModified is not provided, set lastModified to the current // 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. // date and time represented in number of milliseconds since the Unix Epoch.
this.lastModified = options.lastModified || Date.now(); this.lastModified = lastModified;
} }
} }

View file

@ -258,12 +258,12 @@ interface ProgressEvent extends Event {
} }
export interface EventListenerOptions { export interface EventListenerOptions {
capture: boolean; capture?: boolean;
} }
export interface AddEventListenerOptions extends EventListenerOptions { export interface AddEventListenerOptions extends EventListenerOptions {
once: boolean; once?: boolean;
passive: boolean; passive?: boolean;
} }
export interface AbortSignal extends EventTarget { export interface AbortSignal extends EventTarget {

View file

@ -154,11 +154,14 @@ class SingleByteDecoder implements Decoder {
private _index: number[]; private _index: number[];
private _fatal: boolean; private _fatal: boolean;
constructor(index: number[], options: DecoderOptions) { constructor(
if (options.ignoreBOM) { index: number[],
{ ignoreBOM = false, fatal = false }: DecoderOptions = {}
) {
if (ignoreBOM) {
throw new TypeError("Ignoring the BOM is available only with utf-8."); throw new TypeError("Ignoring the BOM is available only with utf-8.");
} }
this._fatal = options.fatal || false; this._fatal = fatal;
this._index = index; this._index = index;
} }
handler(stream: Stream, byte: number): number { handler(stream: Stream, byte: number): number {

View file

@ -58,12 +58,7 @@ export class WorkerImpl extends EventTarget implements Worker {
constructor(specifier: string, options?: WorkerOptions) { constructor(specifier: string, options?: WorkerOptions) {
super(); super();
const { type = "classic", name = "unknown" } = options ?? {};
let type = "classic";
if (options?.type) {
type = options.type;
}
if (type !== "module") { if (type !== "module") {
throw new Error( 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 hasSourceCode = false;
const sourceCode = decoder.decode(new Uint8Array()); const sourceCode = decoder.decode(new Uint8Array());

View file

@ -27,31 +27,31 @@ export interface ArgParsingOptions {
* *
* Defaults to `false`. * Defaults to `false`.
*/ */
"--": boolean; "--"?: boolean;
/** An object mapping string names to strings or arrays of string argument /** An object mapping string names to strings or arrays of string argument
* names to use as aliases */ * names to use as aliases */
alias: Record<string, string | string[]>; alias?: Record<string, string | string[]>;
/** A boolean, string or array of strings to always treat as booleans. If /** A boolean, string or array of strings to always treat as booleans. If
* `true` will treat all double hyphenated arguments without equal signs as * `true` will treat all double hyphenated arguments without equal signs as
* `boolean` (e.g. affects `--foo`, not `-f` or `--foo=bar`) */ * `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. */ /** An object mapping string argument names to default values. */
default: Record<string, unknown>; default?: Record<string, unknown>;
/** When `true`, populate the result `_` with everything after the first /** When `true`, populate the result `_` with everything after the first
* non-option. */ * non-option. */
stopEarly: boolean; stopEarly?: boolean;
/** A string or array of strings argument names to always treat as strings. */ /** 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 /** A function which is invoked with a command line parameter not defined in
* the `options` configuration object. If the function returns `false`, the * the `options` configuration object. If the function returns `false`, the
* unknown option is not added to `parsedArgs`. */ * unknown option is not added to `parsedArgs`. */
unknown: (i: unknown) => unknown; unknown?: (i: unknown) => unknown;
} }
interface Flags { interface Flags {
@ -108,7 +108,7 @@ export function parse(
stopEarly = false, stopEarly = false,
string = [], string = [],
unknown = (i: unknown): unknown => i unknown = (i: unknown): unknown => i
}: Partial<ArgParsingOptions> = {} }: ArgParsingOptions = {}
): Args { ): Args {
const flags: Flags = { const flags: Flags = {
bools: {}, bools: {},

View file

@ -10,7 +10,7 @@ interface MoveOptions {
export async function move( export async function move(
src: string, src: string,
dest: string, dest: string,
options?: MoveOptions { overwrite = false }: MoveOptions = {}
): Promise<void> { ): Promise<void> {
const srcStat = await Deno.stat(src); 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.remove(dest, { recursive: true });
await Deno.rename(src, dest); await Deno.rename(src, dest);
} else { } else {
@ -37,7 +37,7 @@ export async function move(
export function moveSync( export function moveSync(
src: string, src: string,
dest: string, dest: string,
options?: MoveOptions { overwrite = false }: MoveOptions = {}
): void { ): void {
const srcStat = Deno.statSync(src); const srcStat = Deno.statSync(src);
@ -47,7 +47,7 @@ export function moveSync(
); );
} }
if (options && options.overwrite) { if (overwrite) {
Deno.removeSync(dest, { recursive: true }); Deno.removeSync(dest, { recursive: true });
Deno.renameSync(src, dest); Deno.renameSync(src, dest);
} else { } else {

View file

@ -171,7 +171,7 @@ export async function runBenchmarks({
/** Runs specified benchmarks if the enclosing script is main. */ /** Runs specified benchmarks if the enclosing script is main. */
export async function runIfMain( export async function runIfMain(
meta: ImportMeta, meta: ImportMeta,
opts?: BenchmarkRunOptions opts: BenchmarkRunOptions = {}
): Promise<void> { ): Promise<void> {
if (meta.main) { if (meta.main) {
return runBenchmarks(opts); return runBenchmarks(opts);