summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/BUILD.gn45
-rw-r--r--cli/assets.rs59
-rw-r--r--cli/main.rs6
-rw-r--r--cli/ops/compiler.rs19
-rw-r--r--cli/ops/mod.rs7
-rw-r--r--js/assets.ts99
-rw-r--r--js/compiler.ts8
-rw-r--r--js/dispatch.ts1
-rw-r--r--js/globals.ts3
-rw-r--r--js/lib.deno_runtime.d.ts2771
-rw-r--r--rollup.config.js59
-rw-r--r--tests/types.out4
-rw-r--r--tools/target_test.py10
-rw-r--r--tools/ts_library_builder/README.md88
-rw-r--r--tools/ts_library_builder/ast_util.ts499
-rw-r--r--tools/ts_library_builder/build_library.ts569
-rw-r--r--tools/ts_library_builder/main.ts52
-rw-r--r--tools/ts_library_builder/test.ts240
-rw-r--r--tools/ts_library_builder/testdata/api.ts4
-rw-r--r--tools/ts_library_builder/testdata/globals.ts15
-rw-r--r--tools/ts_library_builder/testdata/lib.extra.d.ts7
-rw-r--r--tools/ts_library_builder/testdata/moduleA.ts9
-rw-r--r--tools/ts_library_builder/testdata/moduleB.ts9
-rw-r--r--tools/ts_library_builder/testdata/moduleC.ts18
-rw-r--r--tools/ts_library_builder/testdata/moduleD.ts5
-rw-r--r--tools/ts_library_builder/testdata/moduleE.ts5
-rw-r--r--tools/ts_library_builder/testdata/moduleF.ts1
-rw-r--r--tools/ts_library_builder/tsconfig.json9
-rw-r--r--tsconfig.json1
29 files changed, 2869 insertions, 1753 deletions
diff --git a/cli/BUILD.gn b/cli/BUILD.gn
index 23bc48fda..6704659db 100644
--- a/cli/BUILD.gn
+++ b/cli/BUILD.gn
@@ -61,7 +61,6 @@ if (is_posix) {
}
ts_sources = [
- "../js/assets.ts",
"../js/base64.ts",
"../js/blob.ts",
"../js/body.ts",
@@ -98,6 +97,7 @@ ts_sources = [
"../js/globals.ts",
"../js/headers.ts",
"../js/io.ts",
+ "../js/lib.deno_runtime.d.ts",
"../js/lib.web_assembly.d.ts",
"../js/link.ts",
"../js/location.ts",
@@ -200,55 +200,16 @@ rust_test("cli_test") {
env = [ "CARGO_PKG_VERSION=${deno_cargo_info.version}" ]
}
-# Generates the core TypeScript type library for deno that will be
-# included in the runtime bundle
-run_node("deno_runtime_declaration") {
- out_dir = target_gen_dir
- sources = ts_sources
- outputs = [
- "$out_dir/lib/lib.deno_runtime.d.ts",
- ]
- inputs = ts_sources + [
- "//tools/ts_library_builder/tsconfig.json",
- "//tools/ts_library_builder/main.ts",
- "//tools/ts_library_builder/build_library.ts",
- "//tools/ts_library_builder/ast_util.ts",
- ]
- args = [
- rebase_path("//node_modules/ts-node/dist/bin.js", root_build_dir),
- "--project",
- rebase_path("//tools/ts_library_builder/tsconfig.json"),
- "--skip-ignore",
- rebase_path("//tools/ts_library_builder/main.ts", root_build_dir),
- "--basePath",
- rebase_path("//", root_build_dir),
- "--inline",
- rebase_path("//js/lib.web_assembly.d.ts", root_build_dir),
- "--buildPath",
- rebase_path(root_build_dir, root_build_dir),
- "--outFile",
- rebase_path(outputs[0], root_build_dir),
- "--silent",
- ]
- if (is_debug) {
- args += [ "--debug" ]
- }
-}
-
bundle("main_bundle") {
+ sources = ts_sources
out_dir = "$target_gen_dir/bundle/"
out_name = "main"
- deps = [
- ":deno_runtime_declaration",
- ]
}
bundle("compiler_bundle") {
+ sources = ts_sources
out_dir = "$target_gen_dir/bundle/"
out_name = "compiler"
- deps = [
- ":deno_runtime_declaration",
- ]
}
# Generates $target_gen_dir/snapshot_deno.bin
diff --git a/cli/assets.rs b/cli/assets.rs
new file mode 100644
index 000000000..c7bfc484d
--- /dev/null
+++ b/cli/assets.rs
@@ -0,0 +1,59 @@
+static DENO_RUNTIME: &str = include_str!("../js/lib.deno_runtime.d.ts");
+
+macro_rules! inc {
+ ($e:expr) => {
+ Some(include_str!(concat!(
+ "../third_party/node_modules/typescript/lib/",
+ $e
+ )))
+ };
+}
+
+pub fn get_source_code(name: &str) -> Option<&'static str> {
+ match name {
+ "lib.deno_runtime.d.ts" => Some(DENO_RUNTIME),
+ "lib.es2015.collection.d.ts" => inc!("lib.es2015.collection.d.ts"),
+ "lib.es2015.core.d.ts" => inc!("lib.es2015.core.d.ts"),
+ "lib.es2015.d.ts" => inc!("lib.es2015.d.ts"),
+ "lib.es2015.generator.d.ts" => inc!("lib.es2015.generator.d.ts"),
+ "lib.es2015.iterable.d.ts" => inc!("lib.es2015.iterable.d.ts"),
+ "lib.es2015.promise.d.ts" => inc!("lib.es2015.promise.d.ts"),
+ "lib.es2015.proxy.d.ts" => inc!("lib.es2015.proxy.d.ts"),
+ "lib.es2015.reflect.d.ts" => inc!("lib.es2015.reflect.d.ts"),
+ "lib.es2015.symbol.d.ts" => inc!("lib.es2015.symbol.d.ts"),
+ "lib.es2015.symbol.wellknown.d.ts" => {
+ inc!("lib.es2015.symbol.wellknown.d.ts")
+ }
+ "lib.es2016.array.include.d.ts" => inc!("lib.es2016.array.include.d.ts"),
+ "lib.es2016.d.ts" => inc!("lib.es2016.d.ts"),
+ "lib.es2017.d.ts" => inc!("lib.es2017.d.ts"),
+ "lib.es2017.intl.d.ts" => inc!("lib.es2017.intl.d.ts"),
+ "lib.es2017.object.d.ts" => inc!("lib.es2017.object.d.ts"),
+ "lib.es2017.sharedmemory.d.ts" => inc!("lib.es2017.sharedmemory.d.ts"),
+ "lib.es2017.string.d.ts" => inc!("lib.es2017.string.d.ts"),
+ "lib.es2017.typedarrays.d.ts" => inc!("lib.es2017.typedarrays.d.ts"),
+ "lib.es2018.d.ts" => inc!("lib.es2018.d.ts"),
+ "lib.es2018.asynciterable.d.ts" => inc!("lib.es2018.asynciterable.d.ts"),
+ "lib.es2018.intl.d.ts" => inc!("lib.es2018.intl.d.ts"),
+ "lib.es2018.promise.d.ts" => inc!("lib.es2018.promise.d.ts"),
+ "lib.es2018.regexp.d.ts" => inc!("lib.es2018.regexp.d.ts"),
+ "lib.es2019.d.ts" => inc!("lib.es2019.d.ts"),
+ "lib.es2019.array.d.ts" => inc!("lib.es2019.array.d.ts"),
+ "lib.es2019.object.d.ts" => inc!("lib.es2019.object.d.ts"),
+ "lib.es2019.string.d.ts" => inc!("lib.es2019.string.d.ts"),
+ "lib.es2019.symbol.d.ts" => inc!("lib.es2019.symbol.d.ts"),
+ "lib.es2020.d.ts" => inc!("lib.es2020.d.ts"),
+ "lib.es2020.string.d.ts" => inc!("lib.es2020.string.d.ts"),
+ "lib.es2020.symbol.wellknown.d.ts" => {
+ inc!("lib.es2020.symbol.wellknown.d.ts")
+ }
+ "lib.es5.d.ts" => inc!("lib.es5.d.ts"),
+ "lib.esnext.d.ts" => inc!("lib.esnext.d.ts"),
+ "lib.esnext.array.d.ts" => inc!("lib.esnext.array.d.ts"),
+ "lib.esnext.asynciterable.d.ts" => inc!("lib.esnext.asynciterable.d.ts"),
+ "lib.esnext.bigint.d.ts" => inc!("lib.esnext.bigint.d.ts"),
+ "lib.esnext.intl.d.ts" => inc!("lib.esnext.intl.d.ts"),
+ "lib.esnext.symbol.d.ts" => inc!("lib.esnext.symbol.d.ts"),
+ _ => None,
+ }
+}
diff --git a/cli/main.rs b/cli/main.rs
index a601e68af..53daa84f3 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -18,6 +18,7 @@ extern crate serde_derive;
extern crate url;
mod ansi;
+mod assets;
pub mod compilers;
pub mod deno_dir;
pub mod deno_error;
@@ -127,10 +128,7 @@ fn create_worker_and_state(
}
fn types_command() {
- let content = include_str!(concat!(
- env!("GN_OUT_DIR"),
- "/gen/cli/lib/lib.deno_runtime.d.ts"
- ));
+ let content = assets::get_source_code("lib.deno_runtime.d.ts").unwrap();
println!("{}", content);
}
diff --git a/cli/ops/compiler.rs b/cli/ops/compiler.rs
index 39d3a6d7f..40d25aa74 100644
--- a/cli/ops/compiler.rs
+++ b/cli/ops/compiler.rs
@@ -1,5 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
+use crate::assets;
use crate::state::ThreadSafeState;
use crate::tokio_util;
use deno::*;
@@ -66,3 +67,21 @@ pub fn op_fetch_source_file(
"sourceCode": String::from_utf8(out.source_code).unwrap(),
})))
}
+
+#[derive(Deserialize)]
+struct FetchAssetArgs {
+ name: String,
+}
+
+pub fn op_fetch_asset(
+ _state: &ThreadSafeState,
+ args: Value,
+ _zero_copy: Option<PinnedBuf>,
+) -> Result<JsonOp, ErrBox> {
+ let args: FetchAssetArgs = serde_json::from_value(args)?;
+ if let Some(source_code) = assets::get_source_code(&args.name) {
+ Ok(JsonOp::Sync(json!(source_code)))
+ } else {
+ panic!("op_fetch_asset bad asset {}", args.name)
+ }
+}
diff --git a/cli/ops/mod.rs b/cli/ops/mod.rs
index 106948492..1f07acc65 100644
--- a/cli/ops/mod.rs
+++ b/cli/ops/mod.rs
@@ -80,6 +80,7 @@ pub const OP_READ_LINK: OpId = 53;
pub const OP_TRUNCATE: OpId = 54;
pub const OP_MAKE_TEMP_DIR: OpId = 55;
pub const OP_CWD: OpId = 56;
+pub const OP_FETCH_ASSET: OpId = 57;
pub fn dispatch(
state: &ThreadSafeState,
@@ -293,6 +294,12 @@ pub fn dispatch(
dispatch_json::dispatch(fs::op_make_temp_dir, state, control, zero_copy)
}
OP_CWD => dispatch_json::dispatch(fs::op_cwd, state, control, zero_copy),
+ OP_FETCH_ASSET => dispatch_json::dispatch(
+ compiler::op_fetch_asset,
+ state,
+ control,
+ zero_copy,
+ ),
_ => panic!("bad op_id"),
};
diff --git a/js/assets.ts b/js/assets.ts
deleted file mode 100644
index 89ca7ac86..000000000
--- a/js/assets.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-// eslint-disable-next-line @typescript-eslint/no-triple-slash-reference
-/// <reference path="./plugins.d.ts" />
-
-// There is a rollup plugin that will inline any module ending with `!string`
-
-// Generated default library
-import libDts from "gen/cli/lib/lib.deno_runtime.d.ts!string";
-
-// Static libraries
-import libEs2015Dts from "/third_party/node_modules/typescript/lib/lib.es2015.d.ts!string";
-import libEs2015CollectionDts from "/third_party/node_modules/typescript/lib/lib.es2015.collection.d.ts!string";
-import libEs2015CoreDts from "/third_party/node_modules/typescript/lib/lib.es2015.core.d.ts!string";
-import libEs2015GeneratorDts from "/third_party/node_modules/typescript/lib/lib.es2015.generator.d.ts!string";
-import libEs2015IterableDts from "/third_party/node_modules/typescript/lib/lib.es2015.iterable.d.ts!string";
-import libEs2015PromiseDts from "/third_party/node_modules/typescript/lib/lib.es2015.promise.d.ts!string";
-import libEs2015ProxyDts from "/third_party/node_modules/typescript/lib/lib.es2015.proxy.d.ts!string";
-import libEs2015ReflectDts from "/third_party/node_modules/typescript/lib/lib.es2015.reflect.d.ts!string";
-import libEs2015SymbolDts from "/third_party/node_modules/typescript/lib/lib.es2015.symbol.d.ts!string";
-import libEs2015SymbolWellknownDts from "/third_party/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts!string";
-import libEs2016Dts from "/third_party/node_modules/typescript/lib/lib.es2016.d.ts!string";
-import libEs2016ArrayIncludeDts from "/third_party/node_modules/typescript/lib/lib.es2016.array.include.d.ts!string";
-import libEs2017Dts from "/third_party/node_modules/typescript/lib/lib.es2017.d.ts!string";
-import libEs2017IntlDts from "/third_party/node_modules/typescript/lib/lib.es2017.intl.d.ts!string";
-import libEs2017ObjectDts from "/third_party/node_modules/typescript/lib/lib.es2017.object.d.ts!string";
-import libEs2017SharedmemoryDts from "/third_party/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts!string";
-import libEs2017StringDts from "/third_party/node_modules/typescript/lib/lib.es2017.string.d.ts!string";
-import libEs2017TypedarraysDts from "/third_party/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts!string";
-import libEs2018Dts from "/third_party/node_modules/typescript/lib/lib.es2018.d.ts!string";
-import libEs2018AsyncIterableDts from "/third_party/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts!string";
-import libEs2018IntlDts from "/third_party/node_modules/typescript/lib/lib.es2018.intl.d.ts!string";
-import libEs2018PromiseDts from "/third_party/node_modules/typescript/lib/lib.es2018.promise.d.ts!string";
-import libEs2018RegexpDts from "/third_party/node_modules/typescript/lib/lib.es2018.regexp.d.ts!string";
-import libEs2019Dts from "/third_party/node_modules/typescript/lib/lib.es2019.d.ts!string";
-import libEs2019ArrayDts from "/third_party/node_modules/typescript/lib/lib.es2019.array.d.ts!string";
-import libEs2019ObjectDts from "/third_party/node_modules/typescript/lib/lib.es2019.object.d.ts!string";
-import libEs2019StringDts from "/third_party/node_modules/typescript/lib/lib.es2019.string.d.ts!string";
-import libEs2019SymbolDts from "/third_party/node_modules/typescript/lib/lib.es2019.symbol.d.ts!string";
-import libEs2020Dts from "/third_party/node_modules/typescript/lib/lib.es2020.d.ts!string";
-import libEs2020String from "/third_party/node_modules/typescript/lib/lib.es2020.string.d.ts!string";
-import libEs2020SymbolWellknownDts from "/third_party/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts!string";
-import libEs5Dts from "/third_party/node_modules/typescript/lib/lib.es5.d.ts!string";
-import libEsnextArrayDts from "/third_party/node_modules/typescript/lib/lib.esnext.array.d.ts!string";
-import libEsnextAsynciterablesDts from "/third_party/node_modules/typescript/lib/lib.esnext.asynciterable.d.ts!string";
-import libEsnextBigintDts from "/third_party/node_modules/typescript/lib/lib.esnext.bigint.d.ts!string";
-import libEsnextDts from "/third_party/node_modules/typescript/lib/lib.esnext.d.ts!string";
-import libEsnextIntlDts from "/third_party/node_modules/typescript/lib/lib.esnext.intl.d.ts!string";
-import libEsnextSymbolDts from "/third_party/node_modules/typescript/lib/lib.esnext.symbol.d.ts!string";
-
-// Default static libraries for all compile jobs
-const defaultAssets: { [key: string]: string } = {
- "lib.es2015.collection.d.ts": libEs2015CollectionDts,
- "lib.es2015.core.d.ts": libEs2015CoreDts,
- "lib.es2015.d.ts": libEs2015Dts,
- "lib.es2015.generator.d.ts": libEs2015GeneratorDts,
- "lib.es2015.iterable.d.ts": libEs2015IterableDts,
- "lib.es2015.promise.d.ts": libEs2015PromiseDts,
- "lib.es2015.proxy.d.ts": libEs2015ProxyDts,
- "lib.es2015.reflect.d.ts": libEs2015ReflectDts,
- "lib.es2015.symbol.d.ts": libEs2015SymbolDts,
- "lib.es2015.symbol.wellknown.d.ts": libEs2015SymbolWellknownDts,
- "lib.es2016.array.include.d.ts": libEs2016ArrayIncludeDts,
- "lib.es2016.d.ts": libEs2016Dts,
- "lib.es2017.d.ts": libEs2017Dts,
- "lib.es2017.intl.d.ts": libEs2017IntlDts,
- "lib.es2017.object.d.ts": libEs2017ObjectDts,
- "lib.es2017.sharedmemory.d.ts": libEs2017SharedmemoryDts,
- "lib.es2017.string.d.ts": libEs2017StringDts,
- "lib.es2017.typedarrays.d.ts": libEs2017TypedarraysDts,
- "lib.es2018.d.ts": libEs2018Dts,
- "lib.es2018.asynciterable.d.ts": libEs2018AsyncIterableDts,
- "lib.es2018.intl.d.ts": libEs2018IntlDts,
- "lib.es2018.promise.d.ts": libEs2018PromiseDts,
- "lib.es2018.regexp.d.ts": libEs2018RegexpDts,
- "lib.es2019.d.ts": libEs2019Dts,
- "lib.es2019.array.d.ts": libEs2019ArrayDts,
- "lib.es2019.object.d.ts": libEs2019ObjectDts,
- "lib.es2019.string.d.ts": libEs2019StringDts,
- "lib.es2019.symbol.d.ts": libEs2019SymbolDts,
- "lib.es2020.d.ts": libEs2020Dts,
- "lib.es2020.string.d.ts": libEs2020String,
- "lib.es2020.symbol.wellknown.d.ts": libEs2020SymbolWellknownDts,
- "lib.es5.d.ts": libEs5Dts,
- "lib.esnext.d.ts": libEsnextDts,
- "lib.esnext.array.d.ts": libEsnextArrayDts,
- "lib.esnext.asynciterable.d.ts": libEsnextAsynciterablesDts,
- "lib.esnext.bigint.d.ts": libEsnextBigintDts,
- "lib.esnext.intl.d.ts": libEsnextIntlDts,
- "lib.esnext.symbol.d.ts": libEsnextSymbolDts
-};
-
-// assests for normal compile jobs
-// @internal
-export const assetSourceCode: { [key: string]: string } = {
- // Generated library
- "lib.deno_runtime.d.ts": libDts,
- ...defaultAssets
-};
diff --git a/js/compiler.ts b/js/compiler.ts
index e10dc50db..71b1b06c9 100644
--- a/js/compiler.ts
+++ b/js/compiler.ts
@@ -1,6 +1,5 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import * as ts from "typescript";
-import { assetSourceCode } from "./assets";
import { bold, cyan, yellow } from "./colors";
import { Console } from "./console";
import { core } from "./core";
@@ -128,6 +127,10 @@ interface EmitResult {
diagnostics?: Diagnostic;
}
+function fetchAsset(name: string): string {
+ return sendSync(dispatch.OP_FETCH_ASSET, { name });
+}
+
/** Ops to Rust to resolve and fetch a modules meta data. */
function fetchSourceFile(specifier: string, referrer: string): SourceFile {
util.log("compiler.fetchSourceFile", { specifier, referrer });
@@ -222,8 +225,7 @@ class Host implements ts.CompilerHost {
const assetName = moduleName.includes(".")
? moduleName
: `${moduleName}.d.ts`;
- assert(assetName in assetSourceCode, `No such asset "${assetName}"`);
- const sourceCode = assetSourceCode[assetName];
+ const sourceCode = fetchAsset(assetName);
const sourceFile = {
moduleName,
filename: specifier,
diff --git a/js/dispatch.ts b/js/dispatch.ts
index dfa276cda..af91a9b9e 100644
--- a/js/dispatch.ts
+++ b/js/dispatch.ts
@@ -59,6 +59,7 @@ export const OP_READ_LINK = 53;
export const OP_TRUNCATE = 54;
export const OP_MAKE_TEMP_DIR = 55;
export const OP_CWD = 56;
+export const OP_FETCH_ASSET = 57;
export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void {
switch (opId) {
diff --git a/js/globals.ts b/js/globals.ts
index 93495ff18..b47cd80f3 100644
--- a/js/globals.ts
+++ b/js/globals.ts
@@ -37,9 +37,6 @@ import { core } from "./core";
// file are tracked and created as part of default library that is built into
// Deno, we only need to declare the enough to compile Deno.
declare global {
- const console: consoleTypes.Console;
- const setTimeout: typeof timers.setTimeout;
-
interface CallSite {
getThis(): unknown;
getTypeName(): string;
diff --git a/js/lib.deno_runtime.d.ts b/js/lib.deno_runtime.d.ts
new file mode 100644
index 000000000..bbdc1fcb9
--- /dev/null
+++ b/js/lib.deno_runtime.d.ts
@@ -0,0 +1,2771 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/no-empty-interface */
+
+/// <reference no-default-lib="true" />
+/// <reference lib="esnext" />
+
+declare namespace Deno {
+ // @url js/os.d.ts
+
+ /** The current process id of the runtime. */
+ export let pid: number;
+ /** Reflects the NO_COLOR environment variable: https://no-color.org/ */
+ export let noColor: boolean;
+ /** Check if running in terminal.
+ *
+ * console.log(Deno.isTTY().stdout);
+ */
+ export function isTTY(): {
+ stdin: boolean;
+ stdout: boolean;
+ stderr: boolean;
+ };
+ /** Exit the Deno process with optional exit code. */
+ export function exit(code?: number): never;
+ /** Returns a snapshot of the environment variables at invocation. Mutating a
+ * property in the object will set that variable in the environment for
+ * the process. The environment object will only accept `string`s
+ * as values.
+ *
+ * const myEnv = Deno.env();
+ * console.log(myEnv.SHELL);
+ * myEnv.TEST_VAR = "HELLO";
+ * const newEnv = Deno.env();
+ * console.log(myEnv.TEST_VAR == newEnv.TEST_VAR);
+ */
+ export function env(): {
+ [index: string]: string;
+ };
+ /**
+ * Returns the current user's home directory.
+ * Requires the `--allow-env` flag.
+ */
+ export function homeDir(): string;
+ /**
+ * Returns the path to the current deno executable.
+ * Requires the `--allow-env` flag.
+ */
+ export function execPath(): string;
+
+ // @url js/dir.d.ts
+
+ /**
+ * `cwd()` Return a string representing the current working directory.
+ * If the current directory can be reached via multiple paths
+ * (due to symbolic links), `cwd()` may return
+ * any one of them.
+ * throws `NotFound` exception if directory not available
+ */
+ export function cwd(): string;
+ /**
+ * `chdir()` Change the current working directory to path.
+ * throws `NotFound` exception if directory not available
+ */
+ export function chdir(directory: string): void;
+
+ // @url js/io.d.ts
+
+ export const EOF: null;
+ export type EOF = null;
+ export enum SeekMode {
+ SEEK_START = 0,
+ SEEK_CURRENT = 1,
+ SEEK_END = 2
+ }
+ export interface Reader {
+ /** Reads up to p.byteLength bytes into `p`. It resolves to the number
+ * of bytes read (`0` < `n` <= `p.byteLength`) and rejects if any error encountered.
+ * Even if `read()` returns `n` < `p.byteLength`, it may use all of `p` as
+ * scratch space during the call. If some data is available but not
+ * `p.byteLength` bytes, `read()` conventionally returns what is available
+ * instead of waiting for more.
+ *
+ * When `read()` encounters end-of-file condition, it returns EOF symbol.
+ *
+ * When `read()` encounters an error, it rejects with an error.
+ *
+ * Callers should always process the `n` > `0` bytes returned before
+ * considering the EOF. Doing so correctly handles I/O errors that happen
+ * after reading some bytes and also both of the allowed EOF behaviors.
+ *
+ * Implementations must not retain `p`.
+ */
+ read(p: Uint8Array): Promise<number | EOF>;
+ }
+ export interface SyncReader {
+ readSync(p: Uint8Array): number | EOF;
+ }
+ export interface Writer {
+ /** Writes `p.byteLength` bytes from `p` to the underlying data
+ * stream. It resolves to the number of bytes written from `p` (`0` <= `n` <=
+ * `p.byteLength`) and any error encountered that caused the write to stop
+ * early. `write()` must return a non-null error if it returns `n` <
+ * `p.byteLength`. write() must not modify the slice data, even temporarily.
+ *
+ * Implementations must not retain `p`.
+ */
+ write(p: Uint8Array): Promise<number>;
+ }
+ export interface SyncWriter {
+ writeSync(p: Uint8Array): number;
+ }
+ export interface Closer {
+ close(): void;
+ }
+ export interface Seeker {
+ /** Seek sets the offset for the next `read()` or `write()` to offset,
+ * interpreted according to `whence`: `SeekStart` means relative to the start
+ * of the file, `SeekCurrent` means relative to the current offset, and
+ * `SeekEnd` means relative to the end. Seek returns the new offset relative
+ * to the start of the file and an error, if any.
+ *
+ * Seeking to an offset before the start of the file is an error. Seeking to
+ * any positive offset is legal, but the behavior of subsequent I/O operations
+ * on the underlying object is implementation-dependent.
+ */
+ seek(offset: number, whence: SeekMode): Promise<void>;
+ }
+ export interface SyncSeeker {
+ seekSync(offset: number, whence: SeekMode): void;
+ }
+ export interface ReadCloser extends Reader, Closer {}
+ export interface WriteCloser extends Writer, Closer {}
+ export interface ReadSeeker extends Reader, Seeker {}
+ export interface WriteSeeker extends Writer, Seeker {}
+ export interface ReadWriteCloser extends Reader, Writer, Closer {}
+ export interface ReadWriteSeeker extends Reader, Writer, Seeker {}
+ /** Copies from `src` to `dst` until either `EOF` is reached on `src`
+ * or an error occurs. It returns the number of bytes copied and the first
+ * error encountered while copying, if any.
+ *
+ * Because `copy()` is defined to read from `src` until `EOF`, it does not
+ * treat an `EOF` from `read()` as an error to be reported.
+ */
+ export function copy(dst: Writer, src: Reader): Promise<number>;
+ /** Turns `r` into async iterator.
+ *
+ * for await (const chunk of toAsyncIterator(reader)) {
+ * console.log(chunk)
+ * }
+ */
+ export function toAsyncIterator(r: Reader): AsyncIterableIterator<Uint8Array>;
+
+ // @url js/files.d.ts
+
+ /** Open a file and return an instance of the `File` object
+ * synchronously.
+ *
+ * const file = Deno.openSync("/foo/bar.txt");
+ */
+ export function openSync(filename: string, mode?: OpenMode): File;
+ /** Open a file and return an instance of the `File` object.
+ *
+ * (async () => {
+ * const file = await Deno.open("/foo/bar.txt");
+ * })();
+ */
+ export function open(filename: string, mode?: OpenMode): Promise<File>;
+ /** Read synchronously from a file ID into an array buffer.
+ *
+ * Return `number | EOF` for the operation.
+ *
+ * const file = Deno.openSync("/foo/bar.txt");
+ * const buf = new Uint8Array(100);
+ * const nread = Deno.readSync(file.rid, buf);
+ * const text = new TextDecoder().decode(buf);
+ *
+ */
+ export function readSync(rid: number, p: Uint8Array): number | EOF;
+ /** Read from a file ID into an array buffer.
+ *
+ * Resolves with the `number | EOF` for the operation.
+ *
+ * (async () => {
+ * const file = await Deno.open("/foo/bar.txt");
+ * const buf = new Uint8Array(100);
+ * const nread = await Deno.read(file.rid, buf);
+ * const text = new TextDecoder().decode(buf);
+ * })();
+ */
+ export function read(rid: number, p: Uint8Array): Promise<number | EOF>;
+ /** Write synchronously to the file ID the contents of the array buffer.
+ *
+ * Resolves with the number of bytes written.
+ *
+ * const encoder = new TextEncoder();
+ * const data = encoder.encode("Hello world\n");
+ * const file = Deno.openSync("/foo/bar.txt");
+ * Deno.writeSync(file.rid, data);
+ */
+ export function writeSync(rid: number, p: Uint8Array): number;
+ /** Write to the file ID the contents of the array buffer.
+ *
+ * Resolves with the number of bytes written.
+ *
+ * (async () => {
+ * const encoder = new TextEncoder();
+ * const data = encoder.encode("Hello world\n");
+ * const file = await Deno.open("/foo/bar.txt");
+ * await Deno.write(file.rid, data);
+ * })();
+ *
+ */
+ export function write(rid: number, p: Uint8Array): Promise<number>;
+ /** Seek a file ID synchronously to the given offset under mode given by `whence`.
+ *
+ * const file = Deno.openSync("/foo/bar.txt");
+ * Deno.seekSync(file.rid, 0, 0);
+ */
+ export function seekSync(rid: number, offset: number, whence: SeekMode): void;
+ /** Seek a file ID to the given offset under mode given by `whence`.
+ *
+ * (async () => {
+ * const file = await Deno.open("/foo/bar.txt");
+ * await Deno.seek(file.rid, 0, 0);
+ * })();
+ */
+ export function seek(
+ rid: number,
+ offset: number,
+ whence: SeekMode
+ ): Promise<void>;
+ /** Close the file ID. */
+ export function close(rid: number): void;
+ /** The Deno abstraction for reading and writing files. */
+ export class File
+ implements
+ Reader,
+ SyncReader,
+ Writer,
+ SyncWriter,
+ Seeker,
+ SyncSeeker,
+ Closer {
+ readonly rid: number;
+ constructor(rid: number);
+ write(p: Uint8Array): Promise<number>;
+ writeSync(p: Uint8Array): number;
+ read(p: Uint8Array): Promise<number | EOF>;
+ readSync(p: Uint8Array): number | EOF;
+ seek(offset: number, whence: SeekMode): Promise<void>;
+ seekSync(offset: number, whence: SeekMode): void;
+ close(): void;
+ }
+ /** An instance of `File` for stdin. */
+ export const stdin: File;
+ /** An instance of `File` for stdout. */
+ export const stdout: File;
+ /** An instance of `File` for stderr. */
+ export const stderr: File;
+ export type OpenMode =
+ | "r"
+ /** Read-write. Start at beginning of file. */
+ | "r+"
+ /** Write-only. Opens and truncates existing file or creates new one for
+ * writing only.
+ */
+ | "w"
+ /** Read-write. Opens and truncates existing file or creates new one for
+ * writing and reading.
+ */
+ | "w+"
+ /** Write-only. Opens existing file or creates new one. Each write appends
+ * content to the end of file.
+ */
+ | "a"
+ /** Read-write. Behaves like "a" and allows to read from file. */
+ | "a+"
+ /** Write-only. Exclusive create - creates new file only if one doesn't exist
+ * already.
+ */
+ | "x"
+ /** Read-write. Behaves like `x` and allows to read from file. */
+ | "x+";
+
+ // @url js/buffer.d.ts
+
+ /** A Buffer is a variable-sized buffer of bytes with read() and write()
+ * methods. Based on https://golang.org/pkg/bytes/#Buffer
+ */
+ export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
+ private buf;
+ private off;
+ constructor(ab?: ArrayBuffer);
+ /** bytes() returns a slice holding the unread portion of the buffer.
+ * The slice is valid for use only until the next buffer modification (that
+ * is, only until the next call to a method like read(), write(), reset(), or
+ * truncate()). The slice aliases the buffer content at least until the next
+ * buffer modification, so immediate changes to the slice will affect the
+ * result of future reads.
+ */
+ bytes(): Uint8Array;
+ /** toString() returns the contents of the unread portion of the buffer
+ * as a string. Warning - if multibyte characters are present when data is
+ * flowing through the buffer, this method may result in incorrect strings
+ * due to a character being split.
+ */
+ toString(): string;
+ /** empty() returns whether the unread portion of the buffer is empty. */
+ empty(): boolean;
+ /** length is a getter that returns the number of bytes of the unread
+ * portion of the buffer
+ */
+ readonly length: number;
+ /** Returns the capacity of the buffer's underlying byte slice, that is,
+ * the total space allocated for the buffer's data.
+ */
+ readonly capacity: number;
+ /** truncate() discards all but the first n unread bytes from the buffer but
+ * continues to use the same allocated storage. It throws if n is negative or
+ * greater than the length of the buffer.
+ */
+ truncate(n: number): void;
+ /** reset() resets the buffer to be empty, but it retains the underlying
+ * storage for use by future writes. reset() is the same as truncate(0)
+ */
+ reset(): void;
+ /** _tryGrowByReslice() is a version of grow for the fast-case
+ * where the internal buffer only needs to be resliced. It returns the index
+ * where bytes should be written and whether it succeeded.
+ * It returns -1 if a reslice was not needed.
+ */
+ private _tryGrowByReslice;
+ private _reslice;
+ /** readSync() reads the next len(p) bytes from the buffer or until the buffer
+ * is drained. The return value n is the number of bytes read. If the
+ * buffer has no data to return, eof in the response will be true.
+ */
+ readSync(p: Uint8Array): number | EOF;
+ read(p: Uint8Array): Promise<number | EOF>;
+ writeSync(p: Uint8Array): number;
+ write(p: Uint8Array): Promise<number>;
+ /** _grow() grows the buffer to guarantee space for n more bytes.
+ * It returns the index where bytes should be written.
+ * If the buffer can't grow it will throw with ErrTooLarge.
+ */
+ private _grow;
+ /** grow() grows the buffer's capacity, if necessary, to guarantee space for
+ * another n bytes. After grow(n), at least n bytes can be written to the
+ * buffer without another allocation. If n is negative, grow() will panic. If
+ * the buffer can't grow it will throw ErrTooLarge.
+ * Based on https://golang.org/pkg/bytes/#Buffer.Grow
+ */
+ grow(n: number): void;
+ /** readFrom() reads data from r until EOF and appends it to the buffer,
+ * growing the buffer as needed. It returns the number of bytes read. If the
+ * buffer becomes too large, readFrom will panic with ErrTooLarge.
+ * Based on https://golang.org/pkg/bytes/#Buffer.ReadFrom
+ */
+ readFrom(r: Reader): Promise<number>;
+ /** Sync version of `readFrom`
+ */
+ readFromSync(r: SyncReader): number;
+ }
+ /** Read `r` until EOF and return the content as `Uint8Array`.
+ */
+ export function readAll(r: Reader): Promise<Uint8Array>;
+ /** Read synchronously `r` until EOF and return the content as `Uint8Array`.
+ */
+ export function readAllSync(r: SyncReader): Uint8Array;
+ /** Write all the content of `arr` to `w`.
+ */
+ export function writeAll(w: Writer, arr: Uint8Array): Promise<void>;
+ /** Write synchronously all the content of `arr` to `w`.
+ */
+ export function writeAllSync(w: SyncWriter, arr: Uint8Array): void;
+
+ // @url js/mkdir.d.ts
+
+ /** Creates a new directory with the specified path synchronously.
+ * If `recursive` is set to true, nested directories will be created (also known
+ * as "mkdir -p").
+ * `mode` sets permission bits (before umask) on UNIX and does nothing on
+ * Windows.
+ *
+ * Deno.mkdirSync("new_dir");
+ * Deno.mkdirSync("nested/directories", true);
+ */
+ export function mkdirSync(
+ path: string,
+ recursive?: boolean,
+ mode?: number
+ ): void;
+ /** Creates a new directory with the specified path.
+ * If `recursive` is set to true, nested directories will be created (also known
+ * as "mkdir -p").
+ * `mode` sets permission bits (before umask) on UNIX and does nothing on
+ * Windows.
+ *
+ * await Deno.mkdir("new_dir");
+ * await Deno.mkdir("nested/directories", true);
+ */
+ export function mkdir(
+ path: string,
+ recursive?: boolean,
+ mode?: number
+ ): Promise<void>;
+
+ // @url js/make_temp_dir.d.ts
+
+ export interface MakeTempDirOptions {
+ dir?: string;
+ prefix?: string;
+ suffix?: string;
+ }
+ /** makeTempDirSync is the synchronous version of `makeTempDir`.
+ *
+ * const tempDirName0 = Deno.makeTempDirSync();
+ * const tempDirName1 = Deno.makeTempDirSync({ prefix: 'my_temp' });
+ */
+ export function makeTempDirSync(options?: MakeTempDirOptions): string;
+ /** makeTempDir creates a new temporary directory in the directory `dir`, its
+ * name beginning with `prefix` and ending with `suffix`.
+ * It returns the full path to the newly created directory.
+ * If `dir` is unspecified, tempDir uses the default directory for temporary
+ * files. Multiple programs calling tempDir simultaneously will not choose the
+ * same directory. It is the caller's responsibility to remove the directory
+ * when no longer needed.
+ *
+ * const tempDirName0 = await Deno.makeTempDir();
+ * const tempDirName1 = await Deno.makeTempDir({ prefix: 'my_temp' });
+ */
+ export function makeTempDir(options?: MakeTempDirOptions): Promise<string>;
+
+ // @url js/chmod.d.ts
+
+ /** Changes the permission of a specific file/directory of specified path
+ * synchronously.
+ *
+ * Deno.chmodSync("/path/to/file", 0o666);
+ */
+ export function chmodSync(path: string, mode: number): void;
+ /** Changes the permission of a specific file/directory of specified path.
+ *
+ * await Deno.chmod("/path/to/file", 0o666);
+ */
+ export function chmod(path: string, mode: number): Promise<void>;
+
+ // @url js/chown.d.ts
+
+ /**
+ * Change owner of a regular file or directory synchronously. Unix only at the moment.
+ * @param path path to the file
+ * @param uid user id of the new owner
+ * @param gid group id of the new owner
+ */
+ export function chownSync(path: string, uid: number, gid: number): void;
+ /**
+ * Change owner of a regular file or directory asynchronously. Unix only at the moment.
+ * @param path path to the file
+ * @param uid user id of the new owner
+ * @param gid group id of the new owner
+ */
+ export function chown(path: string, uid: number, gid: number): Promise<void>;
+
+ // @url js/utime.d.ts
+
+ /** Synchronously changes the access and modification times of a file system
+ * object referenced by `filename`. Given times are either in seconds
+ * (Unix epoch time) or as `Date` objects.
+ *
+ * Deno.utimeSync("myfile.txt", 1556495550, new Date());
+ */
+ export function utimeSync(
+ filename: string,
+ atime: number | Date,
+ mtime: number | Date
+ ): void;
+ /** Changes the access and modification times of a file system object
+ * referenced by `filename`. Given times are either in seconds
+ * (Unix epoch time) or as `Date` objects.
+ *
+ * await Deno.utime("myfile.txt", 1556495550, new Date());
+ */
+ export function utime(
+ filename: string,
+ atime: number | Date,
+ mtime: number | Date
+ ): Promise<void>;
+
+ // @url js/remove.d.ts
+
+ export interface RemoveOption {
+ recursive?: boolean;
+ }
+ /** Removes the named file or directory synchronously. Would throw
+ * error if permission denied, not found, or directory not empty if `recursive`
+ * set to false.
+ * `recursive` is set to false by default.
+ *
+ * Deno.removeSync("/path/to/dir/or/file", {recursive: false});
+ */
+ export function removeSync(path: string, options?: RemoveOption): void;
+ /** Removes the named file or directory. Would throw error if
+ * permission denied, not found, or directory not empty if `recursive` set
+ * to false.
+ * `recursive` is set to false by default.
+ *
+ * await Deno.remove("/path/to/dir/or/file", {recursive: false});
+ */
+ export function remove(path: string, options?: RemoveOption): Promise<void>;
+
+ // @url js/rename.d.ts
+
+ /** Synchronously renames (moves) `oldpath` to `newpath`. If `newpath` already
+ * exists and is not a directory, `renameSync()` replaces it. OS-specific
+ * restrictions may apply when `oldpath` and `newpath` are in different
+ * directories.
+ *
+ * Deno.renameSync("old/path", "new/path");
+ */
+ export function renameSync(oldpath: string, newpath: string): void;
+ /** Renames (moves) `oldpath` to `newpath`. If `newpath` already exists and is
+ * not a directory, `rename()` replaces it. OS-specific restrictions may apply
+ * when `oldpath` and `newpath` are in different directories.
+ *
+ * await Deno.rename("old/path", "new/path");
+ */
+ export function rename(oldpath: string, newpath: string): Promise<void>;
+
+ // @url js/read_file.d.ts
+
+ /** Read the entire contents of a file synchronously.
+ *
+ * const decoder = new TextDecoder("utf-8");
+ * const data = Deno.readFileSync("hello.txt");
+ * console.log(decoder.decode(data));
+ */
+ export function readFileSync(filename: string): Uint8Array;
+ /** Read the entire contents of a file.
+ *
+ * const decoder = new TextDecoder("utf-8");
+ * const data = await Deno.readFile("hello.txt");
+ * console.log(decoder.decode(data));
+ */
+ export function readFile(filename: string): Promise<Uint8Array>;
+
+ // @url js/file_info.d.ts
+
+ /** A FileInfo describes a file and is returned by `stat`, `lstat`,
+ * `statSync`, `lstatSync`.
+ */
+ export interface FileInfo {
+ /** The size of the file, in bytes. */
+ len: number;
+ /** The last modification time of the file. This corresponds to the `mtime`
+ * field from `stat` on Unix and `ftLastWriteTime` on Windows. This may not
+ * be available on all platforms.
+ */
+ modified: number | null;
+ /** The last access time of the file. This corresponds to the `atime`
+ * field from `stat` on Unix and `ftLastAccessTime` on Windows. This may not
+ * be available on all platforms.
+ */
+ accessed: number | null;
+ /** The last access time of the file. This corresponds to the `birthtime`
+ * field from `stat` on Unix and `ftCreationTime` on Windows. This may not
+ * be available on all platforms.
+ */
+ created: number | null;
+ /** The underlying raw st_mode bits that contain the standard Unix permissions
+ * for this file/directory. TODO Match behavior with Go on windows for mode.
+ */
+ mode: number | null;
+ /** The file or directory name. */
+ name: string | null;
+ /** Returns whether this is info for a regular file. This result is mutually
+ * exclusive to `FileInfo.isDirectory` and `FileInfo.isSymlink`.
+ */
+ isFile(): boolean;
+ /** Returns whether this is info for a regular directory. This result is
+ * mutually exclusive to `FileInfo.isFile` and `FileInfo.isSymlink`.
+ */
+ isDirectory(): boolean;
+ /** Returns whether this is info for a symlink. This result is
+ * mutually exclusive to `FileInfo.isFile` and `FileInfo.isDirectory`.
+ */
+ isSymlink(): boolean;
+ }
+
+ // @url js/read_dir.d.ts
+
+ /** Reads the directory given by path and returns a list of file info
+ * synchronously.
+ *
+ * const files = Deno.readDirSync("/");
+ */
+ export function readDirSync(path: string): FileInfo[];
+ /** Reads the directory given by path and returns a list of file info.
+ *
+ * const files = await Deno.readDir("/");
+ */
+ export function readDir(path: string): Promise<FileInfo[]>;
+
+ // @url js/copy_file.d.ts
+
+ /** Copies the contents of a file to another by name synchronously.
+ * Creates a new file if target does not exists, and if target exists,
+ * overwrites original content of the target file.
+ *
+ * It would also copy the permission of the original file
+ * to the destination.
+ *
+ * Deno.copyFileSync("from.txt", "to.txt");
+ */
+ export function copyFileSync(from: string, to: string): void;
+ /** Copies the contents of a file to another by name.
+ *
+ * Creates a new file if target does not exists, and if target exists,
+ * overwrites original content of the target file.
+ *
+ * It would also copy the permission of the original file
+ * to the destination.
+ *
+ * await Deno.copyFile("from.txt", "to.txt");
+ */
+ export function copyFile(from: string, to: string): Promise<void>;
+
+ // @url js/read_link.d.ts
+
+ /** Returns the destination of the named symbolic link synchronously.
+ *
+ * const targetPath = Deno.readlinkSync("symlink/path");
+ */
+ export function readlinkSync(name: string): string;
+ /** Returns the destination of the named symbolic link.
+ *
+ * const targetPath = await Deno.readlink("symlink/path");
+ */
+ export function readlink(name: string): Promise<string>;
+
+ // @url js/stat.d.ts
+
+ interface StatResponse {
+ isFile: boolean;
+ isSymlink: boolean;
+ len: number;
+ modified: number;
+ accessed: number;
+ created: number;
+ mode: number;
+ hasMode: boolean;
+ name: string | null;
+ }
+ /** Queries the file system for information on the path provided. If the given
+ * path is a symlink information about the symlink will be returned.
+ *
+ * const fileInfo = await Deno.lstat("hello.txt");
+ * assert(fileInfo.isFile());
+ */
+ export function lstat(filename: string): Promise<FileInfo>;
+ /** Queries the file system for information on the path provided synchronously.
+ * If the given path is a symlink information about the symlink will be
+ * returned.
+ *
+ * const fileInfo = Deno.lstatSync("hello.txt");
+ * assert(fileInfo.isFile());
+ */
+ export function lstatSync(filename: string): FileInfo;
+ /** Queries the file system for information on the path provided. `stat` Will
+ * always follow symlinks.
+ *
+ * const fileInfo = await Deno.stat("hello.txt");
+ * assert(fileInfo.isFile());
+ */
+ export function stat(filename: string): Promise<FileInfo>;
+ /** Queries the file system for information on the path provided synchronously.
+ * `statSync` Will always follow symlinks.
+ *
+ * const fileInfo = Deno.statSync("hello.txt");
+ * assert(fileInfo.isFile());
+ */
+ export function statSync(filename: string): FileInfo;
+
+ // @url js/link.d.ts
+
+ /** Synchronously creates `newname` as a hard link to `oldname`.
+ *
+ * Deno.linkSync("old/name", "new/name");
+ */
+ export function linkSync(oldname: string, newname: string): void;
+ /** Creates `newname` as a hard link to `oldname`.
+ *
+ * await Deno.link("old/name", "new/name");
+ */
+ export function link(oldname: string, newname: string): Promise<void>;
+
+ // @url js/symlink.d.ts
+
+ /** Synchronously creates `newname` as a symbolic link to `oldname`. The type
+ * argument can be set to `dir` or `file` and is only available on Windows
+ * (ignored on other platforms).
+ *
+ * Deno.symlinkSync("old/name", "new/name");
+ */
+ export function symlinkSync(
+ oldname: string,
+ newname: string,
+ type?: string
+ ): void;
+ /** Creates `newname` as a symbolic link to `oldname`. The type argument can be
+ * set to `dir` or `file` and is only available on Windows (ignored on other
+ * platforms).
+ *
+ * await Deno.symlink("old/name", "new/name");
+ */
+ export function symlink(
+ oldname: string,
+ newname: string,
+ type?: string
+ ): Promise<void>;
+
+ // @url js/write_file.d.ts
+
+ /** Options for writing to a file.
+ * `perm` would change the file's permission if set.
+ * `create` decides if the file should be created if not exists (default: true)
+ * `append` decides if the file should be appended (default: false)
+ */
+ export interface WriteFileOptions {
+ perm?: number;
+ create?: boolean;
+ append?: boolean;
+ }
+ /** Write a new file, with given filename and data synchronously.
+ *
+ * const encoder = new TextEncoder();
+ * const data = encoder.encode("Hello world\n");
+ * Deno.writeFileSync("hello.txt", data);
+ */
+ export function writeFileSync(
+ filename: string,
+ data: Uint8Array,
+ options?: WriteFileOptions
+ ): void;
+ /** Write a new file, with given filename and data.
+ *
+ * const encoder = new TextEncoder();
+ * const data = encoder.encode("Hello world\n");
+ * await Deno.writeFile("hello.txt", data);
+ */
+ export function writeFile(
+ filename: string,
+ data: Uint8Array,
+ options?: WriteFileOptions
+ ): Promise<void>;
+
+ // @url js/error_stack.d.ts
+
+ interface Location {
+ /** The full url for the module, e.g. `file://some/file.ts` or
+ * `https://some/file.ts`. */
+ filename: string;
+ /** The line number in the file. It is assumed to be 1-indexed. */
+ line: number;
+ /** The column number in the file. It is assumed to be 1-indexed. */
+ column: number;
+ }
+ /** Given a current location in a module, lookup the source location and
+ * return it.
+ *
+ * When Deno transpiles code, it keep source maps of the transpiled code. This
+ * function can be used to lookup the original location. This is automatically
+ * done when accessing the `.stack` of an error, or when an uncaught error is
+ * logged. This function can be used to perform the lookup for creating better
+ * error handling.
+ *
+ * **Note:** `line` and `column` are 1 indexed, which matches display
+ * expectations, but is not typical of most index numbers in Deno.
+ *
+ * An example:
+ *
+ * const orig = Deno.applySourceMap({
+ * location: "file://my/module.ts",
+ * line: 5,
+ * column: 15
+ * });
+ * console.log(`${orig.filename}:${orig.line}:${orig.column}`);
+ *
+ */
+ export function applySourceMap(location: Location): Location;
+
+ // @url js/errors.d.ts
+
+ /** A Deno specific error. The `kind` property is set to a specific error code
+ * which can be used to in application logic.
+ *
+ * try {
+ * somethingThatMightThrow();
+ * } catch (e) {
+ * if (
+ * e instanceof Deno.DenoError &&
+ * e.kind === Deno.ErrorKind.Overflow
+ * ) {
+ * console.error("Overflow error!");
+ * }
+ * }
+ *
+ */
+ export class DenoError<T extends ErrorKind> extends Error {
+ readonly kind: T;
+ constructor(kind: T, msg: string);
+ }
+ export enum ErrorKind {
+ NoError = 0,
+ NotFound = 1,
+ PermissionDenied = 2,
+ ConnectionRefused = 3,
+ ConnectionReset = 4,
+ ConnectionAborted = 5,
+ NotConnected = 6,
+ AddrInUse = 7,
+ AddrNotAvailable = 8,
+ BrokenPipe = 9,
+ AlreadyExists = 10,
+ WouldBlock = 11,
+ InvalidInput = 12,
+ InvalidData = 13,
+ TimedOut = 14,
+ Interrupted = 15,
+ WriteZero = 16,
+ Other = 17,
+ UnexpectedEof = 18,
+ BadResource = 19,
+ CommandFailed = 20,
+ EmptyHost = 21,
+ IdnaError = 22,
+ InvalidPort = 23,
+ InvalidIpv4Address = 24,
+ InvalidIpv6Address = 25,
+ InvalidDomainCharacter = 26,
+ RelativeUrlWithoutBase = 27,
+ RelativeUrlWithCannotBeABaseBase = 28,
+ SetHostOnCannotBeABaseUrl = 29,
+ Overflow = 30,
+ HttpUser = 31,
+ HttpClosed = 32,
+ HttpCanceled = 33,
+ HttpParse = 34,
+ HttpOther = 35,
+ TooLarge = 36,
+ InvalidUri = 37,
+ InvalidSeekMode = 38,
+ OpNotAvailable = 39,
+ WorkerInitFailed = 40,
+ UnixError = 41,
+ NoAsyncSupport = 42,
+ NoSyncSupport = 43,
+ ImportMapError = 44,
+ InvalidPath = 45,
+ ImportPrefixMissing = 46,
+ UnsupportedFetchScheme = 47,
+ TooManyRedirects = 48,
+ Diagnostic = 49,
+ JSError = 50
+ }
+
+ // @url js/permissions.d.ts
+
+ /** Permissions as granted by the caller */
+ export interface Permissions {
+ read: boolean;
+ write: boolean;
+ net: boolean;
+ env: boolean;
+ run: boolean;
+ hrtime: boolean;
+ }
+ export type Permission = keyof Permissions;
+ /** Inspect granted permissions for the current program.
+ *
+ * if (Deno.permissions().read) {
+ * const file = await Deno.readFile("example.test");
+ * // ...
+ * }
+ */
+ export function permissions(): Permissions;
+ /** Revoke a permission. When the permission was already revoked nothing changes
+ *
+ * if (Deno.permissions().read) {
+ * const file = await Deno.readFile("example.test");
+ * Deno.revokePermission('read');
+ * }
+ * Deno.readFile("example.test"); // -> error or permission prompt
+ */
+ export function revokePermission(permission: Permission): void;
+
+ // @url js/truncate.d.ts
+
+ /** Truncates or extends the specified file synchronously, updating the size of
+ * this file to become size.
+ *
+ * Deno.truncateSync("hello.txt", 10);
+ */
+ export function truncateSync(name: string, len?: number): void;
+ /**
+ * Truncates or extends the specified file, updating the size of this file to
+ * become size.
+ *
+ * await Deno.truncate("hello.txt", 10);
+ */
+ export function truncate(name: string, len?: number): Promise<void>;
+
+ // @url js/net.d.ts
+
+ type Network = "tcp";
+ interface Addr {
+ network: Network;
+ address: string;
+ }
+ /** A Listener is a generic network listener for stream-oriented protocols. */
+ export interface Listener extends AsyncIterator<Conn> {
+ /** Waits for and resolves to the next connection to the `Listener`. */
+ accept(): Promise<Conn>;
+ /** Close closes the listener. Any pending accept promises will be rejected
+ * with errors.
+ */
+ close(): void;
+ /** Return the address of the `Listener`. */
+ addr(): Addr;
+ [Symbol.asyncIterator](): AsyncIterator<Conn>;
+ }
+ export interface Conn extends Reader, Writer, Closer {
+ /** The local address of the connection. */
+ localAddr: string;
+ /** The remote address of the connection. */
+ remoteAddr: string;
+ /** The resource ID of the connection. */
+ rid: number;
+ /** Shuts down (`shutdown(2)`) the reading side of the TCP connection. Most
+ * callers should just use `close()`.
+ */
+ closeRead(): void;
+ /** Shuts down (`shutdown(2)`) the writing side of the TCP connection. Most
+ * callers should just use `close()`.
+ */
+ closeWrite(): void;
+ }
+ /** Listen announces on the local network address.
+ *
+ * The network must be `tcp`, `tcp4`, `tcp6`, `unix` or `unixpacket`.
+ *
+ * For TCP networks, if the host in the address parameter is empty or a literal
+ * unspecified IP address, `listen()` listens on all available unicast and
+ * anycast IP addresses of the local system. To only use IPv4, use network
+ * `tcp4`. The address can use a host name, but this is not recommended,
+ * because it will create a listener for at most one of the host's IP
+ * addresses. If the port in the address parameter is empty or `0`, as in
+ * `127.0.0.1:` or `[::1]:0`, a port number is automatically chosen. The
+ * `addr()` method of `Listener` can be used to discover the chosen port.
+ *
+ * See `dial()` for a description of the network and address parameters.
+ */
+ export function listen(network: Network, address: string): Listener;
+ /** Dial connects to the address on the named network.
+ *
+ * Supported networks are only `tcp` currently.
+ *
+ * TODO: `tcp4` (IPv4-only), `tcp6` (IPv6-only), `udp`, `udp4` (IPv4-only),
+ * `udp6` (IPv6-only), `ip`, `ip4` (IPv4-only), `ip6` (IPv6-only), `unix`,
+ * `unixgram` and `unixpacket`.
+ *
+ * For TCP and UDP networks, the address has the form `host:port`. The host must
+ * be a literal IP address, or a host name that can be resolved to IP addresses.
+ * The port must be a literal port number or a service name. If the host is a
+ * literal IPv6 address it must be enclosed in square brackets, as in
+ * `[2001:db8::1]:80` or `[fe80::1%zone]:80`. The zone specifies the scope of
+ * the literal IPv6 address as defined in RFC 4007. The functions JoinHostPort
+ * and SplitHostPort manipulate a pair of host and port in this form. When using
+ * TCP, and the host resolves to multiple IP addresses, Dial will try each IP
+ * address in order until one succeeds.
+ *
+ * Examples:
+ *
+ * dial("tcp", "golang.org:http")
+ * dial("tcp", "192.0.2.1:http")
+ * dial("tcp", "198.51.100.1:80")
+ * dial("udp", "[2001:db8::1]:domain")
+ * dial("udp", "[fe80::1%lo0]:53")
+ * dial("tcp", ":80")
+ */
+ export function dial(network: Network, address: string): Promise<Conn>;
+ /** **RESERVED** */
+ export function connect(_network: Network, _address: string): Promise<Conn>;
+
+ // @url js/metrics.d.ts
+
+ export interface Metrics {
+ opsDispatched: number;
+ opsCompleted: number;
+ bytesSentControl: number;
+ bytesSentData: number;
+ bytesReceived: number;
+ }
+ /** Receive metrics from the privileged side of Deno.
+ *
+ * > console.table(Deno.metrics())
+ * ┌──────────────────┬────────┐
+ * │ (index) │ Values │
+ * ├──────────────────┼────────┤
+ * │ opsDispatched │ 9 │
+ * │ opsCompleted │ 9 │
+ * │ bytesSentControl │ 504 │
+ * │ bytesSentData │ 0 │
+ * │ bytesReceived │ 856 │
+ * └──────────────────┴────────┘
+ */
+ export function metrics(): Metrics;
+
+ // @url js/resources.d.ts
+
+ interface ResourceMap {
+ [rid: number]: string;
+ }
+ /** Returns a map of open _file like_ resource ids along with their string
+ * representation.
+ */
+ export function resources(): ResourceMap;
+
+ // @url js/process.d.ts
+
+ /** How to handle subprocess stdio.
+ *
+ * "inherit" The default if unspecified. The child inherits from the
+ * corresponding parent descriptor.
+ *
+ * "piped" A new pipe should be arranged to connect the parent and child
+ * subprocesses.
+ *
+ * "null" This stream will be ignored. This is the equivalent of attaching the
+ * stream to /dev/null.
+ */
+ type ProcessStdio = "inherit" | "piped" | "null";
+ export interface RunOptions {
+ args: string[];
+ cwd?: string;
+ env?: {
+ [key: string]: string;
+ };
+ stdout?: ProcessStdio | number;
+ stderr?: ProcessStdio | number;
+ stdin?: ProcessStdio | number;
+ }
+ /** Send a signal to process under given PID. Unix only at this moment.
+ * If pid is negative, the signal will be sent to the process group identified
+ * by -pid.
+ * Requires the `--allow-run` flag.
+ */
+ export function kill(pid: number, signo: number): void;
+ export class Process {
+ readonly rid: number;
+ readonly pid: number;
+ readonly stdin?: WriteCloser;
+ readonly stdout?: ReadCloser;
+ readonly stderr?: ReadCloser;
+ status(): Promise<ProcessStatus>;
+ /** Buffer the stdout and return it as Uint8Array after EOF.
+ * You must set stdout to "piped" when creating the process.
+ * This calls close() on stdout after its done.
+ */
+ output(): Promise<Uint8Array>;
+ /** Buffer the stderr and return it as Uint8Array after EOF.
+ * You must set stderr to "piped" when creating the process.
+ * This calls close() on stderr after its done.
+ */
+ stderrOutput(): Promise<Uint8Array>;
+ close(): void;
+ kill(signo: number): void;
+ }
+ export interface ProcessStatus {
+ success: boolean;
+ code?: number;
+ signal?: number;
+ }
+ /**
+ * Spawns new subprocess.
+ *
+ * Subprocess uses same working directory as parent process unless `opt.cwd`
+ * is specified.
+ *
+ * Environmental variables for subprocess can be specified using `opt.env`
+ * mapping.
+ *
+ * By default subprocess inherits stdio of parent process. To change that
+ * `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;
+ enum LinuxSignal {
+ SIGHUP = 1,
+ SIGINT = 2,
+ SIGQUIT = 3,
+ SIGILL = 4,
+ SIGTRAP = 5,
+ SIGABRT = 6,
+ SIGBUS = 7,
+ SIGFPE = 8,
+ SIGKILL = 9,
+ SIGUSR1 = 10,
+ SIGSEGV = 11,
+ SIGUSR2 = 12,
+ SIGPIPE = 13,
+ SIGALRM = 14,
+ SIGTERM = 15,
+ SIGSTKFLT = 16,
+ SIGCHLD = 17,
+ SIGCONT = 18,
+ SIGSTOP = 19,
+ SIGTSTP = 20,
+ SIGTTIN = 21,
+ SIGTTOU = 22,
+ SIGURG = 23,
+ SIGXCPU = 24,
+ SIGXFSZ = 25,
+ SIGVTALRM = 26,
+ SIGPROF = 27,
+ SIGWINCH = 28,
+ SIGIO = 29,
+ SIGPWR = 30,
+ SIGSYS = 31
+ }
+ enum MacOSSignal {
+ SIGHUP = 1,
+ SIGINT = 2,
+ SIGQUIT = 3,
+ SIGILL = 4,
+ SIGTRAP = 5,
+ SIGABRT = 6,
+ SIGEMT = 7,
+ SIGFPE = 8,
+ SIGKILL = 9,
+ SIGBUS = 10,
+ SIGSEGV = 11,
+ SIGSYS = 12,
+ SIGPIPE = 13,
+ SIGALRM = 14,
+ SIGTERM = 15,
+ SIGURG = 16,
+ SIGSTOP = 17,
+ SIGTSTP = 18,
+ SIGCONT = 19,
+ SIGCHLD = 20,
+ SIGTTIN = 21,
+ SIGTTOU = 22,
+ SIGIO = 23,
+ SIGXCPU = 24,
+ SIGXFSZ = 25,
+ SIGVTALRM = 26,
+ SIGPROF = 27,
+ SIGWINCH = 28,
+ SIGINFO = 29,
+ SIGUSR1 = 30,
+ SIGUSR2 = 31
+ }
+ /** Signals numbers. This is platform dependent.
+ */
+ export const Signal: typeof MacOSSignal | typeof LinuxSignal;
+ export {};
+
+ // @url js/console.d.ts
+
+ type ConsoleOptions = Partial<{
+ showHidden: boolean;
+ depth: number;
+ colors: boolean;
+ indentLevel: number;
+ }>;
+ export const isConsoleInstance: unique symbol;
+ /** A symbol which can be used as a key for a custom method which will be called
+ * when `Deno.inspect()` is called, or when the object is logged to the console.
+ */
+ export const customInspect: unique symbol;
+ /**
+ * `inspect()` converts input into string that has the same format
+ * as printed by `console.log(...)`;
+ */
+ export function inspect(value: unknown, options?: ConsoleOptions): string;
+
+ // @url js/build.d.ts
+
+ export type OperatingSystem = "mac" | "win" | "linux";
+ export type Arch = "x64" | "arm64";
+ /** Build related information */
+ interface BuildInfo {
+ /** The CPU architecture. */
+ arch: Arch;
+ /** The operating system. */
+ os: OperatingSystem;
+ }
+ export const build: BuildInfo;
+ export const platform: BuildInfo;
+
+ // @url js/version.d.ts
+
+ interface Version {
+ deno: string;
+ v8: string;
+ typescript: string;
+ }
+ export const version: Version;
+ export {};
+
+ // @url js/deno.d.ts
+
+ export const args: string[];
+}
+
+// @url js/globals.ts
+
+declare interface Window {
+ window: Window;
+ atob: typeof textEncoding.atob;
+ btoa: typeof textEncoding.btoa;
+ fetch: typeof fetchTypes.fetch;
+ clearTimeout: typeof timers.clearTimeout;
+ clearInterval: typeof timers.clearInterval;
+ console: consoleTypes.Console;
+ setTimeout: typeof timers.setTimeout;
+ setInterval: typeof timers.setInterval;
+ location: domTypes.Location;
+ onload: Function | undefined;
+ crypto: Crypto;
+ Blob: typeof blob.DenoBlob;
+ File: domTypes.DomFileConstructor;
+ CustomEventInit: typeof customEvent.CustomEventInit;
+ CustomEvent: typeof customEvent.CustomEvent;
+ EventInit: typeof event.EventInit;
+ Event: typeof event.Event;
+ EventListener: typeof eventTarget.EventListener;
+ EventTarget: typeof eventTarget.EventTarget;
+ URL: typeof url.URL;
+ URLSearchParams: typeof urlSearchParams.URLSearchParams;
+ Headers: domTypes.HeadersConstructor;
+ FormData: domTypes.FormDataConstructor;
+ TextEncoder: typeof textEncoding.TextEncoder;
+ TextDecoder: typeof textEncoding.TextDecoder;
+ Request: domTypes.RequestConstructor;
+ Response: typeof fetchTypes.Response;
+ performance: performanceUtil.Performance;
+ onmessage: (e: { data: any }) => void;
+ workerMain: typeof workers.workerMain;
+ workerClose: typeof workers.workerClose;
+ postMessage: typeof workers.postMessage;
+ Worker: typeof workers.WorkerImpl;
+ addEventListener: (
+ type: string,
+ callback: (event: domTypes.Event) => void | null,
+ options?: boolean | domTypes.AddEventListenerOptions | undefined
+ ) => void;
+ dispatchEvent: (event: domTypes.Event) => boolean;
+ removeEventListener: (
+ type: string,
+ callback: (event: domTypes.Event) => void | null,
+ options?: boolean | domTypes.EventListenerOptions | undefined
+ ) => void;
+ Deno: typeof Deno;
+}
+
+declare const window: Window;
+declare const atob: typeof textEncoding.atob;
+declare const btoa: typeof textEncoding.btoa;
+declare const fetch: typeof fetchTypes.fetch;
+declare const clearTimeout: typeof timers.clearTimeout;
+declare const clearInterval: typeof timers.clearInterval;
+declare const console: consoleTypes.Console;
+declare const setTimeout: typeof timers.setTimeout;
+declare const setInterval: typeof timers.setInterval;
+declare const location: domTypes.Location;
+declare const onload: Function | undefined;
+declare const crypto: Crypto;
+declare const Blob: typeof blob.DenoBlob;
+declare const File: domTypes.DomFileConstructor;
+declare const CustomEventInit: typeof customEvent.CustomEventInit;
+declare const CustomEvent: typeof customEvent.CustomEvent;
+declare const EventInit: typeof event.EventInit;
+declare const Event: typeof event.Event;
+declare const EventListener: typeof eventTarget.EventListener;
+declare const EventTarget: typeof eventTarget.EventTarget;
+declare const URL: typeof url.URL;
+declare const URLSearchParams: typeof urlSearchParams.URLSearchParams;
+declare const Headers: domTypes.HeadersConstructor;
+declare const FormData: domTypes.FormDataConstructor;
+declare const TextEncoder: typeof textEncoding.TextEncoder;
+declare const TextDecoder: typeof textEncoding.TextDecoder;
+declare const Request: domTypes.RequestConstructor;
+declare const Response: typeof fetchTypes.Response;
+declare const performance: performanceUtil.Performance;
+declare let onmessage: (e: { data: any }) => void;
+declare const workerMain: typeof workers.workerMain;
+declare const workerClose: typeof workers.workerClose;
+declare const postMessage: typeof workers.postMessage;
+declare const Worker: typeof workers.WorkerImpl;
+declare const addEventListener: (
+ type: string,
+ callback: (event: domTypes.Event) => void | null,
+ options?: boolean | domTypes.AddEventListenerOptions | undefined
+) => void;
+declare const dispatchEvent: (event: domTypes.Event) => boolean;
+declare const removeEventListener: (
+ type: string,
+ callback: (event: domTypes.Event) => void | null,
+ options?: boolean | domTypes.EventListenerOptions | undefined
+) => void;
+
+declare type Blob = blob.DenoBlob;
+declare type File = domTypes.DomFile;
+declare type CustomEventInit = customEvent.CustomEventInit;
+declare type CustomEvent = customEvent.CustomEvent;
+declare type EventInit = event.EventInit;
+declare type Event = event.Event;
+declare type EventListener = eventTarget.EventListener;
+declare type EventTarget = eventTarget.EventTarget;
+declare type URL = url.URL;
+declare type URLSearchParams = urlSearchParams.URLSearchParams;
+declare type Headers = domTypes.Headers;
+declare type FormData = domTypes.FormData;
+declare type TextEncoder = textEncoding.TextEncoder;
+declare type TextDecoder = textEncoding.TextDecoder;
+declare type Request = domTypes.Request;
+declare type Response = domTypes.Response;
+declare type Worker = workers.Worker;
+
+declare interface ImportMeta {
+ url: string;
+ main: boolean;
+}
+
+declare interface Crypto {
+ readonly subtle: null;
+ getRandomValues: <
+ T extends
+ | Int8Array
+ | Uint8Array
+ | Uint8ClampedArray
+ | Int16Array
+ | Uint16Array
+ | Int32Array
+ | Uint32Array
+ >(
+ typedArray: T
+ ) => T;
+}
+
+declare namespace domTypes {
+ // @url js/dom_types.d.ts
+
+ export type BufferSource = ArrayBufferView | ArrayBuffer;
+ export type HeadersInit =
+ | Headers
+ | Array<[string, string]>
+ | Record<string, string>;
+ export type URLSearchParamsInit =
+ | string
+ | string[][]
+ | Record<string, string>;
+ type BodyInit =
+ | Blob
+ | BufferSource
+ | FormData
+ | URLSearchParams
+ | ReadableStream
+ | string;
+ export type RequestInfo = Request | string;
+ type ReferrerPolicy =
+ | ""
+ | "no-referrer"
+ | "no-referrer-when-downgrade"
+ | "origin-only"
+ | "origin-when-cross-origin"
+ | "unsafe-url";
+ export type BlobPart = BufferSource | Blob | string;
+ export type FormDataEntryValue = DomFile | string;
+ export interface DomIterable<K, V> {
+ keys(): IterableIterator<K>;
+ values(): IterableIterator<V>;
+ entries(): IterableIterator<[K, V]>;
+ [Symbol.iterator](): IterableIterator<[K, V]>;
+ forEach(
+ callback: (value: V, key: K, parent: this) => void,
+ thisArg?: any
+ ): void;
+ }
+ type EndingType = "transparent" | "native";
+ export interface BlobPropertyBag {
+ type?: string;
+ ending?: EndingType;
+ }
+ interface AbortSignalEventMap {
+ abort: ProgressEvent;
+ }
+ export enum NodeType {
+ ELEMENT_NODE = 1,
+ TEXT_NODE = 3,
+ 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 EventTarget {
+ [eventTargetHost]: EventTarget | null;
+ [eventTargetListeners]: { [type in string]: EventListener[] };
+ [eventTargetMode]: string;
+ [eventTargetNodeType]: NodeType;
+ addEventListener(
+ type: string,
+ callback: (event: Event) => void | null,
+ options?: boolean | AddEventListenerOptions
+ ): void;
+ dispatchEvent(event: Event): boolean;
+ removeEventListener(
+ type: string,
+ callback?: (event: Event) => void | null,
+ options?: EventListenerOptions | boolean
+ ): void;
+ }
+ export interface ProgressEventInit extends EventInit {
+ lengthComputable?: boolean;
+ loaded?: number;
+ total?: number;
+ }
+ 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 all key/value pairs contained in this object in place
+ * and return undefined. The sort order is according to Unicode
+ * code points of the keys.
+ */
+ sort(): void;
+ /**
+ * Returns a query string suitable for use in a URL.
+ */
+ toString(): string;
+ /**
+ * Iterates over each name-value pair in the query
+ * and invokes the given function.
+ */
+ forEach(
+ callbackfn: (value: string, key: string, parent: URLSearchParams) => void,
+ thisArg?: any
+ ): void;
+ }
+ export interface EventListener {
+ handleEvent(event: Event): void;
+ readonly callback: (event: Event) => void | null;
+ readonly options: boolean | AddEventListenerOptions;
+ }
+ export interface EventInit {
+ bubbles?: boolean;
+ cancelable?: boolean;
+ composed?: boolean;
+ }
+ export interface CustomEventInit extends EventInit {
+ detail?: any;
+ }
+ export enum EventPhase {
+ NONE = 0,
+ CAPTURING_PHASE = 1,
+ AT_TARGET = 2,
+ BUBBLING_PHASE = 3
+ }
+ export interface EventPath {
+ item: EventTarget;
+ itemInShadowTree: boolean;
+ relatedTarget: EventTarget | null;
+ rootOfClosedTree: boolean;
+ slotInClosedTree: boolean;
+ target: EventTarget | null;
+ touchTargetList: EventTarget[];
+ }
+ export interface Event {
+ readonly type: string;
+ target: EventTarget | null;
+ currentTarget: EventTarget | null;
+ composedPath(): EventPath[];
+ eventPhase: number;
+ stopPropagation(): void;
+ stopImmediatePropagation(): void;
+ readonly bubbles: boolean;
+ readonly cancelable: boolean;
+ preventDefault(): void;
+ readonly defaultPrevented: boolean;
+ readonly composed: boolean;
+ isTrusted: boolean;
+ readonly timeStamp: Date;
+ dispatched: boolean;
+ readonly initialized: boolean;
+ inPassiveListener: boolean;
+ cancelBubble: boolean;
+ cancelBubbleImmediately: boolean;
+ path: EventPath[];
+ relatedTarget: EventTarget | null;
+ }
+ export interface CustomEvent extends Event {
+ readonly detail: any;
+ initCustomEvent(
+ type: string,
+ bubbles?: boolean,
+ cancelable?: boolean,
+ detail?: any | null
+ ): void;
+ }
+ export interface DomFile extends Blob {
+ readonly lastModified: number;
+ readonly name: string;
+ }
+ export interface DomFileConstructor {
+ new (
+ bits: BlobPart[],
+ filename: string,
+ options?: FilePropertyBag
+ ): DomFile;
+ prototype: DomFile;
+ }
+ export interface FilePropertyBag extends BlobPropertyBag {
+ lastModified?: number;
+ }
+ interface ProgressEvent extends Event {
+ readonly lengthComputable: boolean;
+ readonly loaded: number;
+ readonly total: number;
+ }
+ export interface EventListenerOptions {
+ capture: boolean;
+ }
+ export interface AddEventListenerOptions extends EventListenerOptions {
+ once: boolean;
+ passive: boolean;
+ }
+ interface AbortSignal extends EventTarget {
+ readonly aborted: boolean;
+ onabort: ((this: AbortSignal, ev: ProgressEvent) => any) | null;
+ addEventListener<K extends keyof AbortSignalEventMap>(
+ type: K,
+ listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any,
+ options?: boolean | AddEventListenerOptions
+ ): void;
+ addEventListener(
+ type: string,
+ listener: EventListener,
+ options?: boolean | AddEventListenerOptions
+ ): void;
+ removeEventListener<K extends keyof AbortSignalEventMap>(
+ type: K,
+ listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any,
+ options?: boolean | EventListenerOptions
+ ): void;
+ removeEventListener(
+ type: string,
+ listener: EventListener,
+ options?: boolean | EventListenerOptions
+ ): void;
+ }
+ export interface ReadableStream {
+ readonly locked: boolean;
+ cancel(): Promise<void>;
+ getReader(): ReadableStreamReader;
+ tee(): [ReadableStream, ReadableStream];
+ }
+ export interface ReadableStreamReader {
+ cancel(): Promise<void>;
+ read(): Promise<any>;
+ releaseLock(): void;
+ }
+ export interface FormData extends DomIterable<string, FormDataEntryValue> {
+ append(name: string, value: string | Blob, fileName?: string): void;
+ delete(name: string): void;
+ get(name: string): FormDataEntryValue | null;
+ getAll(name: string): FormDataEntryValue[];
+ has(name: string): boolean;
+ set(name: string, value: string | Blob, fileName?: string): void;
+ }
+ export interface FormDataConstructor {
+ new (): FormData;
+ prototype: FormData;
+ }
+ /** A blob object represents a file-like object of immutable, raw data. */
+ export interface Blob {
+ /** The size, in bytes, of the data contained in the `Blob` object. */
+ readonly size: number;
+ /** A string indicating the media type of the data contained in the `Blob`.
+ * If the type is unknown, this string is empty.
+ */
+ readonly type: string;
+ /** Returns a new `Blob` object containing the data in the specified range of
+ * bytes of the source `Blob`.
+ */
+ slice(start?: number, end?: number, contentType?: string): Blob;
+ }
+ export interface Body {
+ /** A simple getter used to expose a `ReadableStream` of the body contents. */
+ readonly body: ReadableStream | null;
+ /** Stores a `Boolean` that declares whether the body has been used in a
+ * response yet.
+ */
+ readonly bodyUsed: boolean;
+ /** Takes a `Response` stream and reads it to completion. It returns a promise
+ * that resolves with an `ArrayBuffer`.
+ */
+ arrayBuffer(): Promise<ArrayBuffer>;
+ /** Takes a `Response` stream and reads it to completion. It returns a promise
+ * that resolves with a `Blob`.
+ */
+ blob(): Promise<Blob>;
+ /** Takes a `Response` stream and reads it to completion. It returns a promise
+ * that resolves with a `FormData` object.
+ */
+ formData(): Promise<FormData>;
+ /** Takes a `Response` stream and reads it to completion. It returns a promise
+ * that resolves with the result of parsing the body text as JSON.
+ */
+ json(): Promise<any>;
+ /** Takes a `Response` stream and reads it to completion. It returns a promise
+ * that resolves with a `USVString` (text).
+ */
+ text(): Promise<string>;
+ }
+ export interface Headers extends DomIterable<string, string> {
+ /** Appends a new value onto an existing header inside a `Headers` object, or
+ * adds the header if it does not already exist.
+ */
+ append(name: string, value: string): void;
+ /** Deletes a header from a `Headers` object. */
+ delete(name: string): void;
+ /** Returns an iterator allowing to go through all key/value pairs
+ * contained in this Headers object. The both the key and value of each pairs
+ * are ByteString objects.
+ */
+ entries(): IterableIterator<[string, string]>;
+ /** Returns a `ByteString` sequence of all the values of a header within a
+ * `Headers` object with a given name.
+ */
+ get(name: string): string | null;
+ /** Returns a boolean stating whether a `Headers` object contains a certain
+ * header.
+ */
+ has(name: string): boolean;
+ /** Returns an iterator allowing to go through all keys contained in
+ * this Headers object. The keys are ByteString objects.
+ */
+ keys(): IterableIterator<string>;
+ /** Sets a new value for an existing header inside a Headers object, or adds
+ * the header if it does not already exist.
+ */
+ set(name: string, value: string): void;
+ /** Returns an iterator allowing to go through all values contained in
+ * this Headers object. The values are ByteString objects.
+ */
+ values(): IterableIterator<string>;
+ forEach(
+ callbackfn: (value: string, key: string, parent: this) => void,
+ thisArg?: any
+ ): void;
+ /** The Symbol.iterator well-known symbol specifies the default
+ * iterator for this Headers object
+ */
+ [Symbol.iterator](): IterableIterator<[string, string]>;
+ }
+ export interface HeadersConstructor {
+ new (init?: HeadersInit): Headers;
+ prototype: Headers;
+ }
+ type RequestCache =
+ | "default"
+ | "no-store"
+ | "reload"
+ | "no-cache"
+ | "force-cache"
+ | "only-if-cached";
+ type RequestCredentials = "omit" | "same-origin" | "include";
+ type RequestDestination =
+ | ""
+ | "audio"
+ | "audioworklet"
+ | "document"
+ | "embed"
+ | "font"
+ | "image"
+ | "manifest"
+ | "object"
+ | "paintworklet"
+ | "report"
+ | "script"
+ | "sharedworker"
+ | "style"
+ | "track"
+ | "video"
+ | "worker"
+ | "xslt";
+ type RequestMode = "navigate" | "same-origin" | "no-cors" | "cors";
+ type RequestRedirect = "follow" | "error" | "manual";
+ type ResponseType =
+ | "basic"
+ | "cors"
+ | "default"
+ | "error"
+ | "opaque"
+ | "opaqueredirect";
+ export interface RequestInit {
+ body?: BodyInit | null;
+ cache?: RequestCache;
+ credentials?: RequestCredentials;
+ headers?: HeadersInit;
+ integrity?: string;
+ keepalive?: boolean;
+ method?: string;
+ mode?: RequestMode;
+ redirect?: RequestRedirect;
+ referrer?: string;
+ referrerPolicy?: ReferrerPolicy;
+ signal?: AbortSignal | null;
+ window?: any;
+ }
+ export interface ResponseInit {
+ headers?: HeadersInit;
+ status?: number;
+ statusText?: string;
+ }
+ export interface RequestConstructor {
+ new (input: RequestInfo, init?: RequestInit): Request;
+ prototype: Request;
+ }
+ export interface Request extends Body {
+ /** Returns the cache mode associated with request, which is a string
+ * indicating how the the request will interact with the browser's cache when
+ * fetching.
+ */
+ readonly cache?: RequestCache;
+ /** Returns the credentials mode associated with request, which is a string
+ * indicating whether credentials will be sent with the request always, never,
+ * or only when sent to a same-origin URL.
+ */
+ readonly credentials?: RequestCredentials;
+ /** Returns the kind of resource requested by request, (e.g., `document` or
+ * `script`).
+ */
+ readonly destination?: RequestDestination;
+ /** Returns a Headers object consisting of the headers associated with
+ * request.
+ *
+ * Note that headers added in the network layer by the user agent
+ * will not be accounted for in this object, (e.g., the `Host` header).
+ */
+ readonly headers: Headers;
+ /** Returns request's subresource integrity metadata, which is a cryptographic
+ * hash of the resource being fetched. Its value consists of multiple hashes
+ * separated by whitespace. [SRI]
+ */
+ readonly integrity?: string;
+ /** Returns a boolean indicating whether or not request is for a history
+ * navigation (a.k.a. back-forward navigation).
+ */
+ readonly isHistoryNavigation?: boolean;
+ /** Returns a boolean indicating whether or not request is for a reload
+ * navigation.
+ */
+ readonly isReloadNavigation?: boolean;
+ /** Returns a boolean indicating whether or not request can outlive the global
+ * in which it was created.
+ */
+ readonly keepalive?: boolean;
+ /** Returns request's HTTP method, which is `GET` by default. */
+ readonly method: string;
+ /** Returns the mode associated with request, which is a string indicating
+ * whether the request will use CORS, or will be restricted to same-origin
+ * URLs.
+ */
+ readonly mode?: RequestMode;
+ /** Returns the redirect mode associated with request, which is a string
+ * indicating how redirects for the request will be handled during fetching.
+ *
+ * A request will follow redirects by default.
+ */
+ readonly redirect?: RequestRedirect;
+ /** Returns the referrer of request. Its value can be a same-origin URL if
+ * explicitly set in init, the empty string to indicate no referrer, and
+ * `about:client` when defaulting to the global's default.
+ *
+ * This is used during fetching to determine the value of the `Referer`
+ * header of the request being made.
+ */
+ readonly referrer?: string;
+ /** Returns the referrer policy associated with request. This is used during
+ * fetching to compute the value of the request's referrer.
+ */
+ readonly referrerPolicy?: ReferrerPolicy;
+ /** Returns the signal associated with request, which is an AbortSignal object
+ * indicating whether or not request has been aborted, and its abort event
+ * handler.
+ */
+ readonly signal?: AbortSignal;
+ /** Returns the URL of request as a string. */
+ readonly url: string;
+ clone(): Request;
+ }
+ export interface Response extends Body {
+ /** Contains the `Headers` object associated with the response. */
+ readonly headers: Headers;
+ /** Contains a boolean stating whether the response was successful (status in
+ * the range 200-299) or not.
+ */
+ readonly ok: boolean;
+ /** Indicates whether or not the response is the result of a redirect; that
+ * is, its URL list has more than one entry.
+ */
+ readonly redirected: boolean;
+ /** Contains the status code of the response (e.g., `200` for a success). */
+ readonly status: number;
+ /** Contains the status message corresponding to the status code (e.g., `OK`
+ * for `200`).
+ */
+ readonly statusText: string;
+ readonly trailer: Promise<Headers>;
+ /** Contains the type of the response (e.g., `basic`, `cors`). */
+ readonly type: ResponseType;
+ /** Contains the URL of the response. */
+ readonly url: string;
+ /** Creates a clone of a `Response` object. */
+ clone(): Response;
+ }
+ export interface Location {
+ /**
+ * Returns a DOMStringList object listing the origins of the ancestor browsing
+ * contexts, from the parent browsing context to the top-level browsing
+ * context.
+ */
+ readonly ancestorOrigins: string[];
+ /**
+ * Returns the Location object's URL's fragment (includes leading "#" if
+ * non-empty).
+ * Can be set, to navigate to the same URL with a changed fragment (ignores
+ * leading "#").
+ */
+ hash: string;
+ /**
+ * Returns the Location object's URL's host and port (if different from the
+ * default port for the scheme). Can be set, to navigate to the same URL with
+ * a changed host and port.
+ */
+ host: string;
+ /**
+ * Returns the Location object's URL's host. Can be set, to navigate to the
+ * same URL with a changed host.
+ */
+ hostname: string;
+ /**
+ * Returns the Location object's URL. Can be set, to navigate to the given
+ * URL.
+ */
+ href: string;
+ /** Returns the Location object's URL's origin. */
+ readonly origin: string;
+ /**
+ * Returns the Location object's URL's path.
+ * Can be set, to navigate to the same URL with a changed path.
+ */
+ pathname: string;
+ /**
+ * Returns the Location object's URL's port.
+ * Can be set, to navigate to the same URL with a changed port.
+ */
+ port: string;
+ /**
+ * Returns the Location object's URL's scheme.
+ * Can be set, to navigate to the same URL with a changed scheme.
+ */
+ protocol: string;
+ /**
+ * Returns the Location object's URL's query (includes leading "?" if
+ * non-empty). Can be set, to navigate to the same URL with a changed query
+ * (ignores leading "?").
+ */
+ search: string;
+ /**
+ * Navigates to the given URL.
+ */
+ assign(url: string): void;
+ /**
+ * Reloads the current page.
+ */
+ reload(): void;
+ /** @deprecated */
+ reload(forcedReload: boolean): void;
+ /**
+ * Removes the current page from the session history and navigates to the
+ * given URL.
+ */
+ replace(url: string): void;
+ }
+}
+
+declare namespace blob {
+ // @url js/blob.d.ts
+
+ export const bytesSymbol: unique symbol;
+ export const blobBytesWeakMap: WeakMap<domTypes.Blob, Uint8Array>;
+ export class DenoBlob implements domTypes.Blob {
+ private readonly [bytesSymbol];
+ readonly size: number;
+ readonly type: string;
+ /** A blob object represents a file-like object of immutable, raw data. */
+ constructor(
+ blobParts?: domTypes.BlobPart[],
+ options?: domTypes.BlobPropertyBag
+ );
+ slice(start?: number, end?: number, contentType?: string): DenoBlob;
+ }
+}
+
+declare namespace consoleTypes {
+ // @url js/console.d.ts
+
+ type ConsoleOptions = Partial<{
+ showHidden: boolean;
+ depth: number;
+ colors: boolean;
+ indentLevel: number;
+ }>;
+ export class CSI {
+ static kClear: string;
+ static kClearScreenDown: string;
+ }
+ export const isConsoleInstance: unique symbol;
+ export class Console {
+ private printFunc;
+ indentLevel: number;
+ [isConsoleInstance]: boolean;
+ /** Writes the arguments to stdout */
+ log: (...args: unknown[]) => void;
+ /** Writes the arguments to stdout */
+ debug: (...args: unknown[]) => void;
+ /** Writes the arguments to stdout */
+ info: (...args: unknown[]) => void;
+ /** Writes the properties of the supplied `obj` to stdout */
+ dir: (
+ obj: unknown,
+ options?: Partial<{
+ showHidden: boolean;
+ depth: number;
+ colors: boolean;
+ indentLevel: number;
+ }>
+ ) => void;
+
+ /** From MDN:
+ * Displays an interactive tree of the descendant elements of
+ * the specified XML/HTML element. If it is not possible to display
+ * as an element the JavaScript Object view is shown instead.
+ * The output is presented as a hierarchical listing of expandable
+ * nodes that let you see the contents of child nodes.
+ *
+ * Since we write to stdout, we can't display anything interactive
+ * we just fall back to `console.dir`.
+ */
+ dirxml: (
+ obj: unknown,
+ options?: Partial<{
+ showHidden: boolean;
+ depth: number;
+ colors: boolean;
+ indentLevel: number;
+ }>
+ ) => void;
+
+ /** Writes the arguments to stdout */
+ warn: (...args: unknown[]) => void;
+ /** Writes the arguments to stdout */
+ error: (...args: unknown[]) => void;
+ /** Writes an error message to stdout if the assertion is `false`. If the
+ * assertion is `true`, nothing happens.
+ *
+ * ref: https://console.spec.whatwg.org/#assert
+ */
+ assert: (condition?: boolean, ...args: unknown[]) => void;
+ count: (label?: string) => void;
+ countReset: (label?: string) => void;
+ table: (data: unknown, properties?: string[] | undefined) => void;
+ time: (label?: string) => void;
+ timeLog: (label?: string, ...args: unknown[]) => void;
+ timeEnd: (label?: string) => void;
+ group: (...label: unknown[]) => void;
+ groupCollapsed: (...label: unknown[]) => void;
+ groupEnd: () => void;
+ clear: () => void;
+ trace: (...args: unknown[]) => void;
+ static [Symbol.hasInstance](instance: Console): boolean;
+ }
+ /** A symbol which can be used as a key for a custom method which will be called
+ * when `Deno.inspect()` is called, or when the object is logged to the console.
+ */
+ export const customInspect: unique symbol;
+ /**
+ * `inspect()` converts input into string that has the same format
+ * as printed by `console.log(...)`;
+ */
+ export function inspect(value: unknown, options?: ConsoleOptions): string;
+}
+
+declare namespace event {
+ // @url js/event.d.ts
+
+ export const eventAttributes: WeakMap<object, any>;
+ export class EventInit implements domTypes.EventInit {
+ bubbles: boolean;
+ cancelable: boolean;
+ composed: boolean;
+ constructor({
+ bubbles,
+ cancelable,
+ composed
+ }?: {
+ bubbles?: boolean | undefined;
+ cancelable?: boolean | undefined;
+ composed?: boolean | undefined;
+ });
+ }
+ export class Event implements domTypes.Event {
+ isTrusted: boolean;
+ private _canceledFlag;
+ private _dispatchedFlag;
+ private _initializedFlag;
+ private _inPassiveListenerFlag;
+ private _stopImmediatePropagationFlag;
+ private _stopPropagationFlag;
+ private _path;
+ constructor(type: string, eventInitDict?: domTypes.EventInit);
+ readonly bubbles: boolean;
+ cancelBubble: boolean;
+ cancelBubbleImmediately: boolean;
+ readonly cancelable: boolean;
+ readonly composed: boolean;
+ currentTarget: domTypes.EventTarget;
+ readonly defaultPrevented: boolean;
+ dispatched: boolean;
+ eventPhase: number;
+ readonly initialized: boolean;
+ inPassiveListener: boolean;
+ path: domTypes.EventPath[];
+ relatedTarget: domTypes.EventTarget;
+ target: domTypes.EventTarget;
+ readonly timeStamp: Date;
+ readonly type: string;
+ /** Returns the event’s path (objects on which listeners will be
+ * invoked). This does not include nodes in shadow trees if the
+ * shadow root was created with its ShadowRoot.mode closed.
+ *
+ * event.composedPath();
+ */
+ composedPath(): domTypes.EventPath[];
+ /** Cancels the event (if it is cancelable).
+ * See https://dom.spec.whatwg.org/#set-the-canceled-flag
+ *
+ * event.preventDefault();
+ */
+ preventDefault(): void;
+ /** Stops the propagation of events further along in the DOM.
+ *
+ * event.stopPropagation();
+ */
+ stopPropagation(): void;
+ /** For this particular event, no other listener will be called.
+ * Neither those attached on the same element, nor those attached
+ * on elements which will be traversed later (in capture phase,
+ * for instance).
+ *
+ * event.stopImmediatePropagation();
+ */
+ stopImmediatePropagation(): void;
+ }
+}
+
+declare namespace customEvent {
+ // @url js/custom_event.d.ts
+
+ export const customEventAttributes: WeakMap<object, any>;
+ export class CustomEventInit extends event.EventInit
+ implements domTypes.CustomEventInit {
+ detail: any;
+ constructor({
+ bubbles,
+ cancelable,
+ composed,
+ detail
+ }: domTypes.CustomEventInit);
+ }
+ export class CustomEvent extends event.Event implements domTypes.CustomEvent {
+ constructor(type: string, customEventInitDict?: domTypes.CustomEventInit);
+ readonly detail: any;
+ initCustomEvent(
+ type: string,
+ bubbles?: boolean,
+ cancelable?: boolean,
+ detail?: any
+ ): void;
+ readonly [Symbol.toStringTag]: string;
+ }
+}
+
+declare namespace eventTarget {
+ // @url js/event_target.d.ts
+
+ export class EventListenerOptions implements domTypes.EventListenerOptions {
+ _capture: boolean;
+ constructor({ capture }?: { capture?: boolean | undefined });
+ readonly capture: boolean;
+ }
+ export class AddEventListenerOptions extends EventListenerOptions
+ implements domTypes.AddEventListenerOptions {
+ _passive: boolean;
+ _once: boolean;
+ constructor({
+ capture,
+ passive,
+ once
+ }?: {
+ capture?: boolean | undefined;
+ passive?: boolean | undefined;
+ once?: boolean | undefined;
+ });
+ readonly passive: boolean;
+ readonly once: boolean;
+ }
+ export class EventListener implements domTypes.EventListener {
+ allEvents: domTypes.Event[];
+ atEvents: domTypes.Event[];
+ bubbledEvents: domTypes.Event[];
+ capturedEvents: domTypes.Event[];
+ private _callback;
+ private _options;
+ constructor(
+ callback: (event: domTypes.Event) => void | null,
+ options: boolean | domTypes.AddEventListenerOptions
+ );
+ handleEvent(event: domTypes.Event): void;
+ readonly callback: (event: domTypes.Event) => void | null;
+ readonly options: domTypes.AddEventListenerOptions | boolean;
+ }
+ export const eventTargetAssignedSlot: unique symbol;
+ export const eventTargetHasActivationBehavior: unique symbol;
+ export class EventTarget implements domTypes.EventTarget {
+ [domTypes.eventTargetHost]: domTypes.EventTarget | null;
+ [domTypes.eventTargetListeners]: {
+ [type in string]: domTypes.EventListener[]
+ };
+ [domTypes.eventTargetMode]: string;
+ [domTypes.eventTargetNodeType]: domTypes.NodeType;
+ private [eventTargetAssignedSlot];
+ private [eventTargetHasActivationBehavior];
+ addEventListener(
+ type: string,
+ callback: (event: domTypes.Event) => void | null,
+ options?: domTypes.AddEventListenerOptions | boolean
+ ): void;
+ removeEventListener(
+ type: string,
+ callback: (event: domTypes.Event) => void | null,
+ options?: domTypes.EventListenerOptions | boolean
+ ): void;
+ dispatchEvent(event: domTypes.Event): boolean;
+ readonly [Symbol.toStringTag]: string;
+ }
+}
+
+declare namespace io {
+ // @url js/io.d.ts
+
+ export const EOF: null;
+ export type EOF = null;
+ export enum SeekMode {
+ SEEK_START = 0,
+ SEEK_CURRENT = 1,
+ SEEK_END = 2
+ }
+ export interface Reader {
+ /** Reads up to p.byteLength bytes into `p`. It resolves to the number
+ * of bytes read (`0` < `n` <= `p.byteLength`) and rejects if any error encountered.
+ * Even if `read()` returns `n` < `p.byteLength`, it may use all of `p` as
+ * scratch space during the call. If some data is available but not
+ * `p.byteLength` bytes, `read()` conventionally returns what is available
+ * instead of waiting for more.
+ *
+ * When `read()` encounters end-of-file condition, it returns EOF symbol.
+ *
+ * When `read()` encounters an error, it rejects with an error.
+ *
+ * Callers should always process the `n` > `0` bytes returned before
+ * considering the EOF. Doing so correctly handles I/O errors that happen
+ * after reading some bytes and also both of the allowed EOF behaviors.
+ *
+ * Implementations must not retain `p`.
+ */
+ read(p: Uint8Array): Promise<number | EOF>;
+ }
+ export interface SyncReader {
+ readSync(p: Uint8Array): number | EOF;
+ }
+ export interface Writer {
+ /** Writes `p.byteLength` bytes from `p` to the underlying data
+ * stream. It resolves to the number of bytes written from `p` (`0` <= `n` <=
+ * `p.byteLength`) and any error encountered that caused the write to stop
+ * early. `write()` must return a non-null error if it returns `n` <
+ * `p.byteLength`. write() must not modify the slice data, even temporarily.
+ *
+ * Implementations must not retain `p`.
+ */
+ write(p: Uint8Array): Promise<number>;
+ }
+ export interface SyncWriter {
+ writeSync(p: Uint8Array): number;
+ }
+ export interface Closer {
+ close(): void;
+ }
+ export interface Seeker {
+ /** Seek sets the offset for the next `read()` or `write()` to offset,
+ * interpreted according to `whence`: `SeekStart` means relative to the start
+ * of the file, `SeekCurrent` means relative to the current offset, and
+ * `SeekEnd` means relative to the end. Seek returns the new offset relative
+ * to the start of the file and an error, if any.
+ *
+ * Seeking to an offset before the start of the file is an error. Seeking to
+ * any positive offset is legal, but the behavior of subsequent I/O operations
+ * on the underlying object is implementation-dependent.
+ */
+ seek(offset: number, whence: SeekMode): Promise<void>;
+ }
+ export interface SyncSeeker {
+ seekSync(offset: number, whence: SeekMode): void;
+ }
+ export interface ReadCloser extends Reader, Closer {}
+ export interface WriteCloser extends Writer, Closer {}
+ export interface ReadSeeker extends Reader, Seeker {}
+ export interface WriteSeeker extends Writer, Seeker {}
+ export interface ReadWriteCloser extends Reader, Writer, Closer {}
+ export interface ReadWriteSeeker extends Reader, Writer, Seeker {}
+ /** Copies from `src` to `dst` until either `EOF` is reached on `src`
+ * or an error occurs. It returns the number of bytes copied and the first
+ * error encountered while copying, if any.
+ *
+ * Because `copy()` is defined to read from `src` until `EOF`, it does not
+ * treat an `EOF` from `read()` as an error to be reported.
+ */
+ export function copy(dst: Writer, src: Reader): Promise<number>;
+ /** Turns `r` into async iterator.
+ *
+ * for await (const chunk of toAsyncIterator(reader)) {
+ * console.log(chunk)
+ * }
+ */
+ export function toAsyncIterator(r: Reader): AsyncIterableIterator<Uint8Array>;
+}
+
+declare namespace fetchTypes {
+ // @url js/fetch.d.ts
+
+ class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser {
+ private rid;
+ readonly contentType: string;
+ bodyUsed: boolean;
+ private _bodyPromise;
+ private _data;
+ readonly locked: boolean;
+ readonly body: null | Body;
+ constructor(rid: number, contentType: string);
+ private _bodyBuffer;
+ arrayBuffer(): Promise<ArrayBuffer>;
+ blob(): Promise<domTypes.Blob>;
+ formData(): Promise<domTypes.FormData>;
+ json(): Promise<any>;
+ text(): Promise<string>;
+ read(p: Uint8Array): Promise<number | io.EOF>;
+ close(): void;
+ cancel(): Promise<void>;
+ getReader(): domTypes.ReadableStreamReader;
+ tee(): [domTypes.ReadableStream, domTypes.ReadableStream];
+ [Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array>;
+ }
+ export class Response implements domTypes.Response {
+ readonly url: string;
+ readonly status: number;
+ statusText: string;
+ readonly type = "basic";
+ readonly redirected: boolean;
+ headers: domTypes.Headers;
+ readonly trailer: Promise<domTypes.Headers>;
+ bodyUsed: boolean;
+ readonly body: Body;
+ constructor(
+ url: string,
+ status: number,
+ headersList: Array<[string, string]>,
+ rid: number,
+ redirected_: boolean,
+ body_?: null | Body
+ );
+ arrayBuffer(): Promise<ArrayBuffer>;
+ blob(): Promise<domTypes.Blob>;
+ formData(): Promise<domTypes.FormData>;
+ json(): Promise<any>;
+ text(): Promise<string>;
+ readonly ok: boolean;
+ clone(): domTypes.Response;
+ }
+ /** Fetch a resource from the network. */
+ export function fetch(
+ input: domTypes.Request | string,
+ init?: domTypes.RequestInit
+ ): Promise<Response>;
+}
+
+declare namespace textEncoding {
+ // @url js/text_encoding.d.ts
+
+ export function atob(s: string): string;
+ /** Creates a base-64 ASCII string from the input string. */
+ export function btoa(s: string): string;
+ export interface TextDecodeOptions {
+ stream?: false;
+ }
+ export interface TextDecoderOptions {
+ fatal?: boolean;
+ ignoreBOM?: false;
+ }
+ export class TextDecoder {
+ private _encoding;
+ /** Returns encoding's name, lowercased. */
+ readonly encoding: string;
+ /** Returns `true` if error mode is "fatal", and `false` otherwise. */
+ readonly fatal: boolean;
+ /** Returns `true` if ignore BOM flag is set, and `false` otherwise. */
+ readonly ignoreBOM = false;
+ constructor(label?: string, options?: TextDecoderOptions);
+ /** Returns the result of running encoding's decoder. */
+ decode(input?: domTypes.BufferSource, options?: TextDecodeOptions): string;
+ readonly [Symbol.toStringTag]: string;
+ }
+ interface TextEncoderEncodeIntoResult {
+ read: number;
+ written: number;
+ }
+ export class TextEncoder {
+ /** Returns "utf-8". */
+ readonly encoding = "utf-8";
+ /** Returns the result of running UTF-8's encoder. */
+ encode(input?: string): Uint8Array;
+ encodeInto(input: string, dest: Uint8Array): TextEncoderEncodeIntoResult;
+ readonly [Symbol.toStringTag]: string;
+ }
+}
+
+declare namespace timers {
+ // @url js/timers.d.ts
+
+ export type Args = unknown[];
+ /** Sets a timer which executes a function once after the timer expires. */
+ export function setTimeout(
+ cb: (...args: Args) => void,
+ delay?: number,
+ ...args: Args
+ ): number;
+ /** Repeatedly calls a function , with a fixed time delay between each call. */
+ export function setInterval(
+ cb: (...args: Args) => void,
+ delay?: number,
+ ...args: Args
+ ): number;
+ export function clearTimeout(id?: number): void;
+ export function clearInterval(id?: number): void;
+}
+
+declare namespace urlSearchParams {
+ // @url js/url_search_params.d.ts
+
+ export class URLSearchParams {
+ private params;
+ private url;
+ constructor(init?: string | string[][] | Record<string, string>);
+ private updateSteps;
+ /** Appends a specified key/value pair as a new search parameter.
+ *
+ * searchParams.append('name', 'first');
+ * searchParams.append('name', 'second');
+ */
+ append(name: string, value: string): void;
+ /** Deletes the given search parameter and its associated value,
+ * from the list of all search parameters.
+ *
+ * searchParams.delete('name');
+ */
+ delete(name: string): void;
+ /** Returns all the values associated with a given search parameter
+ * as an array.
+ *
+ * searchParams.getAll('name');
+ */
+ getAll(name: string): string[];
+ /** Returns the first value associated to the given search parameter.
+ *
+ * searchParams.get('name');
+ */
+ get(name: string): string | null;
+ /** Returns a Boolean that indicates whether a parameter with the
+ * specified name exists.
+ *
+ * searchParams.has('name');
+ */
+ has(name: string): boolean;
+ /** Sets the value associated with a given search parameter to the
+ * given value. If there were several matching values, this method
+ * deletes the others. If the search parameter doesn't exist, this
+ * method creates it.
+ *
+ * searchParams.set('name', 'value');
+ */
+ set(name: string, value: string): void;
+ /** Sort all key/value pairs contained in this object in place and
+ * return undefined. The sort order is according to Unicode code
+ * points of the keys.
+ *
+ * searchParams.sort();
+ */
+ sort(): void;
+ /** Calls a function for each element contained in this object in
+ * place and return undefined. Optionally accepts an object to use
+ * as this when executing callback as second argument.
+ *
+ * searchParams.forEach((value, key, parent) => {
+ * console.log(value, key, parent);
+ * });
+ *
+ */
+ forEach(
+ callbackfn: (value: string, key: string, parent: URLSearchParams) => void,
+ thisArg?: any
+ ): void;
+ /** Returns an iterator allowing to go through all keys contained
+ * in this object.
+ *
+ * for (const key of searchParams.keys()) {
+ * console.log(key);
+ * }
+ */
+ keys(): Iterable<string>;
+ /** Returns an iterator allowing to go through all values contained
+ * in this object.
+ *
+ * for (const value of searchParams.values()) {
+ * console.log(value);
+ * }
+ */
+ values(): Iterable<string>;
+ /** Returns an iterator allowing to go through all key/value
+ * pairs contained in this object.
+ *
+ * for (const [key, value] of searchParams.entries()) {
+ * console.log(key, value);
+ * }
+ */
+ entries(): Iterable<[string, string]>;
+ /** Returns an iterator allowing to go through all key/value
+ * pairs contained in this object.
+ *
+ * for (const [key, value] of searchParams[Symbol.iterator]()) {
+ * console.log(key, value);
+ * }
+ */
+ [Symbol.iterator](): Iterable<[string, string]>;
+ /** Returns a query string suitable for use in a URL.
+ *
+ * searchParams.toString();
+ */
+ toString(): string;
+ private _handleStringInitialization;
+ private _handleArrayInitialization;
+ }
+}
+
+declare namespace url {
+ // @url js/url.d.ts
+
+ export const blobURLMap: Map<string, domTypes.Blob>;
+ export class URL {
+ private _parts;
+ private _searchParams;
+ private _updateSearchParams;
+ hash: string;
+ host: string;
+ hostname: string;
+ href: string;
+ readonly origin: string;
+ password: string;
+ pathname: string;
+ port: string;
+ protocol: string;
+ search: string;
+ username: string;
+ readonly searchParams: urlSearchParams.URLSearchParams;
+ constructor(url: string, base?: string | URL);
+ toString(): string;
+ toJSON(): string;
+ static createObjectURL(b: domTypes.Blob): string;
+ static revokeObjectURL(url: string): void;
+ }
+}
+
+declare namespace workers {
+ // @url js/workers.d.ts
+
+ export function encodeMessage(data: any): Uint8Array;
+ export function decodeMessage(dataIntArray: Uint8Array): any;
+ export let onmessage: (e: { data: any }) => void;
+ export function postMessage(data: any): void;
+ export function getMessage(): Promise<any>;
+ export let isClosing: boolean;
+ export function workerClose(): void;
+ export function workerMain(): Promise<void>;
+ export interface Worker {
+ onerror?: () => void;
+ onmessage?: (e: { data: any }) => void;
+ onmessageerror?: () => void;
+ postMessage(data: any): void;
+ closed: Promise<void>;
+ }
+ export interface WorkerOptions {}
+ /** Extended Deno Worker initialization options.
+ * `noDenoNamespace` hides global `window.Deno` namespace for
+ * spawned worker and nested workers spawned by it (default: false).
+ */
+ export interface DenoWorkerOptions extends WorkerOptions {
+ noDenoNamespace?: boolean;
+ }
+ export class WorkerImpl implements Worker {
+ private readonly rid;
+ private isClosing;
+ private readonly isClosedPromise;
+ onerror?: () => void;
+ onmessage?: (data: any) => void;
+ onmessageerror?: () => void;
+ constructor(specifier: string, options?: DenoWorkerOptions);
+ readonly closed: Promise<void>;
+ postMessage(data: any): void;
+ private run;
+ }
+}
+
+declare namespace performanceUtil {
+ // @url js/performance.d.ts
+
+ export class Performance {
+ /** Returns a current time from Deno's start in milliseconds.
+ *
+ * Use the flag --allow-hrtime return a precise value.
+ *
+ * const t = performance.now();
+ * console.log(`${t} ms since start!`);
+ */
+ now(): number;
+ }
+}
+
+// @url js/lib.web_assembly.d.ts
+
+// This follows the WebIDL at: https://webassembly.github.io/spec/js-api/
+// And follow on WebIDL at: https://webassembly.github.io/spec/web-api/
+
+/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any */
+
+declare namespace WebAssembly {
+ interface WebAssemblyInstantiatedSource {
+ module: Module;
+ instance: Instance;
+ }
+
+ /** Compiles a `WebAssembly.Module` from WebAssembly binary code. This
+ * function is useful if it is necessary to a compile a module before it can
+ * be instantiated (otherwise, the `WebAssembly.instantiate()` function
+ * should be used). */
+ function compile(bufferSource: domTypes.BufferSource): Promise<Module>;
+
+ /** Compiles a `WebAssembly.Module` directly from a streamed underlying
+ * source. This function is useful if it is necessary to a compile a module
+ * before it can be instantiated (otherwise, the
+ * `WebAssembly.instantiateStreaming()` function should be used). */
+ function compileStreaming(
+ source: Promise<domTypes.Response>
+ ): Promise<Module>;
+
+ /** Takes the WebAssembly binary code, in the form of a typed array or
+ * `ArrayBuffer`, and performs both compilation and instantiation in one step.
+ * The returned `Promise` resolves to both a compiled `WebAssembly.Module` and
+ * its first `WebAssembly.Instance`. */
+ function instantiate(
+ bufferSource: domTypes.BufferSource,
+ importObject?: object
+ ): Promise<WebAssemblyInstantiatedSource>;
+
+ /** Takes an already-compiled `WebAssembly.Module` and returns a `Promise`
+ * that resolves to an `Instance` of that `Module`. This overload is useful if
+ * the `Module` has already been compiled. */
+ function instantiate(
+ module: Module,
+ importObject?: object
+ ): Promise<Instance>;
+
+ /** Compiles and instantiates a WebAssembly module directly from a streamed
+ * underlying source. This is the most efficient, optimized way to load wasm
+ * code. */
+ function instantiateStreaming(
+ source: Promise<domTypes.Response>,
+ importObject?: object
+ ): Promise<WebAssemblyInstantiatedSource>;
+
+ /** Validates a given typed array of WebAssembly binary code, returning
+ * whether the bytes form a valid wasm module (`true`) or not (`false`). */
+ function validate(bufferSource: domTypes.BufferSource): boolean;
+
+ type ImportExportKind = "function" | "table" | "memory" | "global";
+
+ interface ModuleExportDescriptor {
+ name: string;
+ kind: ImportExportKind;
+ }
+ interface ModuleImportDescriptor {
+ module: string;
+ name: string;
+ kind: ImportExportKind;
+ }
+
+ class Module {
+ constructor(bufferSource: domTypes.BufferSource);
+
+ /** Given a `Module` and string, returns a copy of the contents of all
+ * custom sections in the module with the given string name. */
+ static customSections(
+ moduleObject: Module,
+ sectionName: string
+ ): ArrayBuffer;
+
+ /** Given a `Module`, returns an array containing descriptions of all the
+ * declared exports. */
+ static exports(moduleObject: Module): ModuleExportDescriptor[];
+
+ /** Given a `Module`, returns an array containing descriptions of all the
+ * declared imports. */
+ static imports(moduleObject: Module): ModuleImportDescriptor[];
+ }
+
+ class Instance<T extends object = { [key: string]: any }> {
+ constructor(module: Module, importObject?: object);
+
+ /** An object containing as its members all the functions exported from the
+ * WebAssembly module instance, to allow them to be accessed and used by
+ * JavaScript. */
+ readonly exports: T;
+ }
+
+ interface MemoryDescriptor {
+ initial: number;
+ maximum?: number;
+ }
+
+ class Memory {
+ constructor(descriptor: MemoryDescriptor);
+
+ /** An accessor property that returns the buffer contained in the memory. */
+ readonly buffer: ArrayBuffer;
+
+ /** Increases the size of the memory instance by a specified number of
+ * WebAssembly pages (each one is 64KB in size). */
+ grow(delta: number): number;
+ }
+
+ type TableKind = "anyfunc";
+
+ interface TableDescriptor {
+ element: TableKind;
+ initial: number;
+ maximum?: number;
+ }
+
+ class Table {
+ constructor(descriptor: TableDescriptor);
+
+ /** Returns the length of the table, i.e. the number of elements. */
+ readonly length: number;
+
+ /** Accessor function — gets the element stored at a given index. */
+ get(index: number): (...args: any[]) => any;
+
+ /** Increases the size of the Table instance by a specified number of
+ * elements. */
+ grow(delta: number): number;
+
+ /** Sets an element stored at a given index to a given value. */
+ set(index: number, value: (...args: any[]) => any): void;
+ }
+
+ interface GlobalDescriptor {
+ value: string;
+ mutable?: boolean;
+ }
+
+ /** Represents a global variable instance, accessible from both JavaScript and
+ * importable/exportable across one or more `WebAssembly.Module` instances.
+ * This allows dynamic linking of multiple modules. */
+ class Global {
+ constructor(descriptor: GlobalDescriptor, value?: any);
+
+ /** Old-style method that returns the value contained inside the global
+ * variable. */
+ valueOf(): any;
+
+ /** The value contained inside the global variable — this can be used to
+ * directly set and get the global's value. */
+ value: any;
+ }
+
+ /** Indicates an error during WebAssembly decoding or validation */
+ class CompileError extends Error {
+ constructor(message: string, fileName?: string, lineNumber?: string);
+ }
+
+ /** Indicates an error during module instantiation (besides traps from the
+ * start function). */
+ class LinkError extends Error {
+ constructor(message: string, fileName?: string, lineNumber?: string);
+ }
+
+ /** Is thrown whenever WebAssembly specifies a trap. */
+ class RuntimeError extends Error {
+ constructor(message: string, fileName?: string, lineNumber?: string);
+ }
+}
+
+/* eslint-enable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any */
diff --git a/rollup.config.js b/rollup.config.js
index 793b5bd6c..cc583c59c 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -29,56 +29,6 @@ const tsconfigOverride = {
}
};
-/** this is a rollup plugin which will look for imports ending with `!string` and resolve
- * them with a module that will inline the contents of the file as a string. Needed to
- * support `js/assets.ts`.
- * @param {any} param0
- */
-function strings(
- { include, exclude } = { include: undefined, exclude: undefined }
-) {
- if (!include) {
- throw new Error("include option must be passed");
- }
-
- const filter = createFilter(include, exclude);
-
- return {
- name: "strings",
-
- /**
- * @param {string} importee
- */
- resolveId(importee) {
- if (importee.endsWith("!string")) {
- // strip the `!string` from `importee`
- importee = importee.slice(0, importee.lastIndexOf("!string"));
- if (!importee.startsWith("gen/")) {
- // this is a static asset which is located relative to the root of
- // the source project
- return path.resolve(path.join(__dirname, importee));
- }
- // this is an asset which has been generated, therefore it will be
- // located within the build path
- return path.resolve(path.join(process.cwd(), importee));
- }
- },
-
- /**
- * @param {any} code
- * @param {string} id
- */
- transform(code, id) {
- if (filter(id)) {
- return {
- code: `export default ${JSON.stringify(code)};`,
- map: { mappings: "" }
- };
- }
- }
- };
-}
-
const archNodeToDeno = {
x64: "x64"
};
@@ -191,15 +141,6 @@ export default function makeConfig(commandOptions) {
module: mockPath
}),
- // Provides inlining of file contents for `js/assets.ts`
- strings({
- include: [
- "*.d.ts",
- `${__dirname}/**/*.d.ts`,
- `${process.cwd()}/**/*.d.ts`
- ]
- }),
-
// Allows rollup to resolve modules based on Node.js resolution
nodeResolve(),
diff --git a/tests/types.out b/tests/types.out
index b07e10762..2d5a39e64 100644
--- a/tests/types.out
+++ b/tests/types.out
@@ -1,7 +1,5 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-/// <reference no-default-lib="true" />
-/// <reference lib="esnext" />
+[WILDCARD]
declare namespace Deno {
[WILDCARD]
diff --git a/tools/target_test.py b/tools/target_test.py
index 6ff3c11e8..da1bd5537 100644
--- a/tools/target_test.py
+++ b/tools/target_test.py
@@ -34,16 +34,6 @@ class TestTarget(DenoTestCase):
def test_core_http_benchmark(self):
self._test("deno_core_http_bench_test")
- def test_ts_library_builder(self):
- result = run_output([
- "node", "./node_modules/.bin/ts-node", "--project",
- "tools/ts_library_builder/tsconfig.json",
- "tools/ts_library_builder/test.ts"
- ],
- quiet=True)
- self.assertEqual(result.code, 0)
- assert "ts_library_builder ok" in result.out
-
def test_no_color(self):
t = os.path.join(tests_path, "no_color.js")
result = run_output([self.deno_exe, "run", t],
diff --git a/tools/ts_library_builder/README.md b/tools/ts_library_builder/README.md
deleted file mode 100644
index 2eca169ae..000000000
--- a/tools/ts_library_builder/README.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# ts_library_builder
-
-This tool allows us to produce a single TypeScript declaration file that
-describes the complete Deno runtime, including global variables and the built-in
-`Deno` global object. The output of this tool, `lib.deno_runtime.d.ts`, serves
-several purposes:
-
-1. It is passed to the TypeScript compiler `js/compiler.ts`, so that TypeScript
- knows what types to expect and can validate code against the runtime
- environment.
-2. It is outputted to stdout by `deno types`, so that users can easily have
- access to the complete declaration file. Editors can use this in the future
- to perform type checking.
-3. Because JSDocs are maintained, this serves as a simple documentation page for
- Deno. We will use this file to generate HTML docs in the future.
-
-The tool depends upon a couple libraries:
-
-- [`ts-node`](https://www.npmjs.com/package/ts-node) to provide just in time
- transpiling of TypeScript for the tool itself.
-- [`ts-morph`](https://www.npmjs.com/package/ts-morph) which provides a more
- rational and functional interface to the TypeScript AST to make manipulations
- easier.
-- [`prettier`](https://www.npmjs.com/package/prettier) and
- [`@types/prettier`](https://www.npmjs.com/package/@types/prettier) to format
- the output.
-
-## Design
-
-Ideally we wouldn't have to build this tool at all, and could simply use `tsc`
-to output this declaration file. While, `--emitDeclarationsOnly`, `--outFile`
-and `--module AMD` generates a single declaration file, it isn't clean. It was
-never designed for a library generation, where what is available in a runtime
-environment significantly differs from the code that creates that environment's
-structure.
-
-Therefore this tool injects some of the knowledge of what occurs in the Deno
-runtime environment as well as ensures that the output file is more clean and
-logical for an end user. In the deno runtime, code runs in a global scope that
-is defined in `js/global.ts`. This contains global scope items that one
-reasonably expects in a JavaScript runtime, like `console`. It also defines the
-global scope on a self-reflective `window` variable. There is currently only one
-module of Deno specific APIs which is available to the user. This is defined in
-`js/deno.ts`.
-
-This tool takes advantage of an experimental feature of TypeScript that items
-that are not really intended to be part of the public API are marked with a
-comment pragma of `@internal` and then are not emitted when generating type
-definitions. In addition TypeScript will _tree-shake_ any dependencies tied to
-that "hidden" API and elide them as well. This really helps keep the public API
-clean and as minimal as needed.
-
-In order to create the default type library, the process at a high-level looks
-like this:
-
-- We read in all of the runtime environment definition code into TypeScript AST
- parser "project".
-- We emit the TypeScript type definitions only into another AST parser
- "project".
-- We process the `deno` namespace/module, by "flattening" the type definition
- file.
- - We determine the exported symbols for `js/deno.ts`.
- - We recurse over all imports/exports of the modules, only exporting those
- symbols which are finally exported by `js/deno.ts`.
- - We replace the import/export with the type information from the source file.
- - This process assumes that all the modules that feed `js/deno.ts` will have a
- public type API that does not have name conflicts.
-- We process the `js/globals.ts` file to generate the global namespace.
- - We create a `Window` interface and a `global` scope augmentation namespace.
- - We iterate over augmentations to the `window` variable declared in the file,
- extract the type information and apply it to both a global variable
- declaration and a property on the `Window` interface.
- - We identify any type aliases in the module and declare them globally.
-- We take each namespace import to `js/globals.ts`, we resolve the emitted
- declaration `.d.ts` file and create it as its own namespace within the global
- scope. It is unsafe to just flatten these, because there is a high risk of
- collisions, but also, it makes authoring the types easier within the generated
- interface and variable declarations.
-- We then validate the resulting definition file and write it out to the
- appropriate build path.
-
-## TODO
-
-- The tool does not _tree-shake_ when flattening imports. This means there are
- extraneous types that get included that are not really needed and it means
- that `gen/msg_generated.ts` has to be explicitly carved down.
-- Complete the tests... we have some coverage, but not a lot of what is in
- `ast_util_test` which is being tested implicitly.
diff --git a/tools/ts_library_builder/ast_util.ts b/tools/ts_library_builder/ast_util.ts
deleted file mode 100644
index 142b26c00..000000000
--- a/tools/ts_library_builder/ast_util.ts
+++ /dev/null
@@ -1,499 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { basename, dirname, join, relative } from "path";
-import { readFileSync } from "fs";
-import { EOL } from "os";
-import {
- ExportDeclaration,
- ImportDeclaration,
- InterfaceDeclaration,
- JSDoc,
- Project,
- PropertySignature,
- SourceFile,
- StatementedNode,
- ts,
- TypeAliasDeclaration,
- TypeGuards,
- VariableStatement,
- VariableDeclarationKind
-} from "ts-morph";
-
-let silent = false;
-
-/** Logs a message to the console. */
-export function log(message: any = "", ...args: any[]): void {
- if (!silent) {
- console.log(message, ...args);
- }
-}
-
-/** Sets the silent flag which impacts logging to the console. */
-export function setSilent(value = false): void {
- silent = value;
-}
-
-/** Add a property to an interface */
-export function addInterfaceProperty(
- interfaceDeclaration: InterfaceDeclaration,
- name: string,
- type: string,
- jsdocs?: JSDoc[]
-): PropertySignature {
- return interfaceDeclaration.addProperty({
- name,
- type,
- docs: jsdocs && jsdocs.map(jsdoc => jsdoc.getText())
- });
-}
-
-/** Add `@url` comment to node. */
-export function addSourceComment(
- node: StatementedNode,
- sourceFile: SourceFile,
- rootPath: string
-): void {
- node.insertStatements(
- 0,
- `// @url ${relative(rootPath, sourceFile.getFilePath())}\n\n`
- );
-}
-
-/** Add a declaration of a type alias to a node */
-export function addTypeAlias(
- node: StatementedNode,
- name: string,
- type: string,
- hasDeclareKeyword = false,
- jsdocs?: JSDoc[]
-): TypeAliasDeclaration {
- return node.addTypeAlias({
- name,
- type,
- docs: jsdocs && jsdocs.map(jsdoc => jsdoc.getText()),
- hasDeclareKeyword
- });
-}
-
-/** Add a declaration of an interface to a node */
-export function addInterfaceDeclaration(
- node: StatementedNode,
- interfaceDeclaration: InterfaceDeclaration
-) {
- const interfaceStructure = interfaceDeclaration.getStructure();
-
- return node.addInterface({
- name: interfaceStructure.name,
- properties: interfaceStructure.properties,
- docs: interfaceStructure.docs,
- hasDeclareKeyword: true
- });
-}
-
-/** Add a declaration of a variable to a node */
-export function addVariableDeclaration(
- node: StatementedNode,
- name: string,
- type: string,
- isConst: boolean,
- hasDeclareKeyword?: boolean,
- jsdocs?: JSDoc[]
-): VariableStatement {
- return node.addVariableStatement({
- declarationKind: isConst
- ? VariableDeclarationKind.Const
- : VariableDeclarationKind.Let,
- declarations: [{ name, type }],
- docs: jsdocs && jsdocs.map(jsdoc => jsdoc.getText()),
- hasDeclareKeyword
- });
-}
-
-/** Copy one source file to the end of another source file. */
-export function appendSourceFile(
- sourceFile: SourceFile,
- targetSourceFile: SourceFile
-): void {
- targetSourceFile.addStatements(`\n${sourceFile.print()}`);
-}
-
-/** Used when formatting diagnostics */
-const formatDiagnosticHost: ts.FormatDiagnosticsHost = {
- getCurrentDirectory() {
- return process.cwd();
- },
- getCanonicalFileName(path: string) {
- return path;
- },
- getNewLine() {
- return EOL;
- }
-};
-
-/** Log diagnostics to the console with colour. */
-export function logDiagnostics(diagnostics: ts.Diagnostic[]): void {
- if (diagnostics.length) {
- console.log(
- ts.formatDiagnosticsWithColorAndContext(diagnostics, formatDiagnosticHost)
- );
- }
-}
-
-/** Check diagnostics, and if any exist, exit the process */
-export function checkDiagnostics(project: Project, onlyFor?: string[]): void {
- const program = project.getProgram();
- const diagnostics = [
- ...program.getGlobalDiagnostics(),
- ...program.getSyntacticDiagnostics(),
- ...program.getSemanticDiagnostics(),
- ...program.getDeclarationDiagnostics()
- ]
- .filter(diagnostic => {
- const sourceFile = diagnostic.getSourceFile();
- return onlyFor && sourceFile
- ? onlyFor.includes(sourceFile.getFilePath())
- : true;
- })
- .map(diagnostic => diagnostic.compilerObject);
-
- logDiagnostics(diagnostics);
-
- if (diagnostics.length) {
- process.exit(1);
- }
-}
-
-function createDeclarationError(
- msg: string,
- declaration: ImportDeclaration | ExportDeclaration
-): Error {
- return new Error(
- `${msg}\n` +
- ` In: "${declaration.getSourceFile().getFilePath()}"\n` +
- ` Text: "${declaration.getText()}"`
- );
-}
-
-export interface FlattenNamespaceOptions {
- customSources?: { [sourceFilePath: string]: string };
- debug?: boolean;
- rootPath: string;
- sourceFile: SourceFile;
-}
-
-/** Returns a string which indicates the source file as the source */
-export function getSourceComment(
- sourceFile: SourceFile,
- rootPath: string
-): string {
- return `\n// @url ${relative(rootPath, sourceFile.getFilePath())}\n\n`;
-}
-
-/** Return a set of fully qualified symbol names for the files exports */
-function getExportedSymbols(sourceFile: SourceFile): Set<string> {
- const exportedSymbols = new Set<string>();
- const exportDeclarations = sourceFile.getExportDeclarations();
- for (const exportDeclaration of exportDeclarations) {
- const exportSpecifiers = exportDeclaration.getNamedExports();
- for (const exportSpecifier of exportSpecifiers) {
- const aliasedSymbol = exportSpecifier
- .getSymbolOrThrow()
- .getAliasedSymbol();
- if (aliasedSymbol) {
- exportedSymbols.add(aliasedSymbol.getFullyQualifiedName());
- }
- }
- }
- return exportedSymbols;
-}
-
-/** Take a namespace and flatten all exports. */
-export function flattenNamespace({
- customSources,
- debug,
- rootPath,
- sourceFile
-}: FlattenNamespaceOptions): string {
- const sourceFiles = new Set<SourceFile>();
- let output = "";
- const exportedSymbols = getExportedSymbols(sourceFile);
-
- function flattenDeclarations(
- declaration: ImportDeclaration | ExportDeclaration
- ): void {
- const declarationSourceFile = declaration.getModuleSpecifierSourceFile();
- if (declarationSourceFile) {
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
- processSourceFile(declarationSourceFile);
- declaration.remove();
- }
- }
-
- function rectifyNodes(currentSourceFile: SourceFile): void {
- currentSourceFile.forEachChild(node => {
- if (TypeGuards.isAmbientableNode(node)) {
- node.setHasDeclareKeyword(false);
- }
- if (TypeGuards.isExportableNode(node)) {
- const nodeSymbol = node.getSymbol();
- if (
- nodeSymbol &&
- !exportedSymbols.has(nodeSymbol.getFullyQualifiedName())
- ) {
- node.setIsExported(false);
- }
- }
- });
- }
-
- function processSourceFile(
- currentSourceFile: SourceFile
- ): string | undefined {
- if (sourceFiles.has(currentSourceFile)) {
- return;
- }
- sourceFiles.add(currentSourceFile);
-
- const currentSourceFilePath = currentSourceFile
- .getFilePath()
- .replace(/(\.d)?\.ts$/, "");
- log("Process source file:", currentSourceFilePath);
- if (customSources && currentSourceFilePath in customSources) {
- log(" Using custom source.");
- output += customSources[currentSourceFilePath];
- return;
- }
-
- currentSourceFile.getImportDeclarations().forEach(flattenDeclarations);
- currentSourceFile.getExportDeclarations().forEach(flattenDeclarations);
-
- rectifyNodes(currentSourceFile);
-
- output +=
- (debug ? getSourceComment(currentSourceFile, rootPath) : "") +
- currentSourceFile.print();
- }
-
- sourceFile.getExportDeclarations().forEach(exportDeclaration => {
- const exportedSourceFile = exportDeclaration.getModuleSpecifierSourceFile();
- if (exportedSourceFile) {
- processSourceFile(exportedSourceFile);
- } else {
- throw createDeclarationError("Missing source file.", exportDeclaration);
- }
- exportDeclaration.remove();
- });
-
- rectifyNodes(sourceFile);
-
- return (
- output +
- (debug ? getSourceComment(sourceFile, rootPath) : "") +
- sourceFile.print()
- );
-}
-
-interface InlineFilesOptions {
- basePath: string;
- debug?: boolean;
- inline: string[];
- targetSourceFile: SourceFile;
-}
-
-/** Inline files into the target source file. */
-export function inlineFiles({
- basePath,
- debug,
- inline,
- targetSourceFile
-}: InlineFilesOptions): void {
- for (const filename of inline) {
- const text = readFileSync(filename, {
- encoding: "utf8"
- });
- targetSourceFile.addStatements(
- debug
- ? `\n// @url ${relative(basePath, filename)}\n\n${text}`
- : `\n${text}`
- );
- }
-}
-
-/** Load a set of files into a file system host. */
-export function loadFiles(
- project: Project,
- filePaths: string[],
- rebase?: string
-): void {
- const fileSystem = project.getFileSystem();
- for (const filePath of filePaths) {
- const fileText = readFileSync(filePath, {
- encoding: "utf8"
- });
- fileSystem.writeFileSync(
- rebase ? join(rebase, basename(filePath)) : filePath,
- fileText
- );
- }
-}
-
-/**
- * Load and write to a virtual file system all the default libs needed to
- * resolve types on project.
- */
-export function loadDtsFiles(
- project: Project,
- compilerOptions: ts.CompilerOptions
-): void {
- const libSourcePath = dirname(ts.getDefaultLibFilePath(compilerOptions));
- // TODO (@kitsonk) Add missing libs when ts-morph supports TypeScript 3.4
- loadFiles(
- project,
- [
- "lib.es2015.collection.d.ts",
- "lib.es2015.core.d.ts",
- "lib.es2015.d.ts",
- "lib.es2015.generator.d.ts",
- "lib.es2015.iterable.d.ts",
- "lib.es2015.promise.d.ts",
- "lib.es2015.proxy.d.ts",
- "lib.es2015.reflect.d.ts",
- "lib.es2015.symbol.d.ts",
- "lib.es2015.symbol.wellknown.d.ts",
- "lib.es2016.array.include.d.ts",
- "lib.es2016.d.ts",
- "lib.es2017.d.ts",
- "lib.es2017.intl.d.ts",
- "lib.es2017.object.d.ts",
- "lib.es2017.sharedmemory.d.ts",
- "lib.es2017.string.d.ts",
- "lib.es2017.typedarrays.d.ts",
- "lib.es2018.d.ts",
- "lib.es2018.intl.d.ts",
- "lib.es2018.promise.d.ts",
- "lib.es5.d.ts",
- "lib.esnext.d.ts",
- "lib.esnext.array.d.ts",
- "lib.esnext.asynciterable.d.ts",
- "lib.esnext.intl.d.ts",
- "lib.esnext.symbol.d.ts"
- ].map(fileName => join(libSourcePath, fileName)),
- "node_modules/typescript/lib/"
- );
-}
-
-export interface NamespaceSourceFileOptions {
- debug?: boolean;
- namespace?: string;
- namespaces: Set<string>;
- rootPath: string;
- sourceFileMap: Map<SourceFile, string>;
-}
-
-/**
- * Take a source file (`.d.ts`) and convert it to a namespace, resolving any
- * imports as their own namespaces.
- */
-export function namespaceSourceFile(
- sourceFile: SourceFile,
- {
- debug,
- namespace,
- namespaces,
- rootPath,
- sourceFileMap
- }: NamespaceSourceFileOptions
-): string {
- if (sourceFileMap.has(sourceFile)) {
- return "";
- }
- if (!namespace) {
- namespace = sourceFile.getBaseNameWithoutExtension();
- }
- sourceFileMap.set(sourceFile, namespace);
-
- sourceFile.forEachChild(node => {
- if (TypeGuards.isAmbientableNode(node)) {
- node.setHasDeclareKeyword(false);
- }
- });
-
- // TODO need to properly unwrap this
- const globalNamespace = sourceFile.getNamespace("global");
- let globalNamespaceText = "";
- if (globalNamespace) {
- const structure = globalNamespace.getStructure();
- if (structure.bodyText && typeof structure.bodyText === "string") {
- globalNamespaceText = structure.bodyText;
- } else {
- throw new TypeError("Unexpected global declaration structure.");
- }
- }
- if (globalNamespace) {
- globalNamespace.remove();
- }
-
- const output = sourceFile
- .getImportDeclarations()
- .filter(declaration => {
- const dsf = declaration.getModuleSpecifierSourceFile();
- if (dsf == null) {
- try {
- const namespaceName = declaration
- .getNamespaceImportOrThrow()
- .getText();
- if (!namespaces.has(namespaceName)) {
- throw createDeclarationError(
- "Already defined source file under different namespace.",
- declaration
- );
- }
- } catch (e) {
- throw createDeclarationError(
- `Unsupported import clause: ${e}`,
- declaration
- );
- }
- declaration.remove();
- }
- return dsf;
- })
- .map(declaration => {
- if (
- declaration.getNamedImports().length ||
- !declaration.getNamespaceImport()
- ) {
- throw createDeclarationError("Unsupported import clause.", declaration);
- }
- const text = namespaceSourceFile(
- declaration.getModuleSpecifierSourceFileOrThrow(),
- {
- debug,
- namespace: declaration.getNamespaceImportOrThrow().getText(),
- namespaces,
- rootPath,
- sourceFileMap
- }
- );
- declaration.remove();
- return text;
- })
- .join("\n");
- sourceFile
- .getExportDeclarations()
- .forEach(declaration => declaration.remove());
-
- namespaces.add(namespace);
-
- return `${output}
- ${globalNamespaceText || ""}
-
- declare namespace ${namespace} {
- ${debug ? getSourceComment(sourceFile, rootPath) : ""}
- ${sourceFile.getText()}
- }`;
-}
-
-/** Mirrors TypeScript's handling of paths */
-export function normalizeSlashes(path: string): string {
- return path.replace(/\\/g, "/");
-}
diff --git a/tools/ts_library_builder/build_library.ts b/tools/ts_library_builder/build_library.ts
deleted file mode 100644
index 0a18abcbb..000000000
--- a/tools/ts_library_builder/build_library.ts
+++ /dev/null
@@ -1,569 +0,0 @@
-import { writeFileSync } from "fs";
-import { join } from "path";
-import * as prettier from "prettier";
-import {
- InterfaceDeclaration,
- ExpressionStatement,
- NamespaceDeclarationKind,
- Project,
- SourceFile,
- ts,
- Type,
- TypeGuards
-} from "ts-morph";
-import {
- addInterfaceDeclaration,
- addInterfaceProperty,
- addSourceComment,
- addTypeAlias,
- addVariableDeclaration,
- checkDiagnostics,
- flattenNamespace,
- getSourceComment,
- inlineFiles,
- loadDtsFiles,
- loadFiles,
- log,
- logDiagnostics,
- namespaceSourceFile,
- normalizeSlashes,
- setSilent
-} from "./ast_util";
-
-export interface BuildLibraryOptions {
- /**
- * The path to the root of the deno repository
- */
- basePath: string;
-
- /**
- * The path to the current build path
- */
- buildPath: string;
-
- /**
- * Denotes if the library should be built with debug information (comments
- * that indicate the source of the types)
- */
- debug?: boolean;
-
- /**
- * An array of files that should be inlined into the library
- */
- inline?: string[];
-
- /** An array of input files to be provided to the input project, relative to
- * the basePath. */
- inputs?: string[];
-
- /**
- * Path to globals file to be used I.E. `js/globals.ts`
- */
- additionalGlobals?: string[];
-
- /**
- * List of global variables to define as let instead of the default const.
- */
- declareAsLet?: string[];
-
- /**
- * The path to the output library
- */
- outFile: string;
-
- /**
- * Execute in silent mode or not
- */
- silent?: boolean;
-}
-
-const { ModuleKind, ModuleResolutionKind, ScriptTarget } = ts;
-
-/**
- * A preamble which is appended to the start of the library.
- */
-const libPreamble = `// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-/// <reference no-default-lib="true" />
-/// <reference lib="esnext" />
-
-`;
-
-interface FlattenOptions {
- basePath: string;
- customSources: { [filePath: string]: string };
- filePath: string;
- debug?: boolean;
- declarationProject: Project;
- globalInterfaceName?: string;
- moduleName?: string;
- namespaceName?: string;
- targetSourceFile: SourceFile;
-}
-
-/** Flatten a module */
-export function flatten({
- basePath,
- customSources,
- filePath,
- debug,
- declarationProject,
- globalInterfaceName,
- moduleName,
- namespaceName,
- targetSourceFile
-}: FlattenOptions): void {
- // Flatten the source file into a single set of statements
- const statements = flattenNamespace({
- sourceFile: declarationProject.getSourceFileOrThrow(filePath),
- rootPath: basePath,
- customSources,
- debug
- });
-
- // If a module name is specified create the module in the target file
- if (moduleName) {
- const namespace = targetSourceFile.addNamespace({
- name: moduleName,
- hasDeclareKeyword: true,
- declarationKind: NamespaceDeclarationKind.Module
- });
-
- // Add the output of the flattening to the namespace
- namespace.addStatements(statements);
- }
-
- if (namespaceName) {
- const namespace = targetSourceFile.insertNamespace(0, {
- name: namespaceName,
- hasDeclareKeyword: true,
- declarationKind: NamespaceDeclarationKind.Namespace
- });
-
- // Add the output of the flattening to the namespace
- namespace.addStatements(statements);
-
- if (globalInterfaceName) {
- // Retrieve the global interface
- const interfaceDeclaration = targetSourceFile.getInterfaceOrThrow(
- globalInterfaceName
- );
-
- // Add the namespace to the global interface
- addInterfaceProperty(
- interfaceDeclaration,
- namespaceName,
- `typeof ${namespaceName}`
- );
- }
- }
-}
-
-interface PrepareFileForMergeOptions {
- globalVarName: string;
- interfaceName: string;
- targetSourceFile: SourceFile;
-}
-
-interface PrepareFileForMergeReturn {
- interfaceDeclaration: InterfaceDeclaration;
-}
-
-export function prepareFileForMerge({
- globalVarName,
- interfaceName,
- targetSourceFile
-}: PrepareFileForMergeOptions): PrepareFileForMergeReturn {
- // Add the global object interface
- const interfaceDeclaration = targetSourceFile.addInterface({
- name: interfaceName,
- hasDeclareKeyword: true
- });
-
- // Declare the global variable
- addVariableDeclaration(
- targetSourceFile,
- globalVarName,
- interfaceName,
- true,
- true
- );
-
- // Add self reference to the global variable
- addInterfaceProperty(interfaceDeclaration, globalVarName, interfaceName);
-
- return {
- interfaceDeclaration
- };
-}
-
-interface MergeGlobalOptions extends PrepareFileForMergeOptions {
- basePath: string;
- debug?: boolean;
- declarationProject: Project;
- filePath: string;
- ignore?: string[];
- inputProject: Project;
- prepareReturn: PrepareFileForMergeReturn;
- declareAsLet?: string[];
-}
-
-/** Take a module and merge it into the global scope */
-export function mergeGlobals({
- basePath,
- debug,
- declarationProject,
- filePath,
- globalVarName,
- ignore,
- inputProject,
- targetSourceFile,
- declareAsLet,
- prepareReturn: { interfaceDeclaration }
-}: MergeGlobalOptions): void {
- // Retrieve source file from the input project
- const sourceFile = inputProject.getSourceFileOrThrow(filePath);
-
- // we are going to create a map of variables
- const globalVariables = new Map<
- string,
- {
- type: Type;
- node: ExpressionStatement;
- }
- >();
- const globalInterfaces: InterfaceDeclaration[] = [];
-
- // For every augmentation of the global variable in source file, we want
- // to extract the type and add it to the global variable map
- sourceFile.forEachChild(node => {
- if (TypeGuards.isExpressionStatement(node)) {
- const firstChild = node.getFirstChild();
- if (!firstChild) {
- return;
- }
- if (TypeGuards.isBinaryExpression(firstChild)) {
- const leftExpression = firstChild.getLeft();
- if (
- TypeGuards.isPropertyAccessExpression(leftExpression) &&
- leftExpression.getExpression().getText() === globalVarName
- ) {
- const globalVarProperty = leftExpression.getName();
- if (globalVarProperty !== globalVarName) {
- globalVariables.set(globalVarProperty, {
- type: firstChild.getType(),
- node
- });
- }
- }
- }
- } else if (TypeGuards.isInterfaceDeclaration(node) && node.isExported()) {
- globalInterfaces.push(node);
- }
- });
-
- // A set of source files that the types we are using are dependent on us
- // importing
- const dependentSourceFiles = new Set<SourceFile>();
-
- // Create a global variable and add the property to the `Window` interface
- // for each mutation of the `window` variable we observed in `globals.ts`
- for (const [property, info] of globalVariables) {
- if (!(ignore && ignore.includes(property))) {
- const type = info.type.getText(info.node);
- const typeSymbol = info.type.getSymbol();
- if (typeSymbol) {
- const valueDeclaration = typeSymbol.getValueDeclaration();
- if (valueDeclaration) {
- dependentSourceFiles.add(valueDeclaration.getSourceFile());
- }
- }
- const isConst = !(declareAsLet && declareAsLet.includes(property));
- addVariableDeclaration(targetSourceFile, property, type, isConst, true);
- addInterfaceProperty(interfaceDeclaration, property, type);
- }
- }
-
- // We need to copy over any type aliases
- for (const typeAlias of sourceFile.getTypeAliases()) {
- addTypeAlias(
- targetSourceFile,
- typeAlias.getName(),
- typeAlias.getType().getText(sourceFile),
- true
- );
- }
-
- // We need to copy over any interfaces
- for (const interfaceDeclaration of globalInterfaces) {
- addInterfaceDeclaration(targetSourceFile, interfaceDeclaration);
- }
-
- // We need to ensure that we only namespace each source file once, so we
- // will use this map for tracking that.
- const sourceFileMap = new Map<SourceFile, string>();
-
- // For each import declaration in source file we will want to convert the
- // declaration source file into a namespace that exists within the merged
- // namespace
- const importDeclarations = sourceFile.getImportDeclarations();
- const namespaces = new Set<string>();
- for (const declaration of importDeclarations) {
- const namespaceImport = declaration.getNamespaceImport();
- if (namespaceImport) {
- const declarationSourceFile = declaration.getModuleSpecifierSourceFile();
- if (
- declarationSourceFile &&
- dependentSourceFiles.has(declarationSourceFile)
- ) {
- // the source file will resolve to the original `.ts` file, but the
- // information we really want is in the emitted `.d.ts` file, so we will
- // resolve to that file
- const dtsFilePath = declarationSourceFile
- .getFilePath()
- .replace(/\.ts$/, ".d.ts");
- const dtsSourceFile = declarationProject.getSourceFileOrThrow(
- dtsFilePath
- );
- targetSourceFile.addStatements(
- namespaceSourceFile(dtsSourceFile, {
- debug,
- namespace: namespaceImport.getText(),
- namespaces,
- rootPath: basePath,
- sourceFileMap
- })
- );
- }
- }
- }
-
- if (debug) {
- addSourceComment(targetSourceFile, sourceFile, basePath);
- }
-}
-
-/**
- * Generate the runtime library for Deno and write it to the supplied out file
- * name.
- */
-export function main({
- basePath,
- buildPath,
- inline,
- inputs,
- additionalGlobals,
- declareAsLet,
- debug,
- outFile,
- silent
-}: BuildLibraryOptions): void {
- setSilent(silent);
- log("-----");
- log("build_lib");
- log();
- log(`basePath: "${basePath}"`);
- log(`buildPath: "${buildPath}"`);
- if (inline && inline.length) {
- log("inline:");
- for (const filename of inline) {
- log(` "${filename}"`);
- }
- }
- if (inputs && inputs.length) {
- log("inputs:");
- for (const input of inputs) {
- log(` "${input}"`);
- }
- }
- log(`debug: ${!!debug}`);
- log(`outFile: "${outFile}"`);
- log();
-
- // the inputProject will take in the TypeScript files that are internal
- // to Deno to be used to generate the library
- const inputProject = new Project({
- compilerOptions: {
- baseUrl: basePath,
- declaration: true,
- emitDeclarationOnly: true,
- lib: ["esnext"],
- module: ModuleKind.ESNext,
- moduleResolution: ModuleResolutionKind.NodeJs,
- paths: {
- "*": ["*", `${buildPath}/*`]
- },
- preserveConstEnums: true,
- strict: true,
- stripInternal: true,
- target: ScriptTarget.ESNext
- }
- });
-
- // Add the input files we will need to generate the declarations, `globals`
- // plus any modules that are importable in the runtime need to be added here
- // plus the `lib.esnext` which is used as the base library
- if (inputs) {
- inputProject.addExistingSourceFiles(
- inputs.map(input => join(basePath, input))
- );
- }
-
- // emit the project, which will be only the declaration files
- const inputEmitResult = inputProject.emitToMemory();
-
- log("Emitted input project.");
-
- const inputDiagnostics = inputEmitResult
- .getDiagnostics()
- .map(d => d.compilerObject);
- logDiagnostics(inputDiagnostics);
- if (inputDiagnostics.length) {
- console.error("\nDiagnostics present during input project emit.\n");
- process.exit(1);
- }
-
- // the declaration project will be the target for the emitted files from
- // the input project, these will be used to transfer information over to
- // the final library file
- const declarationProject = new Project({
- compilerOptions: {
- baseUrl: basePath,
- lib: ["esnext"],
- moduleResolution: ModuleResolutionKind.NodeJs,
- paths: {
- "*": ["*", `${buildPath}/*`]
- },
- strict: true,
- target: ScriptTarget.ESNext
- },
- useVirtualFileSystem: true
- });
-
- // we don't want to add to the declaration project any of the original
- // `.ts` source files, so we need to filter those out
- const jsPath = normalizeSlashes(`${basePath}/js`);
- const inputProjectFiles = inputProject
- .getSourceFiles()
- .map(sourceFile => sourceFile.getFilePath())
- .filter(filePath => !filePath.startsWith(jsPath));
- loadFiles(declarationProject, inputProjectFiles);
-
- // now we add the emitted declaration files from the input project
- for (const { filePath, text } of inputEmitResult.getFiles()) {
- declarationProject.createSourceFile(filePath, text);
- }
-
- // the outputProject will contain the final library file we are looking to
- // build
- const outputProjectCompilerOptions: ts.CompilerOptions = {
- baseUrl: buildPath,
- lib: ["esnext"],
- moduleResolution: ModuleResolutionKind.NodeJs,
- strict: true,
- target: ScriptTarget.ESNext
- };
-
- const outputProject = new Project({
- compilerOptions: outputProjectCompilerOptions,
- useVirtualFileSystem: true
- });
-
- // There are files we need to load into memory, so that the project "compiles"
- loadDtsFiles(outputProject, outputProjectCompilerOptions);
-
- // libDts is the final output file we are looking to build and we are not
- // actually creating it, only in memory at this stage.
- const libDTs = outputProject.createSourceFile(outFile);
-
- // Deal with `js/deno.ts`
-
- // Generate a object hash of substitutions of modules to use when flattening
- const customSources = {};
-
- const prepareForMergeOpts: PrepareFileForMergeOptions = {
- globalVarName: "window",
- interfaceName: "Window",
- targetSourceFile: libDTs
- };
-
- const prepareReturn = prepareFileForMerge(prepareForMergeOpts);
-
- mergeGlobals({
- basePath,
- debug,
- declarationProject,
- filePath: `${basePath}/js/globals.ts`,
- inputProject,
- ignore: ["Deno"],
- declareAsLet,
- ...prepareForMergeOpts,
- prepareReturn
- });
-
- log(`Merged "globals" into global scope.`);
-
- if (additionalGlobals) {
- for (const additionalGlobal of additionalGlobals) {
- mergeGlobals({
- basePath,
- debug,
- declarationProject,
- filePath: `${basePath}/${additionalGlobal}`,
- inputProject,
- ignore: ["Deno"],
- declareAsLet,
- ...prepareForMergeOpts,
- prepareReturn
- });
- }
-
- log(`Added additional "globals" into global scope.`);
- }
-
- flatten({
- basePath,
- customSources,
- debug,
- declarationProject,
- filePath: `${basePath}/js/deno.d.ts`,
- globalInterfaceName: "Window",
- namespaceName: "Deno",
- targetSourceFile: libDTs
- });
-
- log(`Created module "deno" and namespace Deno.`);
-
- // Inline any files that were passed in, to be used to add additional libs
- // which are not part of TypeScript.
- if (inline && inline.length) {
- inlineFiles({
- basePath,
- debug,
- inline,
- targetSourceFile: libDTs
- });
- }
-
- // Add the preamble
- libDTs.insertStatements(0, libPreamble);
-
- // Check diagnostics
- checkDiagnostics(outputProject);
-
- // Output the final library file
- libDTs.saveSync();
- const libDTsText = prettier.format(
- outputProject.getFileSystem().readFileSync(outFile, "utf8"),
- { parser: "typescript" }
- );
- if (!silent) {
- console.log(`Outputting library to: "${outFile}"`);
- console.log(` Length: ${libDTsText.length}`);
- }
- writeFileSync(outFile, libDTsText, { encoding: "utf8" });
- if (!silent) {
- console.log("-----");
- console.log();
- }
-}
diff --git a/tools/ts_library_builder/main.ts b/tools/ts_library_builder/main.ts
deleted file mode 100644
index e4e2e73ed..000000000
--- a/tools/ts_library_builder/main.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as path from "path";
-import { main as buildRuntimeLib } from "./build_library";
-
-// this is very simplistic argument parsing, just enough to integrate into
-// the build scripts, versus being very robust
-let basePath = process.cwd();
-let buildPath = path.join(basePath, "target", "debug");
-let outFile = path.join(buildPath, "gen", "lib", "lib.d.ts");
-let inline: string[] = [];
-let debug = false;
-let silent = false;
-
-process.argv.forEach((arg, i, argv) => {
- switch (arg) {
- case "--basePath":
- basePath = path.resolve(argv[i + 1]);
- break;
- case "--buildPath":
- buildPath = path.resolve(argv[i + 1]);
- break;
- case "--inline":
- inline = argv[i + 1].split(",").map(filename => {
- return path.resolve(filename);
- });
- break;
- case "--outFile":
- outFile = path.resolve(argv[i + 1]);
- break;
- case "--debug":
- debug = true;
- break;
- case "--silent":
- silent = true;
- break;
- }
-});
-
-buildRuntimeLib({
- basePath,
- buildPath,
- debug,
- inline,
- inputs: [
- "node_modules/typescript/lib/lib.esnext.d.ts",
- "js/deno.ts",
- "js/globals.ts"
- ],
- declareAsLet: ["onmessage"],
- outFile,
- silent
-});
diff --git a/tools/ts_library_builder/test.ts b/tools/ts_library_builder/test.ts
deleted file mode 100644
index d5f9de646..000000000
--- a/tools/ts_library_builder/test.ts
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-// Run this manually with:
-//
-// ./node_modules/.bin/ts-node --project tools/ts_library_builder/tsconfig.json tools/ts_library_builder/test.ts
-
-import * as assert from "assert";
-import { Project, ts } from "ts-morph";
-import { flatten, mergeGlobals, prepareFileForMerge } from "./build_library";
-import { inlineFiles, loadDtsFiles } from "./ast_util";
-
-const { ModuleKind, ModuleResolutionKind, ScriptTarget } = ts;
-
-/** setups and returns the fixtures for testing */
-// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
-function setupFixtures() {
- const basePath = process.cwd();
- const buildPath = `${basePath}/tools/ts_library_builder/testdata`;
- const outputFile = `${buildPath}/lib.output.d.ts`;
- const inputProject = new Project({
- compilerOptions: {
- baseUrl: basePath,
- declaration: true,
- emitDeclarationOnly: true,
- module: ModuleKind.ESNext,
- moduleResolution: ModuleResolutionKind.NodeJs,
- strict: true,
- stripInternal: true,
- target: ScriptTarget.ESNext
- }
- });
- inputProject.addExistingSourceFiles([
- `${buildPath}/globals.ts`,
- `${buildPath}/api.ts`
- ]);
- const declarationProject = new Project({
- compilerOptions: {},
- useVirtualFileSystem: true
- });
- loadDtsFiles(declarationProject, {});
- for (const { filePath, text } of inputProject.emitToMemory().getFiles()) {
- declarationProject.createSourceFile(filePath, text);
- }
- const outputProject = new Project({
- compilerOptions: {},
- useVirtualFileSystem: true
- });
- loadDtsFiles(outputProject, {});
- const outputSourceFile = outputProject.createSourceFile(outputFile);
- const debug = true;
-
- return {
- basePath,
- buildPath,
- inputProject,
- outputFile,
- declarationProject,
- outputProject,
- outputSourceFile,
- debug
- };
-}
-
-function buildLibraryFlatten(): void {
- const {
- basePath,
- buildPath,
- debug,
- declarationProject,
- outputSourceFile: targetSourceFile
- } = setupFixtures();
-
- flatten({
- basePath,
- customSources: {},
- debug,
- declarationProject,
- filePath: `${buildPath}/api.d.ts`,
- moduleName: `"api"`,
- namespaceName: "Api",
- targetSourceFile
- });
-
- assert(targetSourceFile.getNamespace(`"api"`) != null);
- assert(targetSourceFile.getNamespace("Api") != null);
- assert.equal(targetSourceFile.getNamespaces().length, 2);
- const moduleApi = targetSourceFile.getNamespaceOrThrow(`"api"`);
- const functions = moduleApi.getFunctions();
- assert.equal(functions[0].getName(), "foo");
- assert.equal(
- functions[0]
- .getJsDocs()
- .map(jsdoc => jsdoc.getInnerText())
- .join("\n"),
- "jsdoc for foo"
- );
- assert.equal(functions[1].getName(), "bar");
- assert.equal(
- functions[1]
- .getJsDocs()
- .map(jsdoc => jsdoc.getInnerText())
- .join("\n"),
- ""
- );
- assert.equal(functions.length, 2);
- const classes = moduleApi.getClasses();
- assert.equal(classes[0].getName(), "Foo");
- assert.equal(classes.length, 1);
- const variableDeclarations = moduleApi.getVariableDeclarations();
- assert.equal(variableDeclarations[0].getName(), "arr");
- assert.equal(variableDeclarations.length, 1);
-
- const namespaceApi = targetSourceFile.getNamespaceOrThrow(`"api"`);
- const functionsNs = namespaceApi.getFunctions();
- assert.equal(functionsNs[0].getName(), "foo");
- assert.equal(
- functionsNs[0]
- .getJsDocs()
- .map(jsdoc => jsdoc.getInnerText())
- .join("\n"),
- "jsdoc for foo"
- );
- assert.equal(functionsNs[1].getName(), "bar");
- assert.equal(
- functionsNs[1]
- .getJsDocs()
- .map(jsdoc => jsdoc.getInnerText())
- .join("\n"),
- ""
- );
- assert.equal(functionsNs.length, 2);
- const classesNs = namespaceApi.getClasses();
- assert.equal(classesNs[0].getName(), "Foo");
- assert.equal(classesNs.length, 1);
- const variableDeclarationsNs = namespaceApi.getVariableDeclarations();
- assert.equal(variableDeclarationsNs[0].getName(), "arr");
- assert.equal(variableDeclarationsNs.length, 1);
-}
-
-function buildLibraryMerge(): void {
- const {
- basePath,
- buildPath,
- declarationProject,
- debug,
- inputProject,
- outputSourceFile: targetSourceFile
- } = setupFixtures();
-
- const prepareForMergeOpts = {
- globalVarName: "foobarbaz",
- interfaceName: "FooBar",
- targetSourceFile
- };
-
- const prepareReturn = prepareFileForMerge(prepareForMergeOpts);
-
- mergeGlobals({
- basePath,
- declarationProject,
- debug,
- filePath: `${buildPath}/globals.ts`,
- inputProject,
- ...prepareForMergeOpts,
- prepareReturn
- });
-
- assert(targetSourceFile.getNamespace("moduleC") != null);
- assert(targetSourceFile.getNamespace("moduleD") != null);
- assert(targetSourceFile.getNamespace("moduleE") != null);
- assert(targetSourceFile.getNamespace("moduleF") != null);
- assert.equal(targetSourceFile.getNamespaces().length, 4);
- assert(targetSourceFile.getInterface("FooBar") != null);
- assert.equal(targetSourceFile.getInterfaces().length, 2);
- const variableDeclarations = targetSourceFile.getVariableDeclarations();
- assert.equal(variableDeclarations[0].getType().getText(), `FooBar`);
- assert.equal(variableDeclarations[1].getType().getText(), `moduleC.Bar`);
- assert.equal(
- variableDeclarations[2].getType().getText(),
- `typeof moduleC.qat`
- );
- assert.equal(
- variableDeclarations[3].getType().getText(),
- `typeof moduleE.process`
- );
- assert.equal(
- variableDeclarations[4].getType().getText(),
- `typeof moduleD.reprocess`
- );
- assert.equal(
- variableDeclarations[5].getType().getText(),
- `typeof moduleC.Bar`
- );
- assert.equal(variableDeclarations.length, 6);
- const typeAliases = targetSourceFile.getTypeAliases();
- assert.equal(typeAliases[0].getName(), "Bar");
- assert.equal(typeAliases[0].getType().getText(), "moduleC.Bar");
- assert.equal(typeAliases.length, 1);
- const exportedInterface = targetSourceFile.getInterfaceOrThrow("FizzBuzz");
- const interfaceProperties = exportedInterface.getStructure().properties;
- assert(interfaceProperties != null);
- assert.equal(interfaceProperties!.length, 2);
- assert.equal(interfaceProperties![0].name, "foo");
- assert.equal(interfaceProperties![0].type, "string");
- assert.equal(interfaceProperties![1].name, "bar");
- assert.equal(interfaceProperties![1].type, "number");
-}
-
-function testInlineFiles(): void {
- const {
- basePath,
- buildPath,
- debug,
- outputSourceFile: targetSourceFile
- } = setupFixtures();
-
- inlineFiles({
- basePath,
- debug,
- inline: [`${buildPath}/lib.extra.d.ts`],
- targetSourceFile
- });
-
- assert(targetSourceFile.getNamespace("Qat") != null);
- const qatNamespace = targetSourceFile.getNamespaceOrThrow("Qat");
- assert(qatNamespace.getClass("Foo") != null);
-}
-
-// TODO author unit tests for `ast_util.ts`
-
-function main(): void {
- console.log("ts_library_builder buildLibraryFlatten");
- buildLibraryFlatten();
- console.log("ts_library_builder buildLibraryMerge");
- buildLibraryMerge();
- console.log("ts_library_builder testInlineFiles");
- testInlineFiles();
- console.log("ts_library_builder ok");
-}
-
-main();
diff --git a/tools/ts_library_builder/testdata/api.ts b/tools/ts_library_builder/testdata/api.ts
deleted file mode 100644
index f282a8414..000000000
--- a/tools/ts_library_builder/testdata/api.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export { foo, bar } from "./moduleA";
-export { Foo } from "./moduleB";
-/** jsdoc for arr */
-export const arr: string[] = [];
diff --git a/tools/ts_library_builder/testdata/globals.ts b/tools/ts_library_builder/testdata/globals.ts
deleted file mode 100644
index 4fff7e8f9..000000000
--- a/tools/ts_library_builder/testdata/globals.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import * as moduleC from "./moduleC";
-import * as moduleD from "./moduleD";
-import * as moduleE from "./moduleE";
-
-const foobarbaz: any = {};
-foobarbaz.bar = new moduleC.Bar();
-foobarbaz.qat = moduleC.qat;
-foobarbaz.process = moduleE.process;
-foobarbaz.reprocess = moduleD.reprocess;
-foobarbaz.Bar = moduleC.Bar;
-export type Bar = moduleC.Bar;
-export interface FizzBuzz {
- foo: string;
- bar: number;
-}
diff --git a/tools/ts_library_builder/testdata/lib.extra.d.ts b/tools/ts_library_builder/testdata/lib.extra.d.ts
deleted file mode 100644
index 8dc197334..000000000
--- a/tools/ts_library_builder/testdata/lib.extra.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// comment
-
-declare namespace Qat {
- class Foo {
- bar: string;
- }
-}
diff --git a/tools/ts_library_builder/testdata/moduleA.ts b/tools/ts_library_builder/testdata/moduleA.ts
deleted file mode 100644
index a5bd07e2f..000000000
--- a/tools/ts_library_builder/testdata/moduleA.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/** jsdoc for foo */
-export function foo(a: string, b: string) {
- console.log(a, b);
-}
-
-// no jsdoc for bar
-export async function bar(promise: Promise<void>): Promise<void> {
- return promise.then(() => {});
-}
diff --git a/tools/ts_library_builder/testdata/moduleB.ts b/tools/ts_library_builder/testdata/moduleB.ts
deleted file mode 100644
index 91f5ea875..000000000
--- a/tools/ts_library_builder/testdata/moduleB.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/** jsdoc about Foo */
-export class Foo {
- private _foo = "foo";
- /** jsdoc about Foo.log() */
- log() {
- console.log(this._foo);
- return this._foo;
- }
-}
diff --git a/tools/ts_library_builder/testdata/moduleC.ts b/tools/ts_library_builder/testdata/moduleC.ts
deleted file mode 100644
index b998c9e9d..000000000
--- a/tools/ts_library_builder/testdata/moduleC.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-/** jsdoc for Bar */
-export class Bar {
- private _bar: string;
- /** jsdoc for Bar.log() */
- log() {
- console.log(this._bar);
- return this.log;
- }
-}
-
-/**
- * jsdoc for qat
- * @param a jsdoc for qat(a)
- * @param b jsdoc for qat(b)
- */
-export function qat(a: string, b: string) {
- return a + b;
-}
diff --git a/tools/ts_library_builder/testdata/moduleD.ts b/tools/ts_library_builder/testdata/moduleD.ts
deleted file mode 100644
index 8752699d1..000000000
--- a/tools/ts_library_builder/testdata/moduleD.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import * as moduleF from "./moduleF";
-
-export function reprocess(value: typeof moduleF.key) {
- console.log(value);
-}
diff --git a/tools/ts_library_builder/testdata/moduleE.ts b/tools/ts_library_builder/testdata/moduleE.ts
deleted file mode 100644
index 361a9ad0f..000000000
--- a/tools/ts_library_builder/testdata/moduleE.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import * as moduleF from "./moduleF";
-
-export function process(value: typeof moduleF.key) {
- console.log(value);
-}
diff --git a/tools/ts_library_builder/testdata/moduleF.ts b/tools/ts_library_builder/testdata/moduleF.ts
deleted file mode 100644
index b2f8883ad..000000000
--- a/tools/ts_library_builder/testdata/moduleF.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const key = "value";
diff --git a/tools/ts_library_builder/tsconfig.json b/tools/ts_library_builder/tsconfig.json
deleted file mode 100644
index 54db4887e..000000000
--- a/tools/ts_library_builder/tsconfig.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "compilerOptions": {
- "lib": ["esnext"],
- "moduleResolution": "node",
- "strict": true,
- "target": "esnext"
- },
- "files": ["./build_library.ts"]
-}
diff --git a/tsconfig.json b/tsconfig.json
index e9f8048df..4fb16fac1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -21,6 +21,7 @@
},
"files": [
"js/lib.web_assembly.d.ts",
+ "js/lib.deno_runtime.d.ts",
"core/core.d.ts",
"core/libdeno/libdeno.d.ts",
"js/main.ts",