summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2019-10-04 20:28:51 -0400
committerGitHub <noreply@github.com>2019-10-04 20:28:51 -0400
commitb81e5db17aa8b3088d6034ddf86b79c69410f012 (patch)
tree579e4c23d60d1b0d038156bc28a04f74ea87b2f0 /js
parent9049213867d30f7df090a83b6baf3e0717a4d2d2 (diff)
Merge deno_cli_snapshots into deno_cli (#3064)
Diffstat (limited to 'js')
-rw-r--r--js/Cargo.toml25
-rw-r--r--js/README.md10
-rw-r--r--js/base64.ts150
-rw-r--r--js/blob.ts178
-rw-r--r--js/blob_test.ts62
-rw-r--r--js/body.ts272
-rw-r--r--js/body_test.ts68
-rw-r--r--js/buffer.ts294
-rw-r--r--js/buffer_test.ts277
-rw-r--r--js/build.rs28
-rw-r--r--js/build.ts27
-rw-r--r--js/build_test.ts10
-rw-r--r--js/chmod.ts20
-rw-r--r--js/chmod_test.ts142
-rw-r--r--js/chown.ts27
-rw-r--r--js/chown_test.ts145
-rw-r--r--js/colors.ts40
-rw-r--r--js/compiler.ts667
-rw-r--r--js/console.ts790
-rw-r--r--js/console_table.ts94
-rw-r--r--js/console_test.ts698
-rw-r--r--js/copy_file.ts30
-rw-r--r--js/copy_file_test.ts163
-rw-r--r--js/core.ts6
-rw-r--r--js/custom_event.ts48
-rw-r--r--js/custom_event_test.ts27
-rw-r--r--js/deno.ts119
-rw-r--r--js/diagnostics.ts217
-rw-r--r--js/dir.ts22
-rw-r--r--js/dir_test.ts54
-rw-r--r--js/dispatch.ts110
-rw-r--r--js/dispatch_json.ts86
-rw-r--r--js/dispatch_json_test.ts19
-rw-r--r--js/dispatch_minimal.ts80
-rw-r--r--js/dom_file.ts24
-rw-r--r--js/dom_types.ts625
-rw-r--r--js/dom_util.ts85
-rw-r--r--js/error_stack.ts273
-rw-r--r--js/error_stack_test.ts108
-rw-r--r--js/errors.ts79
-rw-r--r--js/event.ts348
-rw-r--r--js/event_target.ts503
-rw-r--r--js/event_target_test.ts142
-rw-r--r--js/event_test.ts95
-rw-r--r--js/fetch.ts478
-rw-r--r--js/fetch_test.ts357
-rw-r--r--js/file_info.ts91
-rw-r--r--js/file_test.ts103
-rw-r--r--js/files.ts235
-rw-r--r--js/files_test.ts329
-rw-r--r--js/form_data.ts149
-rw-r--r--js/form_data_test.ts179
-rw-r--r--js/format_error.ts9
-rw-r--r--js/get_random_values.ts31
-rw-r--r--js/get_random_values_test.ts51
-rw-r--r--js/globals.ts207
-rw-r--r--js/globals_test.ts104
-rw-r--r--js/headers.ts139
-rw-r--r--js/headers_test.ts331
-rw-r--r--js/io.ts170
-rw-r--r--js/lib.deno_runtime.d.ts2800
-rw-r--r--js/lib.rs55
-rw-r--r--js/lib.web_assembly.d.ts173
-rw-r--r--js/link.ts19
-rw-r--r--js/link_test.ts115
-rw-r--r--js/location.ts52
-rw-r--r--js/location_test.ts8
-rw-r--r--js/main.ts41
-rw-r--r--js/make_temp_dir.ts35
-rw-r--r--js/make_temp_dir_test.ts66
-rw-r--r--js/metrics.ts28
-rw-r--r--js/metrics_test.ts46
-rw-r--r--js/mixins/dom_iterable.ts82
-rw-r--r--js/mixins/dom_iterable_test.ts79
-rw-r--r--js/mkdir.ts33
-rw-r--r--js/mkdir_test.ts66
-rw-r--r--js/mock_builtin.js2
-rw-r--r--js/net.ts205
-rw-r--r--js/net_test.ts229
-rw-r--r--js/os.ts151
-rw-r--r--js/os_test.ts165
-rw-r--r--js/performance.ts22
-rw-r--r--js/performance_test.ts10
-rw-r--r--js/permissions.ts39
-rw-r--r--js/permissions_test.ts28
-rw-r--r--js/process.ts307
-rw-r--r--js/process_test.ts377
-rw-r--r--js/read_dir.ts34
-rw-r--r--js/read_dir_test.ts84
-rw-r--r--js/read_file.ts29
-rw-r--r--js/read_file_test.ts57
-rw-r--r--js/read_link.ts19
-rw-r--r--js/read_link_test.ts69
-rw-r--r--js/remove.ts32
-rw-r--r--js/remove_test.ts335
-rw-r--r--js/rename.ts24
-rw-r--r--js/rename_test.ts74
-rw-r--r--js/repl.ts197
-rw-r--r--js/request.ts151
-rw-r--r--js/request_test.ts17
-rw-r--r--js/resources.ts19
-rw-r--r--js/resources_test.ts48
-rw-r--r--js/stat.ts73
-rw-r--r--js/stat_test.ts172
-rw-r--r--js/symlink.ts39
-rw-r--r--js/symlink_test.ts80
-rw-r--r--js/test_util.ts262
-rw-r--r--js/text_encoding.ts554
-rw-r--r--js/text_encoding_test.ts193
-rw-r--r--js/timers.ts280
-rw-r--r--js/timers_test.ts291
-rw-r--r--js/tls.ts21
-rw-r--r--js/tls_test.ts25
-rw-r--r--js/truncate.ts34
-rw-r--r--js/truncate_test.ts74
-rw-r--r--js/ts_global.d.ts19
-rw-r--r--js/type_directives.ts91
-rw-r--r--js/types.ts2
-rwxr-xr-xjs/unit_test_runner.ts107
-rw-r--r--js/unit_tests.ts65
-rw-r--r--js/url.ts376
-rw-r--r--js/url_search_params.ts297
-rw-r--r--js/url_search_params_test.ts238
-rw-r--r--js/url_test.ts181
-rw-r--r--js/util.ts225
-rw-r--r--js/utime.ts45
-rw-r--r--js/utime_test.ts181
-rw-r--r--js/version.ts28
-rw-r--r--js/version_test.ts8
-rw-r--r--js/window.ts9
-rw-r--r--js/workers.ts193
-rw-r--r--js/write_file.ts76
-rw-r--r--js/write_file_test.ts219
133 files changed, 0 insertions, 21130 deletions
diff --git a/js/Cargo.toml b/js/Cargo.toml
deleted file mode 100644
index 40cc43d93..000000000
--- a/js/Cargo.toml
+++ /dev/null
@@ -1,25 +0,0 @@
-[package]
-name = "deno_cli_snapshots"
-version = "0.19.0"
-license = "MIT"
-authors = ["the Deno authors"]
-edition = "2018"
-description = "Provides snapshots for the deno CLI"
-repository = "https://github.com/denoland/deno"
-exclude = [
- "std/fs/testdata/0-link.ts",
- "std/fs/testdata/copy_dir_link_file/0.txt",
-]
-
-[lib]
-path = "lib.rs"
-
-[dependencies]
-deno_typescript = { path = "../deno_typescript", version = "0.19.0" }
-
-[dev-dependencies]
-deno = { path = "../core", version = "0.19.0" }
-
-[build-dependencies]
-deno_typescript = { path = "../deno_typescript", version = "0.19.0" }
-
diff --git a/js/README.md b/js/README.md
deleted file mode 100644
index 850adb6ee..000000000
--- a/js/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Crate: `deno_cli_snapshots`
-
-## AKA `cli_snapshots` AKA `//js`
-
-This is a small crate which exports just a few static blobs. It contains a
-build.rs file which compiles Deno's internal JavaScript and TypeScript code
-first into a single AMD bundle, and then into a binary V8 Snapshot.
-
-The main Deno executable crate ("cli") depends on this crate and has access to
-all the runtime code.
diff --git a/js/base64.ts b/js/base64.ts
deleted file mode 100644
index 4d30e00f1..000000000
--- a/js/base64.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-// Forked from https://github.com/beatgammit/base64-js
-// Copyright (c) 2014 Jameson Little. MIT License.
-
-const lookup: string[] = [];
-const revLookup: number[] = [];
-
-const code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-for (let i = 0, len = code.length; i < len; ++i) {
- lookup[i] = code[i];
- revLookup[code.charCodeAt(i)] = i;
-}
-
-// Support decoding URL-safe base64 strings, as Node.js does.
-// See: https://en.wikipedia.org/wiki/Base64#URL_applications
-revLookup["-".charCodeAt(0)] = 62;
-revLookup["_".charCodeAt(0)] = 63;
-
-function getLens(b64: string): [number, number] {
- const len = b64.length;
-
- if (len % 4 > 0) {
- throw new Error("Invalid string. Length must be a multiple of 4");
- }
-
- // Trim off extra bytes after placeholder bytes are found
- // See: https://github.com/beatgammit/base64-js/issues/42
- let validLen = b64.indexOf("=");
- if (validLen === -1) validLen = len;
-
- const placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4);
-
- return [validLen, placeHoldersLen];
-}
-
-// base64 is 4/3 + up to two characters of the original data
-export function byteLength(b64: string): number {
- const lens = getLens(b64);
- const validLen = lens[0];
- const placeHoldersLen = lens[1];
- return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;
-}
-
-function _byteLength(
- b64: string,
- validLen: number,
- placeHoldersLen: number
-): number {
- return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;
-}
-
-export function toByteArray(b64: string): Uint8Array {
- let tmp;
- const lens = getLens(b64);
- const validLen = lens[0];
- const placeHoldersLen = lens[1];
-
- const arr = new Uint8Array(_byteLength(b64, validLen, placeHoldersLen));
-
- let curByte = 0;
-
- // if there are placeholders, only get up to the last complete 4 chars
- const len = placeHoldersLen > 0 ? validLen - 4 : validLen;
-
- let i;
- for (i = 0; i < len; i += 4) {
- tmp =
- (revLookup[b64.charCodeAt(i)] << 18) |
- (revLookup[b64.charCodeAt(i + 1)] << 12) |
- (revLookup[b64.charCodeAt(i + 2)] << 6) |
- revLookup[b64.charCodeAt(i + 3)];
- arr[curByte++] = (tmp >> 16) & 0xff;
- arr[curByte++] = (tmp >> 8) & 0xff;
- arr[curByte++] = tmp & 0xff;
- }
-
- if (placeHoldersLen === 2) {
- tmp =
- (revLookup[b64.charCodeAt(i)] << 2) |
- (revLookup[b64.charCodeAt(i + 1)] >> 4);
- arr[curByte++] = tmp & 0xff;
- }
-
- if (placeHoldersLen === 1) {
- tmp =
- (revLookup[b64.charCodeAt(i)] << 10) |
- (revLookup[b64.charCodeAt(i + 1)] << 4) |
- (revLookup[b64.charCodeAt(i + 2)] >> 2);
- arr[curByte++] = (tmp >> 8) & 0xff;
- arr[curByte++] = tmp & 0xff;
- }
-
- return arr;
-}
-
-function tripletToBase64(num: number): string {
- return (
- lookup[(num >> 18) & 0x3f] +
- lookup[(num >> 12) & 0x3f] +
- lookup[(num >> 6) & 0x3f] +
- lookup[num & 0x3f]
- );
-}
-
-function encodeChunk(uint8: Uint8Array, start: number, end: number): string {
- let tmp;
- const output = [];
- for (let i = start; i < end; i += 3) {
- tmp =
- ((uint8[i] << 16) & 0xff0000) +
- ((uint8[i + 1] << 8) & 0xff00) +
- (uint8[i + 2] & 0xff);
- output.push(tripletToBase64(tmp));
- }
- return output.join("");
-}
-
-export function fromByteArray(uint8: Uint8Array): string {
- let tmp;
- const len = uint8.length;
- const extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
- const parts = [];
- const maxChunkLength = 16383; // must be multiple of 3
-
- // go through the array every three bytes, we'll deal with trailing stuff later
- for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
- parts.push(
- encodeChunk(
- uint8,
- i,
- i + maxChunkLength > len2 ? len2 : i + maxChunkLength
- )
- );
- }
-
- // pad the end with zeros, but make sure to not forget the extra bytes
- if (extraBytes === 1) {
- tmp = uint8[len - 1];
- parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + "==");
- } else if (extraBytes === 2) {
- tmp = (uint8[len - 2] << 8) + uint8[len - 1];
- parts.push(
- lookup[tmp >> 10] +
- lookup[(tmp >> 4) & 0x3f] +
- lookup[(tmp << 2) & 0x3f] +
- "="
- );
- }
-
- return parts.join("");
-}
diff --git a/js/blob.ts b/js/blob.ts
deleted file mode 100644
index 50ab7f374..000000000
--- a/js/blob.ts
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as domTypes from "./dom_types.ts";
-import { containsOnlyASCII, hasOwnProperty } from "./util.ts";
-import { TextEncoder } from "./text_encoding.ts";
-import { build } from "./build.ts";
-
-export const bytesSymbol = Symbol("bytes");
-
-function convertLineEndingsToNative(s: string): string {
- const nativeLineEnd = build.os == "win" ? "\r\n" : "\n";
-
- let position = 0;
-
- let collectionResult = collectSequenceNotCRLF(s, position);
-
- let token = collectionResult.collected;
- position = collectionResult.newPosition;
-
- let result = token;
-
- while (position < s.length) {
- const c = s.charAt(position);
- if (c == "\r") {
- result += nativeLineEnd;
- position++;
- if (position < s.length && s.charAt(position) == "\n") {
- position++;
- }
- } else if (c == "\n") {
- position++;
- result += nativeLineEnd;
- }
-
- collectionResult = collectSequenceNotCRLF(s, position);
-
- token = collectionResult.collected;
- position = collectionResult.newPosition;
-
- result += token;
- }
-
- return result;
-}
-
-function collectSequenceNotCRLF(
- s: string,
- position: number
-): { collected: string; newPosition: number } {
- const start = position;
- for (
- let c = s.charAt(position);
- position < s.length && !(c == "\r" || c == "\n");
- c = s.charAt(++position)
- );
- return { collected: s.slice(start, position), newPosition: position };
-}
-
-function toUint8Arrays(
- blobParts: domTypes.BlobPart[],
- doNormalizeLineEndingsToNative: boolean
-): Uint8Array[] {
- const ret: Uint8Array[] = [];
- const enc = new TextEncoder();
- for (const element of blobParts) {
- if (typeof element === "string") {
- let str = element;
- if (doNormalizeLineEndingsToNative) {
- str = convertLineEndingsToNative(element);
- }
- ret.push(enc.encode(str));
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
- } else if (element instanceof DenoBlob) {
- ret.push(element[bytesSymbol]);
- } else if (element instanceof Uint8Array) {
- ret.push(element);
- } else if (element instanceof Uint16Array) {
- const uint8 = new Uint8Array(element.buffer);
- ret.push(uint8);
- } else if (element instanceof Uint32Array) {
- const uint8 = new Uint8Array(element.buffer);
- ret.push(uint8);
- } else if (ArrayBuffer.isView(element)) {
- // Convert view to Uint8Array.
- const uint8 = new Uint8Array(element.buffer);
- ret.push(uint8);
- } else if (element instanceof ArrayBuffer) {
- // Create a new Uint8Array view for the given ArrayBuffer.
- const uint8 = new Uint8Array(element);
- ret.push(uint8);
- } else {
- ret.push(enc.encode(String(element)));
- }
- }
- return ret;
-}
-
-function processBlobParts(
- blobParts: domTypes.BlobPart[],
- options: domTypes.BlobPropertyBag
-): Uint8Array {
- const normalizeLineEndingsToNative = options.ending === "native";
- // ArrayBuffer.transfer is not yet implemented in V8, so we just have to
- // pre compute size of the array buffer and do some sort of static allocation
- // instead of dynamic allocation.
- const uint8Arrays = toUint8Arrays(blobParts, normalizeLineEndingsToNative);
- const byteLength = uint8Arrays
- .map((u8): number => u8.byteLength)
- .reduce((a, b): number => a + b, 0);
- const ab = new ArrayBuffer(byteLength);
- const bytes = new Uint8Array(ab);
-
- let courser = 0;
- for (const u8 of uint8Arrays) {
- bytes.set(u8, courser);
- courser += u8.byteLength;
- }
-
- return bytes;
-}
-
-// A WeakMap holding blob to byte array mapping.
-// Ensures it does not impact garbage collection.
-export const blobBytesWeakMap = new WeakMap<domTypes.Blob, Uint8Array>();
-
-export class DenoBlob implements domTypes.Blob {
- private readonly [bytesSymbol]: Uint8Array;
- readonly size: number = 0;
- readonly type: string = "";
-
- /** A blob object represents a file-like object of immutable, raw data. */
- constructor(
- blobParts?: domTypes.BlobPart[],
- options?: domTypes.BlobPropertyBag
- ) {
- if (arguments.length === 0) {
- this[bytesSymbol] = new Uint8Array();
- return;
- }
-
- options = options || {};
- // Set ending property's default value to "transparent".
- if (!hasOwnProperty(options, "ending")) {
- options.ending = "transparent";
- }
-
- if (options.type && !containsOnlyASCII(options.type)) {
- const errMsg = "The 'type' property must consist of ASCII characters.";
- throw new SyntaxError(errMsg);
- }
-
- const bytes = processBlobParts(blobParts!, options);
- // Normalize options.type.
- let type = options.type ? options.type : "";
- if (type.length) {
- for (let i = 0; i < type.length; ++i) {
- const char = type[i];
- if (char < "\u0020" || char > "\u007E") {
- type = "";
- break;
- }
- }
- type = type.toLowerCase();
- }
- // Set Blob object's properties.
- this[bytesSymbol] = bytes;
- this.size = bytes.byteLength;
- this.type = type;
-
- // Register bytes for internal private use.
- blobBytesWeakMap.set(this, bytes);
- }
-
- slice(start?: number, end?: number, contentType?: string): DenoBlob {
- return new DenoBlob([this[bytesSymbol].slice(start, end)], {
- type: contentType || this.type
- });
- }
-}
diff --git a/js/blob_test.ts b/js/blob_test.ts
deleted file mode 100644
index afa1182a9..000000000
--- a/js/blob_test.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert, assertEquals } from "./test_util.ts";
-
-test(function blobString(): void {
- const b1 = new Blob(["Hello World"]);
- const str = "Test";
- const b2 = new Blob([b1, str]);
- assertEquals(b2.size, b1.size + str.length);
-});
-
-test(function blobBuffer(): void {
- const buffer = new ArrayBuffer(12);
- const u8 = new Uint8Array(buffer);
- const f1 = new Float32Array(buffer);
- const b1 = new Blob([buffer, u8]);
- assertEquals(b1.size, 2 * u8.length);
- const b2 = new Blob([b1, f1]);
- assertEquals(b2.size, 3 * u8.length);
-});
-
-test(function blobSlice(): void {
- const blob = new Blob(["Deno", "Foo"]);
- const b1 = blob.slice(0, 3, "Text/HTML");
- assert(b1 instanceof Blob);
- assertEquals(b1.size, 3);
- assertEquals(b1.type, "text/html");
- const b2 = blob.slice(-1, 3);
- assertEquals(b2.size, 0);
- const b3 = blob.slice(100, 3);
- assertEquals(b3.size, 0);
- const b4 = blob.slice(0, 10);
- assertEquals(b4.size, blob.size);
-});
-
-test(function blobShouldNotThrowError(): void {
- let hasThrown = false;
-
- try {
- const options1: object = {
- ending: "utf8",
- hasOwnProperty: "hasOwnProperty"
- };
- const options2: object = Object.create(null);
- new Blob(["Hello World"], options1);
- new Blob(["Hello World"], options2);
- } catch {
- hasThrown = true;
- }
-
- assertEquals(hasThrown, false);
-});
-
-test(function nativeEndLine(): void {
- const options: object = {
- ending: "native"
- };
- const blob = new Blob(["Hello\nWorld"], options);
-
- assertEquals(blob.size, Deno.build.os === "win" ? 12 : 11);
-});
-
-// TODO(qti3e) Test the stored data in a Blob after implementing FileReader API.
diff --git a/js/body.ts b/js/body.ts
deleted file mode 100644
index 6567b1934..000000000
--- a/js/body.ts
+++ /dev/null
@@ -1,272 +0,0 @@
-import * as formData from "./form_data.ts";
-import * as blob from "./blob.ts";
-import * as encoding from "./text_encoding.ts";
-import * as headers from "./headers.ts";
-import * as domTypes from "./dom_types.ts";
-
-const { Headers } = headers;
-
-// only namespace imports work for now, plucking out what we need
-const { FormData } = formData;
-const { TextEncoder, TextDecoder } = encoding;
-const Blob = blob.DenoBlob;
-const DenoBlob = blob.DenoBlob;
-
-export type BodySource =
- | domTypes.Blob
- | domTypes.BufferSource
- | domTypes.FormData
- | domTypes.URLSearchParams
- | domTypes.ReadableStream
- | string;
-
-function validateBodyType(owner: Body, bodySource: BodySource): boolean {
- if (
- bodySource instanceof Int8Array ||
- bodySource instanceof Int16Array ||
- bodySource instanceof Int32Array ||
- bodySource instanceof Uint8Array ||
- bodySource instanceof Uint16Array ||
- bodySource instanceof Uint32Array ||
- bodySource instanceof Uint8ClampedArray ||
- bodySource instanceof Float32Array ||
- bodySource instanceof Float64Array
- ) {
- return true;
- } else if (bodySource instanceof ArrayBuffer) {
- return true;
- } else if (typeof bodySource === "string") {
- return true;
- } else if (bodySource instanceof FormData) {
- return true;
- } else if (!bodySource) {
- return true; // null body is fine
- }
- throw new Error(
- `Bad ${owner.constructor.name} body type: ${bodySource.constructor.name}`
- );
-}
-
-function getHeaderValueParams(value: string): Map<string, string> {
- const params = new Map();
- // Forced to do so for some Map constructor param mismatch
- value
- .split(";")
- .slice(1)
- .map((s): string[] => s.trim().split("="))
- .filter((arr): boolean => arr.length > 1)
- .map(([k, v]): [string, string] => [k, v.replace(/^"([^"]*)"$/, "$1")])
- .forEach(([k, v]): Map<string, string> => params.set(k, v));
- return params;
-}
-
-function hasHeaderValueOf(s: string, value: string): boolean {
- return new RegExp(`^${value}[\t\s]*;?`).test(s);
-}
-
-export const BodyUsedError =
- "Failed to execute 'clone' on 'Body': body is already used";
-
-export class Body implements domTypes.Body {
- protected _stream: domTypes.ReadableStream | null;
-
- constructor(protected _bodySource: BodySource, readonly contentType: string) {
- validateBodyType(this, _bodySource);
- this._bodySource = _bodySource;
- this.contentType = contentType;
- this._stream = null;
- }
-
- get body(): domTypes.ReadableStream | null {
- if (this._stream) {
- return this._stream;
- }
- if (typeof this._bodySource === "string") {
- throw Error("not implemented");
- }
- return this._stream;
- }
-
- get bodyUsed(): boolean {
- if (this.body && this.body.locked) {
- return true;
- }
- return false;
- }
-
- public async blob(): Promise<domTypes.Blob> {
- return new Blob([await this.arrayBuffer()]);
- }
-
- // ref: https://fetch.spec.whatwg.org/#body-mixin
- public async formData(): Promise<domTypes.FormData> {
- const formData = new FormData();
- const enc = new TextEncoder();
- if (hasHeaderValueOf(this.contentType, "multipart/form-data")) {
- const params = getHeaderValueParams(this.contentType);
- if (!params.has("boundary")) {
- // TypeError is required by spec
- throw new TypeError("multipart/form-data must provide a boundary");
- }
- // ref: https://tools.ietf.org/html/rfc2046#section-5.1
- const boundary = params.get("boundary")!;
- const dashBoundary = `--${boundary}`;
- const delimiter = `\r\n${dashBoundary}`;
- const closeDelimiter = `${delimiter}--`;
-
- const body = await this.text();
- let bodyParts: string[];
- const bodyEpilogueSplit = body.split(closeDelimiter);
- if (bodyEpilogueSplit.length < 2) {
- bodyParts = [];
- } else {
- // discard epilogue
- const bodyEpilogueTrimmed = bodyEpilogueSplit[0];
- // first boundary treated special due to optional prefixed \r\n
- const firstBoundaryIndex = bodyEpilogueTrimmed.indexOf(dashBoundary);
- if (firstBoundaryIndex < 0) {
- throw new TypeError("Invalid boundary");
- }
- const bodyPreambleTrimmed = bodyEpilogueTrimmed
- .slice(firstBoundaryIndex + dashBoundary.length)
- .replace(/^[\s\r\n\t]+/, ""); // remove transport-padding CRLF
- // trimStart might not be available
- // Be careful! body-part allows trailing \r\n!
- // (as long as it is not part of `delimiter`)
- bodyParts = bodyPreambleTrimmed
- .split(delimiter)
- .map((s): string => s.replace(/^[\s\r\n\t]+/, ""));
- // TODO: LWSP definition is actually trickier,
- // but should be fine in our case since without headers
- // we should just discard the part
- }
- for (const bodyPart of bodyParts) {
- const headers = new Headers();
- const headerOctetSeperatorIndex = bodyPart.indexOf("\r\n\r\n");
- if (headerOctetSeperatorIndex < 0) {
- continue; // Skip unknown part
- }
- const headerText = bodyPart.slice(0, headerOctetSeperatorIndex);
- const octets = bodyPart.slice(headerOctetSeperatorIndex + 4);
-
- // TODO: use textproto.readMIMEHeader from deno_std
- const rawHeaders = headerText.split("\r\n");
- for (const rawHeader of rawHeaders) {
- const sepIndex = rawHeader.indexOf(":");
- if (sepIndex < 0) {
- continue; // Skip this header
- }
- const key = rawHeader.slice(0, sepIndex);
- const value = rawHeader.slice(sepIndex + 1);
- headers.set(key, value);
- }
- if (!headers.has("content-disposition")) {
- continue; // Skip unknown part
- }
- // Content-Transfer-Encoding Deprecated
- const contentDisposition = headers.get("content-disposition")!;
- const partContentType = headers.get("content-type") || "text/plain";
- // TODO: custom charset encoding (needs TextEncoder support)
- // const contentTypeCharset =
- // getHeaderValueParams(partContentType).get("charset") || "";
- if (!hasHeaderValueOf(contentDisposition, "form-data")) {
- continue; // Skip, might not be form-data
- }
- const dispositionParams = getHeaderValueParams(contentDisposition);
- if (!dispositionParams.has("name")) {
- continue; // Skip, unknown name
- }
- const dispositionName = dispositionParams.get("name")!;
- if (dispositionParams.has("filename")) {
- const filename = dispositionParams.get("filename")!;
- const blob = new DenoBlob([enc.encode(octets)], {
- type: partContentType
- });
- // TODO: based on spec
- // https://xhr.spec.whatwg.org/#dom-formdata-append
- // https://xhr.spec.whatwg.org/#create-an-entry
- // Currently it does not mention how I could pass content-type
- // to the internally created file object...
- formData.append(dispositionName, blob, filename);
- } else {
- formData.append(dispositionName, octets);
- }
- }
- return formData;
- } else if (
- hasHeaderValueOf(this.contentType, "application/x-www-form-urlencoded")
- ) {
- // From https://github.com/github/fetch/blob/master/fetch.js
- // Copyright (c) 2014-2016 GitHub, Inc. MIT License
- const body = await this.text();
- try {
- body
- .trim()
- .split("&")
- .forEach(
- (bytes): void => {
- if (bytes) {
- const split = bytes.split("=");
- const name = split.shift()!.replace(/\+/g, " ");
- const value = split.join("=").replace(/\+/g, " ");
- formData.append(
- decodeURIComponent(name),
- decodeURIComponent(value)
- );
- }
- }
- );
- } catch (e) {
- throw new TypeError("Invalid form urlencoded format");
- }
- return formData;
- } else {
- throw new TypeError("Invalid form data");
- }
- }
-
- public async text(): Promise<string> {
- if (typeof this._bodySource === "string") {
- return this._bodySource;
- }
-
- const ab = await this.arrayBuffer();
- const decoder = new TextDecoder("utf-8");
- return decoder.decode(ab);
- }
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- public async json(): Promise<any> {
- const raw = await this.text();
- return JSON.parse(raw);
- }
-
- public async arrayBuffer(): Promise<ArrayBuffer> {
- if (
- this._bodySource instanceof Int8Array ||
- this._bodySource instanceof Int16Array ||
- this._bodySource instanceof Int32Array ||
- this._bodySource instanceof Uint8Array ||
- this._bodySource instanceof Uint16Array ||
- this._bodySource instanceof Uint32Array ||
- this._bodySource instanceof Uint8ClampedArray ||
- this._bodySource instanceof Float32Array ||
- this._bodySource instanceof Float64Array
- ) {
- return this._bodySource.buffer as ArrayBuffer;
- } else if (this._bodySource instanceof ArrayBuffer) {
- return this._bodySource;
- } else if (typeof this._bodySource === "string") {
- const enc = new TextEncoder();
- return enc.encode(this._bodySource).buffer as ArrayBuffer;
- } else if (this._bodySource instanceof FormData) {
- const enc = new TextEncoder();
- return enc.encode(this._bodySource.toString()).buffer as ArrayBuffer;
- } else if (!this._bodySource) {
- return new ArrayBuffer(0);
- }
- throw new Error(
- `Body type not yet implemented: ${this._bodySource.constructor.name}`
- );
- }
-}
diff --git a/js/body_test.ts b/js/body_test.ts
deleted file mode 100644
index ec76e9072..000000000
--- a/js/body_test.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, testPerm, assertEquals, assert } from "./test_util.ts";
-
-// just a hack to get a body object
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-function buildBody(body: any): Body {
- const stub = new Request("", {
- body: body
- });
- return stub as Body;
-}
-
-const intArrays = [
- Int8Array,
- Int16Array,
- Int32Array,
- Uint8Array,
- Uint16Array,
- Uint32Array,
- Uint8ClampedArray,
- Float32Array,
- Float64Array
-];
-test(async function arrayBufferFromByteArrays(): Promise<void> {
- const buffer = new TextEncoder().encode("ahoyhoy8").buffer;
-
- for (const type of intArrays) {
- const body = buildBody(new type(buffer));
- const text = new TextDecoder("utf-8").decode(await body.arrayBuffer());
- assertEquals(text, "ahoyhoy8");
- }
-});
-
-//FormData
-testPerm({ net: true }, async function bodyMultipartFormData(): Promise<void> {
- const response = await fetch(
- "http://localhost:4545/tests/subdir/multipart_form_data.txt"
- );
- const text = await response.text();
-
- const body = buildBody(text);
-
- // @ts-ignore
- body.contentType = "multipart/form-data;boundary=boundary";
-
- const formData = await body.formData();
- assert(formData.has("field_1"));
- assertEquals(formData.get("field_1").toString(), "value_1 \r\n");
- assert(formData.has("field_2"));
-});
-
-testPerm({ net: true }, async function bodyURLEncodedFormData(): Promise<void> {
- const response = await fetch(
- "http://localhost:4545/tests/subdir/form_urlencoded.txt"
- );
- const text = await response.text();
-
- const body = buildBody(text);
-
- // @ts-ignore
- body.contentType = "application/x-www-form-urlencoded";
-
- const formData = await body.formData();
- assert(formData.has("field_1"));
- assertEquals(formData.get("field_1").toString(), "Hi");
- assert(formData.has("field_2"));
- assertEquals(formData.get("field_2").toString(), "<Deno>");
-});
diff --git a/js/buffer.ts b/js/buffer.ts
deleted file mode 100644
index dc73b7e60..000000000
--- a/js/buffer.ts
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-// This code has been ported almost directly from Go's src/bytes/buffer.go
-// Copyright 2009 The Go Authors. All rights reserved. BSD license.
-// https://github.com/golang/go/blob/master/LICENSE
-
-import { Reader, Writer, EOF, SyncReader, SyncWriter } from "./io.ts";
-import { assert } from "./util.ts";
-import { TextDecoder } from "./text_encoding.ts";
-import { DenoError, ErrorKind } from "./errors.ts";
-
-// MIN_READ is the minimum ArrayBuffer size passed to a read call by
-// buffer.ReadFrom. As long as the Buffer has at least MIN_READ bytes beyond
-// what is required to hold the contents of r, readFrom() will not grow the
-// underlying buffer.
-const MIN_READ = 512;
-const MAX_SIZE = 2 ** 32 - 2;
-
-// `off` is the offset into `dst` where it will at which to begin writing values
-// from `src`.
-// Returns the number of bytes copied.
-function copyBytes(dst: Uint8Array, src: Uint8Array, off = 0): number {
- const r = dst.byteLength - off;
- if (src.byteLength > r) {
- src = src.subarray(0, r);
- }
- dst.set(src, off);
- return src.byteLength;
-}
-
-/** 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: Uint8Array; // contents are the bytes buf[off : len(buf)]
- private off = 0; // read at buf[off], write at buf[buf.byteLength]
-
- constructor(ab?: ArrayBuffer) {
- if (ab == null) {
- this.buf = new Uint8Array(0);
- return;
- }
-
- this.buf = new Uint8Array(ab);
- }
-
- /** 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 {
- return this.buf.subarray(this.off);
- }
-
- /** 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 {
- const decoder = new TextDecoder();
- return decoder.decode(this.buf.subarray(this.off));
- }
-
- /** empty() returns whether the unread portion of the buffer is empty. */
- empty(): boolean {
- return this.buf.byteLength <= this.off;
- }
-
- /** length is a getter that returns the number of bytes of the unread
- * portion of the buffer
- */
- get length(): number {
- return this.buf.byteLength - this.off;
- }
-
- /** Returns the capacity of the buffer's underlying byte slice, that is,
- * the total space allocated for the buffer's data.
- */
- get capacity(): number {
- return this.buf.buffer.byteLength;
- }
-
- /** 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 {
- if (n === 0) {
- this.reset();
- return;
- }
- if (n < 0 || n > this.length) {
- throw Error("bytes.Buffer: truncation out of range");
- }
- this._reslice(this.off + n);
- }
-
- /** 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 {
- this._reslice(0);
- this.off = 0;
- }
-
- /** _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(n: number): number {
- const l = this.buf.byteLength;
- if (n <= this.capacity - l) {
- this._reslice(l + n);
- return l;
- }
- return -1;
- }
-
- private _reslice(len: number): void {
- assert(len <= this.buf.buffer.byteLength);
- this.buf = new Uint8Array(this.buf.buffer, 0, len);
- }
-
- /** 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 {
- if (this.empty()) {
- // Buffer is empty, reset to recover space.
- this.reset();
- if (p.byteLength === 0) {
- // this edge case is tested in 'bufferReadEmptyAtEOF' test
- return 0;
- }
- return EOF;
- }
- const nread = copyBytes(p, this.buf.subarray(this.off));
- this.off += nread;
- return nread;
- }
-
- async read(p: Uint8Array): Promise<number | EOF> {
- const rr = this.readSync(p);
- return Promise.resolve(rr);
- }
-
- writeSync(p: Uint8Array): number {
- const m = this._grow(p.byteLength);
- return copyBytes(this.buf, p, m);
- }
-
- async write(p: Uint8Array): Promise<number> {
- const n = this.writeSync(p);
- return Promise.resolve(n);
- }
-
- /** _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(n: number): number {
- const m = this.length;
- // If buffer is empty, reset to recover space.
- if (m === 0 && this.off !== 0) {
- this.reset();
- }
- // Fast: Try to grow by means of a reslice.
- const i = this._tryGrowByReslice(n);
- if (i >= 0) {
- return i;
- }
- const c = this.capacity;
- if (n <= Math.floor(c / 2) - m) {
- // We can slide things down instead of allocating a new
- // ArrayBuffer. We only need m+n <= c to slide, but
- // we instead let capacity get twice as large so we
- // don't spend all our time copying.
- copyBytes(this.buf, this.buf.subarray(this.off));
- } else if (c > MAX_SIZE - c - n) {
- throw new DenoError(
- ErrorKind.TooLarge,
- "The buffer cannot be grown beyond the maximum size."
- );
- } else {
- // Not enough space anywhere, we need to allocate.
- const buf = new Uint8Array(2 * c + n);
- copyBytes(buf, this.buf.subarray(this.off));
- this.buf = buf;
- }
- // Restore this.off and len(this.buf).
- this.off = 0;
- this._reslice(m + n);
- return m;
- }
-
- /** 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 {
- if (n < 0) {
- throw Error("Buffer.grow: negative count");
- }
- const m = this._grow(n);
- this._reslice(m);
- }
-
- /** 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
- */
- async readFrom(r: Reader): Promise<number> {
- let n = 0;
- while (true) {
- try {
- const i = this._grow(MIN_READ);
- this._reslice(i);
- const fub = new Uint8Array(this.buf.buffer, i);
- const nread = await r.read(fub);
- if (nread === EOF) {
- return n;
- }
- this._reslice(i + nread);
- n += nread;
- } catch (e) {
- return n;
- }
- }
- }
-
- /** Sync version of `readFrom`
- */
- readFromSync(r: SyncReader): number {
- let n = 0;
- while (true) {
- try {
- const i = this._grow(MIN_READ);
- this._reslice(i);
- const fub = new Uint8Array(this.buf.buffer, i);
- const nread = r.readSync(fub);
- if (nread === EOF) {
- return n;
- }
- this._reslice(i + nread);
- n += nread;
- } catch (e) {
- return n;
- }
- }
- }
-}
-
-/** Read `r` until EOF and return the content as `Uint8Array`.
- */
-export async function readAll(r: Reader): Promise<Uint8Array> {
- const buf = new Buffer();
- await buf.readFrom(r);
- return buf.bytes();
-}
-
-/** Read synchronously `r` until EOF and return the content as `Uint8Array`.
- */
-export function readAllSync(r: SyncReader): Uint8Array {
- const buf = new Buffer();
- buf.readFromSync(r);
- return buf.bytes();
-}
-
-/** Write all the content of `arr` to `w`.
- */
-export async function writeAll(w: Writer, arr: Uint8Array): Promise<void> {
- let nwritten = 0;
- while (nwritten < arr.length) {
- nwritten += await w.write(arr.subarray(nwritten));
- }
-}
-
-/** Write synchronously all the content of `arr` to `w`.
- */
-export function writeAllSync(w: SyncWriter, arr: Uint8Array): void {
- let nwritten = 0;
- while (nwritten < arr.length) {
- nwritten += w.writeSync(arr.subarray(nwritten));
- }
-}
diff --git a/js/buffer_test.ts b/js/buffer_test.ts
deleted file mode 100644
index a157b927e..000000000
--- a/js/buffer_test.ts
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-// This code has been ported almost directly from Go's src/bytes/buffer_test.go
-// Copyright 2009 The Go Authors. All rights reserved. BSD license.
-// https://github.com/golang/go/blob/master/LICENSE
-import { assertEquals, test } from "./test_util.ts";
-
-const { Buffer, readAll, readAllSync, writeAll, writeAllSync } = Deno;
-type Buffer = Deno.Buffer;
-
-// N controls how many iterations of certain checks are performed.
-const N = 100;
-let testBytes: Uint8Array | null;
-let testString: string | null;
-
-function init(): void {
- if (testBytes == null) {
- testBytes = new Uint8Array(N);
- for (let i = 0; i < N; i++) {
- testBytes[i] = "a".charCodeAt(0) + (i % 26);
- }
- const decoder = new TextDecoder();
- testString = decoder.decode(testBytes);
- }
-}
-
-function check(buf: Deno.Buffer, s: string): void {
- const bytes = buf.bytes();
- assertEquals(buf.length, bytes.byteLength);
- const decoder = new TextDecoder();
- const bytesStr = decoder.decode(bytes);
- assertEquals(bytesStr, s);
- assertEquals(buf.length, buf.toString().length);
- assertEquals(buf.length, s.length);
-}
-
-// Fill buf through n writes of byte slice fub.
-// The initial contents of buf corresponds to the string s;
-// the result is the final contents of buf returned as a string.
-async function fillBytes(
- buf: Buffer,
- s: string,
- n: number,
- fub: Uint8Array
-): Promise<string> {
- check(buf, s);
- for (; n > 0; n--) {
- const m = await buf.write(fub);
- assertEquals(m, fub.byteLength);
- const decoder = new TextDecoder();
- s += decoder.decode(fub);
- check(buf, s);
- }
- return s;
-}
-
-// Empty buf through repeated reads into fub.
-// The initial contents of buf corresponds to the string s.
-async function empty(buf: Buffer, s: string, fub: Uint8Array): Promise<void> {
- check(buf, s);
- while (true) {
- const r = await buf.read(fub);
- if (r === Deno.EOF) {
- break;
- }
- s = s.slice(r);
- check(buf, s);
- }
- check(buf, "");
-}
-
-function repeat(c: string, bytes: number): Uint8Array {
- assertEquals(c.length, 1);
- const ui8 = new Uint8Array(bytes);
- ui8.fill(c.charCodeAt(0));
- return ui8;
-}
-
-test(function bufferNewBuffer(): void {
- init();
- const buf = new Buffer(testBytes.buffer as ArrayBuffer);
- check(buf, testString);
-});
-
-test(async function bufferBasicOperations(): Promise<void> {
- init();
- const buf = new Buffer();
- for (let i = 0; i < 5; i++) {
- check(buf, "");
-
- buf.reset();
- check(buf, "");
-
- buf.truncate(0);
- check(buf, "");
-
- let n = await buf.write(testBytes.subarray(0, 1));
- assertEquals(n, 1);
- check(buf, "a");
-
- n = await buf.write(testBytes.subarray(1, 2));
- assertEquals(n, 1);
- check(buf, "ab");
-
- n = await buf.write(testBytes.subarray(2, 26));
- assertEquals(n, 24);
- check(buf, testString.slice(0, 26));
-
- buf.truncate(26);
- check(buf, testString.slice(0, 26));
-
- buf.truncate(20);
- check(buf, testString.slice(0, 20));
-
- await empty(buf, testString.slice(0, 20), new Uint8Array(5));
- await empty(buf, "", new Uint8Array(100));
-
- // TODO buf.writeByte()
- // TODO buf.readByte()
- }
-});
-
-test(async function bufferReadEmptyAtEOF(): Promise<void> {
- // check that EOF of 'buf' is not reached (even though it's empty) if
- // results are written to buffer that has 0 length (ie. it can't store any data)
- const buf = new Buffer();
- const zeroLengthTmp = new Uint8Array(0);
- const result = await buf.read(zeroLengthTmp);
- assertEquals(result, 0);
-});
-
-test(async function bufferLargeByteWrites(): Promise<void> {
- init();
- const buf = new Buffer();
- const limit = 9;
- for (let i = 3; i < limit; i += 3) {
- const s = await fillBytes(buf, "", 5, testBytes);
- await empty(buf, s, new Uint8Array(Math.floor(testString.length / i)));
- }
- check(buf, "");
-});
-
-test(async function bufferTooLargeByteWrites(): Promise<void> {
- init();
- const tmp = new Uint8Array(72);
- const growLen = Number.MAX_VALUE;
- const xBytes = repeat("x", 0);
- const buf = new Buffer(xBytes.buffer as ArrayBuffer);
- await buf.read(tmp);
-
- let err;
- try {
- buf.grow(growLen);
- } catch (e) {
- err = e;
- }
-
- assertEquals(err.kind, Deno.ErrorKind.TooLarge);
- assertEquals(err.name, "TooLarge");
-});
-
-test(async function bufferLargeByteReads(): Promise<void> {
- init();
- const buf = new Buffer();
- for (let i = 3; i < 30; i += 3) {
- const n = Math.floor(testBytes.byteLength / i);
- const s = await fillBytes(buf, "", 5, testBytes.subarray(0, n));
- await empty(buf, s, new Uint8Array(testString.length));
- }
- check(buf, "");
-});
-
-test(function bufferCapWithPreallocatedSlice(): void {
- const buf = new Buffer(new ArrayBuffer(10));
- assertEquals(buf.capacity, 10);
-});
-
-test(async function bufferReadFrom(): Promise<void> {
- init();
- const buf = new Buffer();
- for (let i = 3; i < 30; i += 3) {
- const s = await fillBytes(
- buf,
- "",
- 5,
- testBytes.subarray(0, Math.floor(testBytes.byteLength / i))
- );
- const b = new Buffer();
- await b.readFrom(buf);
- const fub = new Uint8Array(testString.length);
- await empty(b, s, fub);
- }
-});
-
-test(async function bufferReadFromSync(): Promise<void> {
- init();
- const buf = new Buffer();
- for (let i = 3; i < 30; i += 3) {
- const s = await fillBytes(
- buf,
- "",
- 5,
- testBytes.subarray(0, Math.floor(testBytes.byteLength / i))
- );
- const b = new Buffer();
- b.readFromSync(buf);
- const fub = new Uint8Array(testString.length);
- await empty(b, s, fub);
- }
-});
-
-test(async function bufferTestGrow(): Promise<void> {
- const tmp = new Uint8Array(72);
- for (const startLen of [0, 100, 1000, 10000, 100000]) {
- const xBytes = repeat("x", startLen);
- for (const growLen of [0, 100, 1000, 10000, 100000]) {
- const buf = new Buffer(xBytes.buffer as ArrayBuffer);
- // If we read, this affects buf.off, which is good to test.
- const result = await buf.read(tmp);
- const nread = result === Deno.EOF ? 0 : result;
- buf.grow(growLen);
- const yBytes = repeat("y", growLen);
- await buf.write(yBytes);
- // Check that buffer has correct data.
- assertEquals(
- buf.bytes().subarray(0, startLen - nread),
- xBytes.subarray(nread)
- );
- assertEquals(
- buf.bytes().subarray(startLen - nread, startLen - nread + growLen),
- yBytes
- );
- }
- }
-});
-
-test(async function testReadAll(): Promise<void> {
- init();
- const reader = new Buffer(testBytes.buffer as ArrayBuffer);
- const actualBytes = await readAll(reader);
- assertEquals(testBytes.byteLength, actualBytes.byteLength);
- for (let i = 0; i < testBytes.length; ++i) {
- assertEquals(testBytes[i], actualBytes[i]);
- }
-});
-
-test(function testReadAllSync(): void {
- init();
- const reader = new Buffer(testBytes.buffer as ArrayBuffer);
- const actualBytes = readAllSync(reader);
- assertEquals(testBytes.byteLength, actualBytes.byteLength);
- for (let i = 0; i < testBytes.length; ++i) {
- assertEquals(testBytes[i], actualBytes[i]);
- }
-});
-
-test(async function testWriteAll(): Promise<void> {
- init();
- const writer = new Buffer();
- await writeAll(writer, testBytes);
- const actualBytes = writer.bytes();
- assertEquals(testBytes.byteLength, actualBytes.byteLength);
- for (let i = 0; i < testBytes.length; ++i) {
- assertEquals(testBytes[i], actualBytes[i]);
- }
-});
-
-test(function testWriteAllSync(): void {
- init();
- const writer = new Buffer();
- writeAllSync(writer, testBytes);
- const actualBytes = writer.bytes();
- assertEquals(testBytes.byteLength, actualBytes.byteLength);
- for (let i = 0; i < testBytes.length; ++i) {
- assertEquals(testBytes[i], actualBytes[i]);
- }
-});
diff --git a/js/build.rs b/js/build.rs
deleted file mode 100644
index 1063fd8eb..000000000
--- a/js/build.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use std::env;
-use std::path::PathBuf;
-
-fn main() {
- // To debug snapshot issues uncomment:
- // deno_typescript::trace_serializer();
-
- println!(
- "cargo:rustc-env=TS_VERSION={}",
- deno_typescript::ts_version()
- );
-
- let c = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
- let o = PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
- let root_names = vec![c.join("main.ts")];
- let bundle = o.join("CLI_SNAPSHOT.js");
- let state = deno_typescript::compile_bundle(&bundle, root_names).unwrap();
- assert!(bundle.exists());
- deno_typescript::mksnapshot_bundle(&bundle, state).unwrap();
-
- let root_names = vec![c.join("compiler.ts")];
- let bundle = o.join("COMPILER_SNAPSHOT.js");
- let state = deno_typescript::compile_bundle(&bundle, root_names).unwrap();
- assert!(bundle.exists());
- deno_typescript::mksnapshot_bundle_ts(&bundle, state).unwrap();
-}
diff --git a/js/build.ts b/js/build.ts
deleted file mode 100644
index 942f57458..000000000
--- a/js/build.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-export type OperatingSystem = "mac" | "win" | "linux";
-
-export type Arch = "x64" | "arm64";
-
-// Do not add unsupported platforms.
-/** Build related information */
-export interface BuildInfo {
- /** The CPU architecture. */
- arch: Arch;
-
- /** The operating system. */
- os: OperatingSystem;
-}
-
-export const build: BuildInfo = {
- arch: "" as Arch,
- os: "" as OperatingSystem
-};
-
-export function setBuildInfo(os: OperatingSystem, arch: Arch): void {
- build.os = os;
- build.arch = arch;
-
- Object.freeze(build);
-}
diff --git a/js/build_test.ts b/js/build_test.ts
deleted file mode 100644
index 4423de338..000000000
--- a/js/build_test.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert } from "./test_util.ts";
-
-test(function buildInfo(): void {
- // Deno.build is injected by rollup at compile time. Here
- // we check it has been properly transformed.
- const { arch, os } = Deno.build;
- assert(arch === "x64");
- assert(os === "mac" || os === "win" || os === "linux");
-});
diff --git a/js/chmod.ts b/js/chmod.ts
deleted file mode 100644
index 7bf54cc5b..000000000
--- a/js/chmod.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.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 {
- sendSync(dispatch.OP_CHMOD, { path, mode });
-}
-
-/** Changes the permission of a specific file/directory of specified path.
- *
- * await Deno.chmod("/path/to/file", 0o666);
- */
-export async function chmod(path: string, mode: number): Promise<void> {
- await sendAsync(dispatch.OP_CHMOD, { path, mode });
-}
diff --git a/js/chmod_test.ts b/js/chmod_test.ts
deleted file mode 100644
index 420f4f313..000000000
--- a/js/chmod_test.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assertEquals } from "./test_util.ts";
-
-const isNotWindows = Deno.build.os !== "win";
-
-testPerm({ read: true, write: true }, function chmodSyncSuccess(): void {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const tempDir = Deno.makeTempDirSync();
- const filename = tempDir + "/test.txt";
- Deno.writeFileSync(filename, data, { perm: 0o666 });
-
- // On windows no effect, but should not crash
- Deno.chmodSync(filename, 0o777);
-
- // Check success when not on windows
- if (isNotWindows) {
- const fileInfo = Deno.statSync(filename);
- assertEquals(fileInfo.mode & 0o777, 0o777);
- }
-});
-
-// Check symlink when not on windows
-if (isNotWindows) {
- testPerm(
- { read: true, write: true },
- function chmodSyncSymlinkSuccess(): void {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const tempDir = Deno.makeTempDirSync();
-
- const filename = tempDir + "/test.txt";
- Deno.writeFileSync(filename, data, { perm: 0o666 });
- const symlinkName = tempDir + "/test_symlink.txt";
- Deno.symlinkSync(filename, symlinkName);
-
- let symlinkInfo = Deno.lstatSync(symlinkName);
- const symlinkMode = symlinkInfo.mode & 0o777; // platform dependent
-
- Deno.chmodSync(symlinkName, 0o777);
-
- // Change actual file mode, not symlink
- const fileInfo = Deno.statSync(filename);
- assertEquals(fileInfo.mode & 0o777, 0o777);
- symlinkInfo = Deno.lstatSync(symlinkName);
- assertEquals(symlinkInfo.mode & 0o777, symlinkMode);
- }
- );
-}
-
-testPerm({ write: true }, function chmodSyncFailure(): void {
- let err;
- try {
- const filename = "/badfile.txt";
- Deno.chmodSync(filename, 0o777);
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: false }, function chmodSyncPerm(): void {
- let err;
- try {
- Deno.chmodSync("/somefile.txt", 0o777);
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ read: true, write: true }, async function chmodSuccess(): Promise<
- void
-> {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const tempDir = Deno.makeTempDirSync();
- const filename = tempDir + "/test.txt";
- Deno.writeFileSync(filename, data, { perm: 0o666 });
-
- // On windows no effect, but should not crash
- await Deno.chmod(filename, 0o777);
-
- // Check success when not on windows
- if (isNotWindows) {
- const fileInfo = Deno.statSync(filename);
- assertEquals(fileInfo.mode & 0o777, 0o777);
- }
-});
-
-// Check symlink when not on windows
-if (isNotWindows) {
- testPerm(
- { read: true, write: true },
- async function chmodSymlinkSuccess(): Promise<void> {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const tempDir = Deno.makeTempDirSync();
-
- const filename = tempDir + "/test.txt";
- Deno.writeFileSync(filename, data, { perm: 0o666 });
- const symlinkName = tempDir + "/test_symlink.txt";
- Deno.symlinkSync(filename, symlinkName);
-
- let symlinkInfo = Deno.lstatSync(symlinkName);
- const symlinkMode = symlinkInfo.mode & 0o777; // platform dependent
-
- await Deno.chmod(symlinkName, 0o777);
-
- // Just change actual file mode, not symlink
- const fileInfo = Deno.statSync(filename);
- assertEquals(fileInfo.mode & 0o777, 0o777);
- symlinkInfo = Deno.lstatSync(symlinkName);
- assertEquals(symlinkInfo.mode & 0o777, symlinkMode);
- }
- );
-}
-
-testPerm({ write: true }, async function chmodFailure(): Promise<void> {
- let err;
- try {
- const filename = "/badfile.txt";
- await Deno.chmod(filename, 0o777);
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: false }, async function chmodPerm(): Promise<void> {
- let err;
- try {
- await Deno.chmod("/somefile.txt", 0o777);
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
diff --git a/js/chown.ts b/js/chown.ts
deleted file mode 100644
index a8bad1193..000000000
--- a/js/chown.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.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 {
- sendSync(dispatch.OP_CHOWN, { path, uid, gid });
-}
-
-/**
- * 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 async function chown(
- path: string,
- uid: number,
- gid: number
-): Promise<void> {
- await sendAsync(dispatch.OP_CHOWN, { path, uid, gid });
-}
diff --git a/js/chown_test.ts b/js/chown_test.ts
deleted file mode 100644
index 84106d545..000000000
--- a/js/chown_test.ts
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assertEquals } from "./test_util.ts";
-
-// chown on Windows is noop for now, so ignore its testing on Windows
-if (Deno.build.os !== "win") {
- async function getUidAndGid(): Promise<{ uid: number; gid: number }> {
- // get the user ID and group ID of the current process
- const uidProc = Deno.run({
- stdout: "piped",
- args: ["python", "-c", "import os; print(os.getuid())"]
- });
- const gidProc = Deno.run({
- stdout: "piped",
- args: ["python", "-c", "import os; print(os.getgid())"]
- });
-
- assertEquals((await uidProc.status()).code, 0);
- assertEquals((await gidProc.status()).code, 0);
- const uid = parseInt(
- new TextDecoder("utf-8").decode(await uidProc.output())
- );
- const gid = parseInt(
- new TextDecoder("utf-8").decode(await gidProc.output())
- );
-
- return { uid, gid };
- }
-
- testPerm({}, async function chownNoWritePermission(): Promise<void> {
- const filePath = "chown_test_file.txt";
- try {
- await Deno.chown(filePath, 1000, 1000);
- } catch (e) {
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- });
-
- testPerm(
- { run: true, write: true },
- async function chownSyncFileNotExist(): Promise<void> {
- const { uid, gid } = await getUidAndGid();
- const filePath = Deno.makeTempDirSync() + "/chown_test_file.txt";
-
- try {
- Deno.chownSync(filePath, uid, gid);
- } catch (e) {
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- assertEquals(e.name, "NotFound");
- }
- }
- );
-
- testPerm(
- { run: true, write: true },
- async function chownFileNotExist(): Promise<void> {
- const { uid, gid } = await getUidAndGid();
- const filePath = (await Deno.makeTempDir()) + "/chown_test_file.txt";
-
- try {
- await Deno.chown(filePath, uid, gid);
- } catch (e) {
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- assertEquals(e.name, "NotFound");
- }
- }
- );
-
- testPerm({ write: true }, function chownSyncPermissionDenied(): void {
- const enc = new TextEncoder();
- const dirPath = Deno.makeTempDirSync();
- const filePath = dirPath + "/chown_test_file.txt";
- const fileData = enc.encode("Hello");
- Deno.writeFileSync(filePath, fileData);
-
- try {
- // try changing the file's owner to root
- Deno.chownSync(filePath, 0, 0);
- } catch (e) {
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- Deno.removeSync(dirPath, { recursive: true });
- });
-
- testPerm({ write: true }, async function chownPermissionDenied(): Promise<
- void
- > {
- const enc = new TextEncoder();
- const dirPath = await Deno.makeTempDir();
- const filePath = dirPath + "/chown_test_file.txt";
- const fileData = enc.encode("Hello");
- await Deno.writeFile(filePath, fileData);
-
- try {
- // try changing the file's owner to root
- await Deno.chown(filePath, 0, 0);
- } catch (e) {
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- await Deno.remove(dirPath, { recursive: true });
- });
-
- testPerm(
- { run: true, write: true },
- async function chownSyncSucceed(): Promise<void> {
- // TODO: when a file's owner is actually being changed,
- // chown only succeeds if run under priviledged user (root)
- // The test script has no such priviledge, so need to find a better way to test this case
- const { uid, gid } = await getUidAndGid();
-
- const enc = new TextEncoder();
- const dirPath = Deno.makeTempDirSync();
- const filePath = dirPath + "/chown_test_file.txt";
- const fileData = enc.encode("Hello");
- Deno.writeFileSync(filePath, fileData);
-
- // the test script creates this file with the same uid and gid,
- // here chown is a noop so it succeeds under non-priviledged user
- Deno.chownSync(filePath, uid, gid);
-
- Deno.removeSync(dirPath, { recursive: true });
- }
- );
-
- testPerm({ run: true, write: true }, async function chownSucceed(): Promise<
- void
- > {
- // TODO: same as chownSyncSucceed
- const { uid, gid } = await getUidAndGid();
-
- const enc = new TextEncoder();
- const dirPath = await Deno.makeTempDir();
- const filePath = dirPath + "/chown_test_file.txt";
- const fileData = enc.encode("Hello");
- await Deno.writeFile(filePath, fileData);
-
- // the test script creates this file with the same uid and gid,
- // here chown is a noop so it succeeds under non-priviledged user
- await Deno.chown(filePath, uid, gid);
-
- Deno.removeSync(dirPath, { recursive: true });
- });
-}
diff --git a/js/colors.ts b/js/colors.ts
deleted file mode 100644
index 9937bdb57..000000000
--- a/js/colors.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-// TODO(kitsonk) Replace with `deno_std/colors/mod.ts` when we can load modules
-// which end in `.ts`.
-
-import { noColor } from "./deno.ts";
-
-interface Code {
- open: string;
- close: string;
- regexp: RegExp;
-}
-
-const enabled = !noColor;
-
-function code(open: number, close: number): Code {
- return {
- open: `\x1b[${open}m`,
- close: `\x1b[${close}m`,
- regexp: new RegExp(`\\x1b\\[${close}m`, "g")
- };
-}
-
-function run(str: string, code: Code): string {
- return enabled
- ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}`
- : str;
-}
-
-export function bold(str: string): string {
- return run(str, code(1, 22));
-}
-
-export function yellow(str: string): string {
- return run(str, code(33, 39));
-}
-
-export function cyan(str: string): string {
- return run(str, code(36, 39));
-}
diff --git a/js/compiler.ts b/js/compiler.ts
deleted file mode 100644
index 57e5e3a47..000000000
--- a/js/compiler.ts
+++ /dev/null
@@ -1,667 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-// TODO(ry) Combine this implementation with //deno_typescript/compiler_main.js
-
-import "./globals.ts";
-import "./ts_global.d.ts";
-
-import { bold, cyan, yellow } from "./colors.ts";
-import { Console } from "./console.ts";
-import { core } from "./core.ts";
-import { Diagnostic, fromTypeScriptDiagnostic } from "./diagnostics.ts";
-import { cwd } from "./dir.ts";
-import * as dispatch from "./dispatch.ts";
-import { sendAsync, sendSync } from "./dispatch_json.ts";
-import * as os from "./os.ts";
-import { TextEncoder } from "./text_encoding.ts";
-import { getMappedModuleName, parseTypeDirectives } from "./type_directives.ts";
-import { assert, notImplemented } from "./util.ts";
-import * as util from "./util.ts";
-import { window } from "./window.ts";
-import { postMessage, workerClose, workerMain } from "./workers.ts";
-import { writeFileSync } from "./write_file.ts";
-
-// Warning! The values in this enum are duplicated in cli/msg.rs
-// Update carefully!
-enum MediaType {
- JavaScript = 0,
- JSX = 1,
- TypeScript = 2,
- TSX = 3,
- Json = 4,
- Unknown = 5
-}
-
-// Startup boilerplate. This is necessary because the compiler has its own
-// snapshot. (It would be great if we could remove these things or centralize
-// them somewhere else.)
-const console = new Console(core.print);
-window.console = console;
-window.workerMain = workerMain;
-function denoMain(): void {
- os.start(true, "TS");
-}
-window["denoMain"] = denoMain;
-
-const ASSETS = "$asset$";
-const OUT_DIR = "$deno$";
-
-/** The format of the work message payload coming from the privileged side */
-interface CompilerReq {
- rootNames: string[];
- bundle?: string;
- // TODO(ry) add compiler config to this interface.
- // options: ts.CompilerOptions;
- configPath?: string;
- config?: string;
-}
-
-interface ConfigureResponse {
- ignoredOptions?: string[];
- diagnostics?: ts.Diagnostic[];
-}
-
-/** Options that either do nothing in Deno, or would cause undesired behavior
- * if modified. */
-const ignoredCompilerOptions: readonly string[] = [
- "allowSyntheticDefaultImports",
- "baseUrl",
- "build",
- "composite",
- "declaration",
- "declarationDir",
- "declarationMap",
- "diagnostics",
- "downlevelIteration",
- "emitBOM",
- "emitDeclarationOnly",
- "esModuleInterop",
- "extendedDiagnostics",
- "forceConsistentCasingInFileNames",
- "help",
- "importHelpers",
- "incremental",
- "inlineSourceMap",
- "inlineSources",
- "init",
- "isolatedModules",
- "lib",
- "listEmittedFiles",
- "listFiles",
- "mapRoot",
- "maxNodeModuleJsDepth",
- "module",
- "moduleResolution",
- "newLine",
- "noEmit",
- "noEmitHelpers",
- "noEmitOnError",
- "noLib",
- "noResolve",
- "out",
- "outDir",
- "outFile",
- "paths",
- "preserveSymlinks",
- "preserveWatchOutput",
- "pretty",
- "rootDir",
- "rootDirs",
- "showConfig",
- "skipDefaultLibCheck",
- "skipLibCheck",
- "sourceMap",
- "sourceRoot",
- "stripInternal",
- "target",
- "traceResolution",
- "tsBuildInfoFile",
- "types",
- "typeRoots",
- "version",
- "watch"
-];
-
-/** The shape of the SourceFile that comes from the privileged side */
-interface SourceFileJson {
- url: string;
- filename: string;
- mediaType: MediaType;
- sourceCode: string;
-}
-
-/** A self registering abstraction of source files. */
-class SourceFile {
- extension!: ts.Extension;
- filename!: string;
-
- /** An array of tuples which represent the imports for the source file. The
- * first element is the one that will be requested at compile time, the
- * second is the one that should be actually resolved. This provides the
- * feature of type directives for Deno. */
- importedFiles?: Array<[string, string]>;
-
- mediaType!: MediaType;
- processed = false;
- sourceCode!: string;
- tsSourceFile?: ts.SourceFile;
- url!: string;
-
- constructor(json: SourceFileJson) {
- if (SourceFile._moduleCache.has(json.url)) {
- throw new TypeError("SourceFile already exists");
- }
- Object.assign(this, json);
- this.extension = getExtension(this.url, this.mediaType);
- SourceFile._moduleCache.set(this.url, this);
- }
-
- /** Cache the source file to be able to be retrieved by `moduleSpecifier` and
- * `containingFile`. */
- cache(moduleSpecifier: string, containingFile: string): void {
- let innerCache = SourceFile._specifierCache.get(containingFile);
- if (!innerCache) {
- innerCache = new Map();
- SourceFile._specifierCache.set(containingFile, innerCache);
- }
- innerCache.set(moduleSpecifier, this);
- }
-
- /** Process the imports for the file and return them. */
- imports(): Array<[string, string]> {
- if (this.processed) {
- throw new Error("SourceFile has already been processed.");
- }
- assert(this.sourceCode != null);
- const preProcessedFileInfo = ts.preProcessFile(
- this.sourceCode!,
- true,
- true
- );
- this.processed = true;
- const files = (this.importedFiles = [] as Array<[string, string]>);
-
- function process(references: ts.FileReference[]): void {
- for (const { fileName } of references) {
- files.push([fileName, fileName]);
- }
- }
-
- const {
- importedFiles,
- referencedFiles,
- libReferenceDirectives,
- typeReferenceDirectives
- } = preProcessedFileInfo;
- const typeDirectives = parseTypeDirectives(this.sourceCode);
- if (typeDirectives) {
- for (const importedFile of importedFiles) {
- files.push([
- importedFile.fileName,
- getMappedModuleName(importedFile, typeDirectives)
- ]);
- }
- } else {
- process(importedFiles);
- }
- process(referencedFiles);
- process(libReferenceDirectives);
- process(typeReferenceDirectives);
- return files;
- }
-
- /** A cache of all the source files which have been loaded indexed by the
- * url. */
- private static _moduleCache: Map<string, SourceFile> = new Map();
-
- /** A cache of source files based on module specifiers and containing files
- * which is used by the TypeScript compiler to resolve the url */
- private static _specifierCache: Map<
- string,
- Map<string, SourceFile>
- > = new Map();
-
- /** Retrieve a `SourceFile` based on a `moduleSpecifier` and `containingFile`
- * or return `undefined` if not preset. */
- static getUrl(
- moduleSpecifier: string,
- containingFile: string
- ): string | undefined {
- const containingCache = this._specifierCache.get(containingFile);
- if (containingCache) {
- const sourceFile = containingCache.get(moduleSpecifier);
- return sourceFile && sourceFile.url;
- }
- return undefined;
- }
-
- /** Retrieve a `SourceFile` based on a `url` */
- static get(url: string): SourceFile | undefined {
- return this._moduleCache.get(url);
- }
-}
-
-interface EmitResult {
- emitSkipped: boolean;
- diagnostics?: Diagnostic;
-}
-
-/** Ops to Rust to resolve special static assets. */
-function fetchAsset(name: string): string {
- return sendSync(dispatch.OP_FETCH_ASSET, { name });
-}
-
-/** Ops to Rust to resolve and fetch modules meta data. */
-function fetchSourceFiles(
- specifiers: string[],
- referrer: string
-): Promise<SourceFileJson[]> {
- util.log("compiler::fetchSourceFiles", { specifiers, referrer });
- return sendAsync(dispatch.OP_FETCH_SOURCE_FILES, {
- specifiers,
- referrer
- });
-}
-
-/** Recursively process the imports of modules, generating `SourceFile`s of any
- * imported files.
- *
- * Specifiers are supplied in an array of tupples where the first is the
- * specifier that will be requested in the code and the second is the specifier
- * that should be actually resolved. */
-async function processImports(
- specifiers: Array<[string, string]>,
- referrer = ""
-): Promise<void> {
- if (!specifiers.length) {
- return;
- }
- const sources = specifiers.map(([, moduleSpecifier]) => moduleSpecifier);
- const sourceFiles = await fetchSourceFiles(sources, referrer);
- assert(sourceFiles.length === specifiers.length);
- for (let i = 0; i < sourceFiles.length; i++) {
- const sourceFileJson = sourceFiles[i];
- const sourceFile =
- SourceFile.get(sourceFileJson.url) || new SourceFile(sourceFileJson);
- sourceFile.cache(specifiers[i][0], referrer);
- if (!sourceFile.processed) {
- await processImports(sourceFile.imports(), sourceFile.url);
- }
- }
-}
-
-/** Utility function to turn the number of bytes into a human readable
- * unit */
-function humanFileSize(bytes: number): string {
- const thresh = 1000;
- if (Math.abs(bytes) < thresh) {
- return bytes + " B";
- }
- const units = ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
- let u = -1;
- do {
- bytes /= thresh;
- ++u;
- } while (Math.abs(bytes) >= thresh && u < units.length - 1);
- return `${bytes.toFixed(1)} ${units[u]}`;
-}
-
-/** Ops to rest for caching source map and compiled js */
-function cache(extension: string, moduleId: string, contents: string): void {
- util.log("compiler::cache", { extension, moduleId });
- sendSync(dispatch.OP_CACHE, { extension, moduleId, contents });
-}
-
-const encoder = new TextEncoder();
-
-/** Given a fileName and the data, emit the file to the file system. */
-function emitBundle(fileName: string, data: string): void {
- // For internal purposes, when trying to emit to `$deno$` just no-op
- if (fileName.startsWith("$deno$")) {
- console.warn("skipping emitBundle", fileName);
- return;
- }
- const encodedData = encoder.encode(data);
- console.log(`Emitting bundle to "${fileName}"`);
- writeFileSync(fileName, encodedData);
- console.log(`${humanFileSize(encodedData.length)} emitted.`);
-}
-
-/** Returns the TypeScript Extension enum for a given media type. */
-function getExtension(fileName: string, mediaType: MediaType): ts.Extension {
- switch (mediaType) {
- case MediaType.JavaScript:
- return ts.Extension.Js;
- case MediaType.JSX:
- return ts.Extension.Jsx;
- case MediaType.TypeScript:
- return fileName.endsWith(".d.ts") ? ts.Extension.Dts : ts.Extension.Ts;
- case MediaType.TSX:
- return ts.Extension.Tsx;
- case MediaType.Json:
- return ts.Extension.Json;
- case MediaType.Unknown:
- default:
- throw TypeError("Cannot resolve extension.");
- }
-}
-
-class Host implements ts.CompilerHost {
- private readonly _options: ts.CompilerOptions = {
- allowJs: true,
- allowNonTsExtensions: true,
- checkJs: false,
- esModuleInterop: true,
- module: ts.ModuleKind.ESNext,
- outDir: OUT_DIR,
- resolveJsonModule: true,
- sourceMap: true,
- stripComments: true,
- target: ts.ScriptTarget.ESNext,
- jsx: ts.JsxEmit.React
- };
-
- private _getAsset(filename: string): SourceFile {
- const sourceFile = SourceFile.get(filename);
- if (sourceFile) {
- return sourceFile;
- }
- const url = filename.split("/").pop()!;
- const assetName = url.includes(".") ? url : `${url}.d.ts`;
- const sourceCode = fetchAsset(assetName);
- return new SourceFile({
- url,
- filename,
- mediaType: MediaType.TypeScript,
- sourceCode
- });
- }
-
- /* Deno specific APIs */
-
- /** Provides the `ts.HostCompiler` interface for Deno.
- *
- * @param _bundle Set to a string value to configure the host to write out a
- * bundle instead of caching individual files.
- */
- constructor(private _bundle?: string) {
- if (this._bundle) {
- // options we need to change when we are generating a bundle
- const bundlerOptions: ts.CompilerOptions = {
- module: ts.ModuleKind.AMD,
- inlineSourceMap: true,
- outDir: undefined,
- outFile: `${OUT_DIR}/bundle.js`,
- sourceMap: false
- };
- Object.assign(this._options, bundlerOptions);
- }
- }
-
- /** Take a configuration string, parse it, and use it to merge with the
- * compiler's configuration options. The method returns an array of compiler
- * options which were ignored, or `undefined`. */
- configure(path: string, configurationText: string): ConfigureResponse {
- util.log("compiler::host.configure", path);
- const { config, error } = ts.parseConfigFileTextToJson(
- path,
- configurationText
- );
- if (error) {
- return { diagnostics: [error] };
- }
- const { options, errors } = ts.convertCompilerOptionsFromJson(
- config.compilerOptions,
- cwd()
- );
- const ignoredOptions: string[] = [];
- for (const key of Object.keys(options)) {
- if (
- ignoredCompilerOptions.includes(key) &&
- (!(key in this._options) || options[key] !== this._options[key])
- ) {
- ignoredOptions.push(key);
- delete options[key];
- }
- }
- Object.assign(this._options, options);
- return {
- ignoredOptions: ignoredOptions.length ? ignoredOptions : undefined,
- diagnostics: errors.length ? errors : undefined
- };
- }
-
- /* TypeScript CompilerHost APIs */
-
- fileExists(_fileName: string): boolean {
- return notImplemented();
- }
-
- getCanonicalFileName(fileName: string): string {
- return fileName;
- }
-
- getCompilationSettings(): ts.CompilerOptions {
- util.log("compiler::host.getCompilationSettings()");
- return this._options;
- }
-
- getCurrentDirectory(): string {
- return "";
- }
-
- getDefaultLibFileName(_options: ts.CompilerOptions): string {
- return ASSETS + "/lib.deno_runtime.d.ts";
- }
-
- getNewLine(): string {
- return "\n";
- }
-
- getSourceFile(
- fileName: string,
- languageVersion: ts.ScriptTarget,
- onError?: (message: string) => void,
- shouldCreateNewSourceFile?: boolean
- ): ts.SourceFile | undefined {
- util.log("compiler::host.getSourceFile", fileName);
- try {
- assert(!shouldCreateNewSourceFile);
- const sourceFile = fileName.startsWith(ASSETS)
- ? this._getAsset(fileName)
- : SourceFile.get(fileName);
- assert(sourceFile != null);
- if (!sourceFile!.tsSourceFile) {
- sourceFile!.tsSourceFile = ts.createSourceFile(
- fileName,
- sourceFile!.sourceCode,
- languageVersion
- );
- }
- return sourceFile!.tsSourceFile;
- } catch (e) {
- if (onError) {
- onError(String(e));
- } else {
- throw e;
- }
- return undefined;
- }
- }
-
- readFile(_fileName: string): string | undefined {
- return notImplemented();
- }
-
- resolveModuleNames(
- moduleNames: string[],
- containingFile: string
- ): Array<ts.ResolvedModuleFull | undefined> {
- util.log("compiler::host.resolveModuleNames", {
- moduleNames,
- containingFile
- });
- return moduleNames.map(specifier => {
- const url = SourceFile.getUrl(specifier, containingFile);
- const sourceFile = specifier.startsWith(ASSETS)
- ? this._getAsset(specifier)
- : url
- ? SourceFile.get(url)
- : undefined;
- if (!sourceFile) {
- return undefined;
- }
- return {
- resolvedFileName: sourceFile.url,
- isExternalLibraryImport: specifier.startsWith(ASSETS),
- extension: sourceFile.extension
- };
- });
- }
-
- useCaseSensitiveFileNames(): boolean {
- return true;
- }
-
- writeFile(
- fileName: string,
- data: string,
- _writeByteOrderMark: boolean,
- onError?: (message: string) => void,
- sourceFiles?: readonly ts.SourceFile[]
- ): void {
- util.log("compiler::host.writeFile", fileName);
- try {
- if (this._bundle) {
- emitBundle(this._bundle, data);
- } else {
- assert(sourceFiles != null && sourceFiles.length == 1);
- const url = sourceFiles![0].fileName;
- const sourceFile = SourceFile.get(url);
-
- if (sourceFile) {
- // NOTE: If it's a `.json` file we don't want to write it to disk.
- // JSON files are loaded and used by TS compiler to check types, but we don't want
- // to emit them to disk because output file is the same as input file.
- if (sourceFile.extension === ts.Extension.Json) {
- return;
- }
-
- // NOTE: JavaScript files are only emitted to disk if `checkJs` option in on
- if (
- sourceFile.extension === ts.Extension.Js &&
- !this._options.checkJs
- ) {
- return;
- }
- }
-
- if (fileName.endsWith(".map")) {
- // Source Map
- cache(".map", url, data);
- } else if (fileName.endsWith(".js") || fileName.endsWith(".json")) {
- // Compiled JavaScript
- cache(".js", url, data);
- } else {
- assert(false, "Trying to cache unhandled file type " + fileName);
- }
- }
- } catch (e) {
- if (onError) {
- onError(String(e));
- } else {
- throw e;
- }
- }
- }
-}
-
-// provide the "main" function that will be called by the privileged side when
-// lazy instantiating the compiler web worker
-window.compilerMain = function compilerMain(): void {
- // workerMain should have already been called since a compiler is a worker.
- window.onmessage = async ({ data }: { data: CompilerReq }): Promise<void> => {
- const { rootNames, configPath, config, bundle } = data;
- util.log(">>> compile start", { rootNames, bundle });
-
- // This will recursively analyse all the code for other imports, requesting
- // those from the privileged side, populating the in memory cache which
- // will be used by the host, before resolving.
- await processImports(rootNames.map(rootName => [rootName, rootName]));
-
- const host = new Host(bundle);
- let emitSkipped = true;
- let diagnostics: ts.Diagnostic[] | undefined;
-
- // if there is a configuration supplied, we need to parse that
- if (config && config.length && configPath) {
- const configResult = host.configure(configPath, config);
- const ignoredOptions = configResult.ignoredOptions;
- diagnostics = configResult.diagnostics;
- if (ignoredOptions) {
- console.warn(
- yellow(`Unsupported compiler options in "${configPath}"\n`) +
- cyan(` The following options were ignored:\n`) +
- ` ${ignoredOptions
- .map((value): string => bold(value))
- .join(", ")}`
- );
- }
- }
-
- // if there was a configuration and no diagnostics with it, we will continue
- // to generate the program and possibly emit it.
- if (!diagnostics || (diagnostics && diagnostics.length === 0)) {
- const options = host.getCompilationSettings();
- const program = ts.createProgram(rootNames, options, host);
-
- diagnostics = ts.getPreEmitDiagnostics(program).filter(
- ({ code }): boolean => {
- // TS1308: 'await' expression is only allowed within an async
- // function.
- if (code === 1308) return false;
- // TS2691: An import path cannot end with a '.ts' extension. Consider
- // importing 'bad-module' instead.
- if (code === 2691) return false;
- // TS5009: Cannot find the common subdirectory path for the input files.
- if (code === 5009) return false;
- // TS5055: Cannot write file
- // 'http://localhost:4545/tests/subdir/mt_application_x_javascript.j4.js'
- // because it would overwrite input file.
- if (code === 5055) return false;
- // TypeScript is overly opinionated that only CommonJS modules kinds can
- // support JSON imports. Allegedly this was fixed in
- // Microsoft/TypeScript#26825 but that doesn't seem to be working here,
- // so we will ignore complaints about this compiler setting.
- if (code === 5070) return false;
- return true;
- }
- );
-
- // We will only proceed with the emit if there are no diagnostics.
- if (diagnostics && diagnostics.length === 0) {
- if (bundle) {
- console.log(`Bundling "${bundle}"`);
- }
- const emitResult = program.emit();
- emitSkipped = emitResult.emitSkipped;
- // emitResult.diagnostics is `readonly` in TS3.5+ and can't be assigned
- // without casting.
- diagnostics = emitResult.diagnostics as ts.Diagnostic[];
- }
- }
-
- const result: EmitResult = {
- emitSkipped,
- diagnostics: diagnostics.length
- ? fromTypeScriptDiagnostic(diagnostics)
- : undefined
- };
-
- postMessage(result);
-
- util.log("<<< compile end", { rootNames, bundle });
-
- // The compiler isolate exits after a single message.
- workerClose();
- };
-};
diff --git a/js/console.ts b/js/console.ts
deleted file mode 100644
index 9f0ce4bd6..000000000
--- a/js/console.ts
+++ /dev/null
@@ -1,790 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { isTypedArray } from "./util.ts";
-import { TypedArray } from "./types.ts";
-import { TextEncoder } from "./text_encoding.ts";
-import { File, stdout } from "./files.ts";
-import { cliTable } from "./console_table.ts";
-
-type ConsoleContext = Set<unknown>;
-type ConsoleOptions = Partial<{
- showHidden: boolean;
- depth: number;
- colors: boolean;
- indentLevel: number;
-}>;
-
-// Default depth of logging nested objects
-const DEFAULT_MAX_DEPTH = 4;
-
-// Number of elements an object must have before it's displayed in appreviated
-// form.
-const OBJ_ABBREVIATE_SIZE = 5;
-
-const STR_ABBREVIATE_SIZE = 100;
-
-// Char codes
-const CHAR_PERCENT = 37; /* % */
-const CHAR_LOWERCASE_S = 115; /* s */
-const CHAR_LOWERCASE_D = 100; /* d */
-const CHAR_LOWERCASE_I = 105; /* i */
-const CHAR_LOWERCASE_F = 102; /* f */
-const CHAR_LOWERCASE_O = 111; /* o */
-const CHAR_UPPERCASE_O = 79; /* O */
-const CHAR_LOWERCASE_C = 99; /* c */
-export class CSI {
- static kClear = "\x1b[1;1H";
- static kClearScreenDown = "\x1b[0J";
-}
-
-/* eslint-disable @typescript-eslint/no-use-before-define */
-
-function cursorTo(stream: File, _x: number, _y?: number): void {
- const uint8 = new TextEncoder().encode(CSI.kClear);
- stream.write(uint8);
-}
-
-function clearScreenDown(stream: File): void {
- const uint8 = new TextEncoder().encode(CSI.kClearScreenDown);
- stream.write(uint8);
-}
-
-function getClassInstanceName(instance: unknown): string {
- if (typeof instance !== "object") {
- return "";
- }
- if (!instance) {
- return "";
- }
-
- const proto = Object.getPrototypeOf(instance);
- if (proto && proto.constructor) {
- return proto.constructor.name; // could be "Object" or "Array"
- }
-
- return "";
-}
-
-function createFunctionString(value: Function, _ctx: ConsoleContext): string {
- // Might be Function/AsyncFunction/GeneratorFunction
- const cstrName = Object.getPrototypeOf(value).constructor.name;
- if (value.name && value.name !== "anonymous") {
- // from MDN spec
- return `[${cstrName}: ${value.name}]`;
- }
- return `[${cstrName}]`;
-}
-
-interface IterablePrintConfig<T> {
- typeName: string;
- displayName: string;
- delims: [string, string];
- entryHandler: (
- entry: T,
- ctx: ConsoleContext,
- level: number,
- maxLevel: number
- ) => string;
-}
-
-function createIterableString<T>(
- value: Iterable<T>,
- ctx: ConsoleContext,
- level: number,
- maxLevel: number,
- config: IterablePrintConfig<T>
-): string {
- if (level >= maxLevel) {
- return `[${config.typeName}]`;
- }
- ctx.add(value);
-
- const entries: string[] = [];
- // In cases e.g. Uint8Array.prototype
- try {
- for (const el of value) {
- entries.push(config.entryHandler(el, ctx, level + 1, maxLevel));
- }
- } catch (e) {}
- ctx.delete(value);
- const iPrefix = `${config.displayName ? config.displayName + " " : ""}`;
- const iContent = entries.length === 0 ? "" : ` ${entries.join(", ")} `;
- return `${iPrefix}${config.delims[0]}${iContent}${config.delims[1]}`;
-}
-
-function stringify(
- value: unknown,
- ctx: ConsoleContext,
- level: number,
- maxLevel: number
-): string {
- switch (typeof value) {
- case "string":
- return value;
- case "number":
- // Special handling of -0
- return Object.is(value, -0) ? "-0" : `${value}`;
- case "boolean":
- case "undefined":
- case "symbol":
- return String(value);
- case "bigint":
- return `${value}n`;
- case "function":
- return createFunctionString(value as Function, ctx);
- case "object":
- if (value === null) {
- return "null";
- }
-
- if (ctx.has(value)) {
- return "[Circular]";
- }
-
- return createObjectString(value, ctx, level, maxLevel);
- default:
- return "[Not Implemented]";
- }
-}
-
-// Print strings when they are inside of arrays or objects with quotes
-function stringifyWithQuotes(
- value: unknown,
- ctx: ConsoleContext,
- level: number,
- maxLevel: number
-): string {
- switch (typeof value) {
- case "string":
- const trunc =
- value.length > STR_ABBREVIATE_SIZE
- ? value.slice(0, STR_ABBREVIATE_SIZE) + "..."
- : value;
- return JSON.stringify(trunc);
- default:
- return stringify(value, ctx, level, maxLevel);
- }
-}
-
-function createArrayString(
- value: unknown[],
- ctx: ConsoleContext,
- level: number,
- maxLevel: number
-): string {
- const printConfig: IterablePrintConfig<unknown> = {
- typeName: "Array",
- displayName: "",
- delims: ["[", "]"],
- entryHandler: (el, ctx, level, maxLevel): string =>
- stringifyWithQuotes(el, ctx, level + 1, maxLevel)
- };
- return createIterableString(value, ctx, level, maxLevel, printConfig);
-}
-
-function createTypedArrayString(
- typedArrayName: string,
- value: TypedArray,
- ctx: ConsoleContext,
- level: number,
- maxLevel: number
-): string {
- const printConfig: IterablePrintConfig<unknown> = {
- typeName: typedArrayName,
- displayName: typedArrayName,
- delims: ["[", "]"],
- entryHandler: (el, ctx, level, maxLevel): string =>
- stringifyWithQuotes(el, ctx, level + 1, maxLevel)
- };
- return createIterableString(value, ctx, level, maxLevel, printConfig);
-}
-
-function createSetString(
- value: Set<unknown>,
- ctx: ConsoleContext,
- level: number,
- maxLevel: number
-): string {
- const printConfig: IterablePrintConfig<unknown> = {
- typeName: "Set",
- displayName: "Set",
- delims: ["{", "}"],
- entryHandler: (el, ctx, level, maxLevel): string =>
- stringifyWithQuotes(el, ctx, level + 1, maxLevel)
- };
- return createIterableString(value, ctx, level, maxLevel, printConfig);
-}
-
-function createMapString(
- value: Map<unknown, unknown>,
- ctx: ConsoleContext,
- level: number,
- maxLevel: number
-): string {
- const printConfig: IterablePrintConfig<[unknown, unknown]> = {
- typeName: "Map",
- displayName: "Map",
- delims: ["{", "}"],
- entryHandler: (el, ctx, level, maxLevel): string => {
- const [key, val] = el;
- return `${stringifyWithQuotes(
- key,
- ctx,
- level + 1,
- maxLevel
- )} => ${stringifyWithQuotes(val, ctx, level + 1, maxLevel)}`;
- }
- };
- return createIterableString(value, ctx, level, maxLevel, printConfig);
-}
-
-function createWeakSetString(): string {
- return "WeakSet { [items unknown] }"; // as seen in Node
-}
-
-function createWeakMapString(): string {
- return "WeakMap { [items unknown] }"; // as seen in Node
-}
-
-function createDateString(value: Date): string {
- // without quotes, ISO format
- return value.toISOString();
-}
-
-function createRegExpString(value: RegExp): string {
- return value.toString();
-}
-
-/* eslint-disable @typescript-eslint/ban-types */
-
-function createStringWrapperString(value: String): string {
- return `[String: "${value.toString()}"]`;
-}
-
-function createBooleanWrapperString(value: Boolean): string {
- return `[Boolean: ${value.toString()}]`;
-}
-
-function createNumberWrapperString(value: Number): string {
- return `[Number: ${value.toString()}]`;
-}
-
-/* eslint-enable @typescript-eslint/ban-types */
-
-// TODO: Promise, requires v8 bindings to get info
-// TODO: Proxy
-
-function createRawObjectString(
- value: { [key: string]: unknown },
- ctx: ConsoleContext,
- level: number,
- maxLevel: number
-): string {
- if (level >= maxLevel) {
- return "[Object]";
- }
- ctx.add(value);
-
- let baseString = "";
-
- const className = getClassInstanceName(value);
- let shouldShowClassName = false;
- if (className && className !== "Object" && className !== "anonymous") {
- shouldShowClassName = true;
- }
- const keys = Object.keys(value);
- const entries: string[] = keys.map(
- (key): string => {
- if (keys.length > OBJ_ABBREVIATE_SIZE) {
- return key;
- } else {
- return `${key}: ${stringifyWithQuotes(
- value[key],
- ctx,
- level + 1,
- maxLevel
- )}`;
- }
- }
- );
-
- ctx.delete(value);
-
- if (entries.length === 0) {
- baseString = "{}";
- } else {
- baseString = `{ ${entries.join(", ")} }`;
- }
-
- if (shouldShowClassName) {
- baseString = `${className} ${baseString}`;
- }
-
- return baseString;
-}
-
-function createObjectString(
- value: {},
- ...args: [ConsoleContext, number, number]
-): string {
- if (customInspect in value && typeof value[customInspect] === "function") {
- return String(value[customInspect]!());
- } else if (value instanceof Error) {
- return String(value.stack);
- } else if (Array.isArray(value)) {
- return createArrayString(value, ...args);
- } else if (value instanceof Number) {
- return createNumberWrapperString(value);
- } else if (value instanceof Boolean) {
- return createBooleanWrapperString(value);
- } else if (value instanceof String) {
- return createStringWrapperString(value);
- } else if (value instanceof RegExp) {
- return createRegExpString(value);
- } else if (value instanceof Date) {
- return createDateString(value);
- } else if (value instanceof Set) {
- return createSetString(value, ...args);
- } else if (value instanceof Map) {
- return createMapString(value, ...args);
- } else if (value instanceof WeakSet) {
- return createWeakSetString();
- } else if (value instanceof WeakMap) {
- return createWeakMapString();
- } else if (isTypedArray(value)) {
- return createTypedArrayString(
- Object.getPrototypeOf(value).constructor.name,
- value,
- ...args
- );
- } else {
- // Otherwise, default object formatting
- return createRawObjectString(value, ...args);
- }
-}
-
-/** TODO Do not expose this from "deno" namespace.
- * @internal
- */
-export function stringifyArgs(
- args: unknown[],
- options: ConsoleOptions = {}
-): string {
- const first = args[0];
- let a = 0;
- let str = "";
- let join = "";
-
- if (typeof first === "string") {
- let tempStr: string;
- let lastPos = 0;
-
- for (let i = 0; i < first.length - 1; i++) {
- if (first.charCodeAt(i) === CHAR_PERCENT) {
- const nextChar = first.charCodeAt(++i);
- if (a + 1 !== args.length) {
- switch (nextChar) {
- case CHAR_LOWERCASE_S:
- // format as a string
- tempStr = String(args[++a]);
- break;
- case CHAR_LOWERCASE_D:
- case CHAR_LOWERCASE_I:
- // format as an integer
- const tempInteger = args[++a];
- if (typeof tempInteger === "bigint") {
- tempStr = `${tempInteger}n`;
- } else if (typeof tempInteger === "symbol") {
- tempStr = "NaN";
- } else {
- tempStr = `${parseInt(String(tempInteger), 10)}`;
- }
- break;
- case CHAR_LOWERCASE_F:
- // format as a floating point value
- const tempFloat = args[++a];
- if (typeof tempFloat === "symbol") {
- tempStr = "NaN";
- } else {
- tempStr = `${parseFloat(String(tempFloat))}`;
- }
- break;
- case CHAR_LOWERCASE_O:
- case CHAR_UPPERCASE_O:
- // format as an object
- tempStr = stringify(
- args[++a],
- new Set<unknown>(),
- 0,
- options.depth != undefined ? options.depth : DEFAULT_MAX_DEPTH
- );
- break;
- case CHAR_PERCENT:
- str += first.slice(lastPos, i);
- lastPos = i + 1;
- continue;
- case CHAR_LOWERCASE_C:
- // TODO: applies CSS style rules to the output string as specified
- continue;
- default:
- // any other character is not a correct placeholder
- continue;
- }
-
- if (lastPos !== i - 1) {
- str += first.slice(lastPos, i - 1);
- }
-
- str += tempStr;
- lastPos = i + 1;
- } else if (nextChar === CHAR_PERCENT) {
- str += first.slice(lastPos, i);
- lastPos = i + 1;
- }
- }
- }
-
- if (lastPos !== 0) {
- a++;
- join = " ";
- if (lastPos < first.length) {
- str += first.slice(lastPos);
- }
- }
- }
-
- while (a < args.length) {
- const value = args[a];
- str += join;
- if (typeof value === "string") {
- str += value;
- } else {
- // use default maximum depth for null or undefined argument
- str += stringify(
- value,
- new Set<unknown>(),
- 0,
- options.depth != undefined ? options.depth : DEFAULT_MAX_DEPTH
- );
- }
- join = " ";
- a++;
- }
-
- const { indentLevel } = options;
- if (indentLevel != null && indentLevel > 0) {
- const groupIndent = " ".repeat(indentLevel);
- if (str.indexOf("\n") !== -1) {
- str = str.replace(/\n/g, `\n${groupIndent}`);
- }
- str = groupIndent + str;
- }
-
- return str;
-}
-
-type PrintFunc = (x: string, isErr?: boolean) => void;
-
-const countMap = new Map<string, number>();
-const timerMap = new Map<string, number>();
-const isConsoleInstance = Symbol("isConsoleInstance");
-
-export class Console {
- indentLevel: number;
- [isConsoleInstance] = false;
-
- /** @internal */
- constructor(private printFunc: PrintFunc) {
- this.indentLevel = 0;
- this[isConsoleInstance] = true;
-
- // ref https://console.spec.whatwg.org/#console-namespace
- // For historical web-compatibility reasons, the namespace object for
- // console must have as its [[Prototype]] an empty object, created as if
- // by ObjectCreate(%ObjectPrototype%), instead of %ObjectPrototype%.
- const console = Object.create({}) as Console;
- Object.assign(console, this);
- return console;
- }
-
- /** Writes the arguments to stdout */
- log = (...args: unknown[]): void => {
- this.printFunc(
- stringifyArgs(args, {
- indentLevel: this.indentLevel
- }) + "\n",
- false
- );
- };
-
- /** Writes the arguments to stdout */
- debug = this.log;
- /** Writes the arguments to stdout */
- info = this.log;
-
- /** Writes the properties of the supplied `obj` to stdout */
- dir = (obj: unknown, options: ConsoleOptions = {}): void => {
- this.printFunc(stringifyArgs([obj], options) + "\n", false);
- };
-
- /** 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 = this.dir;
-
- /** Writes the arguments to stdout */
- warn = (...args: unknown[]): void => {
- this.printFunc(
- stringifyArgs(args, {
- indentLevel: this.indentLevel
- }) + "\n",
- true
- );
- };
-
- /** Writes the arguments to stdout */
- error = this.warn;
-
- /** 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 = false, ...args: unknown[]): void => {
- if (condition) {
- return;
- }
-
- if (args.length === 0) {
- this.error("Assertion failed");
- return;
- }
-
- const [first, ...rest] = args;
-
- if (typeof first === "string") {
- this.error(`Assertion failed: ${first}`, ...rest);
- return;
- }
-
- this.error(`Assertion failed:`, ...args);
- };
-
- count = (label = "default"): void => {
- label = String(label);
-
- if (countMap.has(label)) {
- const current = countMap.get(label) || 0;
- countMap.set(label, current + 1);
- } else {
- countMap.set(label, 1);
- }
-
- this.info(`${label}: ${countMap.get(label)}`);
- };
-
- countReset = (label = "default"): void => {
- label = String(label);
-
- if (countMap.has(label)) {
- countMap.set(label, 0);
- } else {
- this.warn(`Count for '${label}' does not exist`);
- }
- };
-
- table = (data: unknown, properties?: string[]): void => {
- if (properties !== undefined && !Array.isArray(properties)) {
- throw new Error(
- "The 'properties' argument must be of type Array. " +
- "Received type string"
- );
- }
-
- if (data === null || typeof data !== "object") {
- return this.log(data);
- }
-
- const objectValues: { [key: string]: string[] } = {};
- const indexKeys: string[] = [];
- const values: string[] = [];
-
- const stringifyValue = (value: unknown): string =>
- stringifyWithQuotes(value, new Set<unknown>(), 0, 1);
- const toTable = (header: string[], body: string[][]): void =>
- this.log(cliTable(header, body));
- const createColumn = (value: unknown, shift?: number): string[] => [
- ...(shift ? [...new Array(shift)].map((): string => "") : []),
- stringifyValue(value)
- ];
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- let resultData: any;
- const isSet = data instanceof Set;
- const isMap = data instanceof Map;
- const valuesKey = "Values";
- const indexKey = isSet || isMap ? "(iteration index)" : "(index)";
-
- if (data instanceof Set) {
- resultData = [...data];
- } else if (data instanceof Map) {
- let idx = 0;
- resultData = {};
-
- data.forEach(
- (v: unknown, k: unknown): void => {
- resultData[idx] = { Key: k, Values: v };
- idx++;
- }
- );
- } else {
- resultData = data!;
- }
-
- Object.keys(resultData).forEach(
- (k, idx): void => {
- const value: unknown = resultData[k]!;
-
- if (value !== null && typeof value === "object") {
- Object.entries(value as { [key: string]: unknown }).forEach(
- ([k, v]): void => {
- if (properties && !properties.includes(k)) {
- return;
- }
-
- if (objectValues[k]) {
- objectValues[k].push(stringifyValue(v));
- } else {
- objectValues[k] = createColumn(v, idx);
- }
- }
- );
-
- values.push("");
- } else {
- values.push(stringifyValue(value));
- }
-
- indexKeys.push(k);
- }
- );
-
- const headerKeys = Object.keys(objectValues);
- const bodyValues = Object.values(objectValues);
- const header = [
- indexKey,
- ...(properties || [
- ...headerKeys,
- !isMap && values.length > 0 && valuesKey
- ])
- ].filter(Boolean) as string[];
- const body = [indexKeys, ...bodyValues, values];
-
- toTable(header, body);
- };
-
- time = (label = "default"): void => {
- label = String(label);
-
- if (timerMap.has(label)) {
- this.warn(`Timer '${label}' already exists`);
- return;
- }
-
- timerMap.set(label, Date.now());
- };
-
- timeLog = (label = "default", ...args: unknown[]): void => {
- label = String(label);
-
- if (!timerMap.has(label)) {
- this.warn(`Timer '${label}' does not exists`);
- return;
- }
-
- const startTime = timerMap.get(label) as number;
- const duration = Date.now() - startTime;
-
- this.info(`${label}: ${duration}ms`, ...args);
- };
-
- timeEnd = (label = "default"): void => {
- label = String(label);
-
- if (!timerMap.has(label)) {
- this.warn(`Timer '${label}' does not exists`);
- return;
- }
-
- const startTime = timerMap.get(label) as number;
- timerMap.delete(label);
- const duration = Date.now() - startTime;
-
- this.info(`${label}: ${duration}ms`);
- };
-
- group = (...label: unknown[]): void => {
- if (label.length > 0) {
- this.log(...label);
- }
- this.indentLevel += 2;
- };
-
- groupCollapsed = this.group;
-
- groupEnd = (): void => {
- if (this.indentLevel > 0) {
- this.indentLevel -= 2;
- }
- };
-
- clear = (): void => {
- this.indentLevel = 0;
- cursorTo(stdout, 0, 0);
- clearScreenDown(stdout);
- };
-
- trace = (...args: unknown[]): void => {
- const message = stringifyArgs(args, { indentLevel: 0 });
- const err = {
- name: "Trace",
- message
- };
- // @ts-ignore
- Error.captureStackTrace(err, this.trace);
- this.error((err as Error).stack);
- };
-
- static [Symbol.hasInstance](instance: Console): boolean {
- return instance[isConsoleInstance];
- }
-}
-
-/** 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 = Symbol.for("Deno.customInspect");
-
-/**
- * `inspect()` converts input into string that has the same format
- * as printed by `console.log(...)`;
- */
-export function inspect(value: unknown, options?: ConsoleOptions): string {
- const opts = options || {};
- if (typeof value === "string") {
- return value;
- } else {
- return stringify(
- value,
- new Set<unknown>(),
- 0,
- opts.depth != undefined ? opts.depth : DEFAULT_MAX_DEPTH
- );
- }
-}
diff --git a/js/console_table.ts b/js/console_table.ts
deleted file mode 100644
index d74dc0127..000000000
--- a/js/console_table.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright Joyent, Inc. and other Node contributors. MIT license.
-// Forked from Node's lib/internal/cli_table.js
-
-import { TextEncoder } from "./text_encoding.ts";
-import { hasOwnProperty } from "./util.ts";
-
-const encoder = new TextEncoder();
-
-const tableChars = {
- middleMiddle: "─",
- rowMiddle: "┼",
- topRight: "┐",
- topLeft: "┌",
- leftMiddle: "├",
- topMiddle: "┬",
- bottomRight: "┘",
- bottomLeft: "└",
- bottomMiddle: "┴",
- rightMiddle: "┤",
- left: "│ ",
- right: " │",
- middle: " │ "
-};
-
-const colorRegExp = /\u001b\[\d\d?m/g;
-
-function removeColors(str: string): string {
- return str.replace(colorRegExp, "");
-}
-
-function countBytes(str: string): number {
- const normalized = removeColors(String(str)).normalize("NFC");
-
- return encoder.encode(normalized).byteLength;
-}
-
-function renderRow(row: string[], columnWidths: number[]): string {
- let out = tableChars.left;
- for (let i = 0; i < row.length; i++) {
- const cell = row[i];
- const len = countBytes(cell);
- const needed = (columnWidths[i] - len) / 2;
- // round(needed) + ceil(needed) will always add up to the amount
- // of spaces we need while also left justifying the output.
- out += `${" ".repeat(needed)}${cell}${" ".repeat(Math.ceil(needed))}`;
- if (i !== row.length - 1) {
- out += tableChars.middle;
- }
- }
- out += tableChars.right;
- return out;
-}
-
-export function cliTable(head: string[], columns: string[][]): string {
- const rows: string[][] = [];
- const columnWidths = head.map((h: string): number => countBytes(h));
- const longestColumn = columns.reduce(
- (n: number, a: string[]): number => Math.max(n, a.length),
- 0
- );
-
- for (let i = 0; i < head.length; i++) {
- const column = columns[i];
- for (let j = 0; j < longestColumn; j++) {
- if (rows[j] === undefined) {
- rows[j] = [];
- }
- const value = (rows[j][i] = hasOwnProperty(column, j) ? column[j] : "");
- const width = columnWidths[i] || 0;
- const counted = countBytes(value);
- columnWidths[i] = Math.max(width, counted);
- }
- }
-
- const divider = columnWidths.map(
- (i: number): string => tableChars.middleMiddle.repeat(i + 2)
- );
-
- let result =
- `${tableChars.topLeft}${divider.join(tableChars.topMiddle)}` +
- `${tableChars.topRight}\n${renderRow(head, columnWidths)}\n` +
- `${tableChars.leftMiddle}${divider.join(tableChars.rowMiddle)}` +
- `${tableChars.rightMiddle}\n`;
-
- for (const row of rows) {
- result += `${renderRow(row, columnWidths)}\n`;
- }
-
- result +=
- `${tableChars.bottomLeft}${divider.join(tableChars.bottomMiddle)}` +
- tableChars.bottomRight;
-
- return result;
-}
diff --git a/js/console_test.ts b/js/console_test.ts
deleted file mode 100644
index 903e65a82..000000000
--- a/js/console_test.ts
+++ /dev/null
@@ -1,698 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { assert, assertEquals, test } from "./test_util.ts";
-
-// Some of these APIs aren't exposed in the types and so we have to cast to any
-// in order to "trick" TypeScript.
-const {
- Console,
- customInspect,
- stringifyArgs,
- inspect,
- write,
- stdout
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
-} = Deno as any;
-
-function stringify(...args: unknown[]): string {
- return stringifyArgs(args).replace(/\n$/, "");
-}
-
-// test cases from web-platform-tests
-// via https://github.com/web-platform-tests/wpt/blob/master/console/console-is-a-namespace.any.js
-test(function consoleShouldBeANamespace(): void {
- const prototype1 = Object.getPrototypeOf(console);
- const prototype2 = Object.getPrototypeOf(prototype1);
-
- assertEquals(Object.getOwnPropertyNames(prototype1).length, 0);
- assertEquals(prototype2, Object.prototype);
-});
-
-test(function consoleHasRightInstance(): void {
- assert(console instanceof Console);
- assertEquals({} instanceof Console, false);
-});
-
-test(function consoleTestAssertShouldNotThrowError(): void {
- console.assert(true);
-
- let hasThrown = undefined;
- try {
- console.assert(false);
- hasThrown = false;
- } catch {
- hasThrown = true;
- }
- assertEquals(hasThrown, false);
-});
-
-test(function consoleTestStringifyComplexObjects(): void {
- assertEquals(stringify("foo"), "foo");
- assertEquals(stringify(["foo", "bar"]), `[ "foo", "bar" ]`);
- assertEquals(stringify({ foo: "bar" }), `{ foo: "bar" }`);
-});
-
-test(function consoleTestStringifyLongStrings(): void {
- const veryLongString = "a".repeat(200);
- // If we stringify an object containing the long string, it gets abbreviated.
- let actual = stringify({ veryLongString });
- assert(actual.includes("..."));
- assert(actual.length < 200);
- // However if we stringify the string itself, we get it exactly.
- actual = stringify(veryLongString);
- assertEquals(actual, veryLongString);
-});
-
-/* eslint-disable @typescript-eslint/explicit-function-return-type */
-test(function consoleTestStringifyCircular(): void {
- class Base {
- a = 1;
- m1() {}
- }
-
- class Extended extends Base {
- b = 2;
- m2() {}
- }
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const nestedObj: any = {
- num: 1,
- bool: true,
- str: "a",
- method() {},
- async asyncMethod() {},
- *generatorMethod() {},
- un: undefined,
- nu: null,
- arrowFunc: () => {},
- extendedClass: new Extended(),
- nFunc: new Function(),
- extendedCstr: Extended
- };
-
- const circularObj = {
- num: 2,
- bool: false,
- str: "b",
- method() {},
- un: undefined,
- nu: null,
- nested: nestedObj,
- emptyObj: {},
- arr: [1, "s", false, null, nestedObj],
- baseClass: new Base()
- };
-
- nestedObj.o = circularObj;
- const nestedObjExpected = `{ num, bool, str, method, asyncMethod, generatorMethod, un, nu, arrowFunc, extendedClass, nFunc, extendedCstr, o }`;
-
- assertEquals(stringify(1), "1");
- assertEquals(stringify(-0), "-0");
- assertEquals(stringify(1n), "1n");
- assertEquals(stringify("s"), "s");
- assertEquals(stringify(false), "false");
- assertEquals(stringify(new Number(1)), "[Number: 1]");
- assertEquals(stringify(new Boolean(true)), "[Boolean: true]");
- assertEquals(stringify(new String("deno")), `[String: "deno"]`);
- assertEquals(stringify(/[0-9]*/), "/[0-9]*/");
- assertEquals(
- stringify(new Date("2018-12-10T02:26:59.002Z")),
- "2018-12-10T02:26:59.002Z"
- );
- assertEquals(stringify(new Set([1, 2, 3])), "Set { 1, 2, 3 }");
- assertEquals(
- stringify(new Map([[1, "one"], [2, "two"]])),
- `Map { 1 => "one", 2 => "two" }`
- );
- assertEquals(stringify(new WeakSet()), "WeakSet { [items unknown] }");
- assertEquals(stringify(new WeakMap()), "WeakMap { [items unknown] }");
- assertEquals(stringify(Symbol(1)), "Symbol(1)");
- assertEquals(stringify(null), "null");
- assertEquals(stringify(undefined), "undefined");
- assertEquals(stringify(new Extended()), "Extended { a: 1, b: 2 }");
- assertEquals(stringify(function f(): void {}), "[Function: f]");
- assertEquals(
- stringify(async function af(): Promise<void> {}),
- "[AsyncFunction: af]"
- );
- assertEquals(stringify(function* gf() {}), "[GeneratorFunction: gf]");
- assertEquals(
- stringify(async function* agf() {}),
- "[AsyncGeneratorFunction: agf]"
- );
- assertEquals(stringify(new Uint8Array([1, 2, 3])), "Uint8Array [ 1, 2, 3 ]");
- assertEquals(stringify(Uint8Array.prototype), "TypedArray []");
- assertEquals(
- stringify({ a: { b: { c: { d: new Set([1]) } } } }),
- "{ a: { b: { c: { d: [Set] } } } }"
- );
- assertEquals(stringify(nestedObj), nestedObjExpected);
- assertEquals(stringify(JSON), "{}");
- assertEquals(
- stringify(console),
- "{ printFunc, log, debug, info, dir, dirxml, warn, error, assert, count, countReset, table, time, timeLog, timeEnd, group, groupCollapsed, groupEnd, clear, trace, indentLevel }"
- );
- // test inspect is working the same
- assertEquals(inspect(nestedObj), nestedObjExpected);
-});
-/* eslint-enable @typescript-eslint/explicit-function-return-type */
-
-test(function consoleTestStringifyWithDepth(): void {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const nestedObj: any = { a: { b: { c: { d: { e: { f: 42 } } } } } };
- assertEquals(
- stringifyArgs([nestedObj], { depth: 3 }),
- "{ a: { b: { c: [Object] } } }"
- );
- assertEquals(
- stringifyArgs([nestedObj], { depth: 4 }),
- "{ a: { b: { c: { d: [Object] } } } }"
- );
- assertEquals(stringifyArgs([nestedObj], { depth: 0 }), "[Object]");
- assertEquals(
- stringifyArgs([nestedObj], { depth: null }),
- "{ a: { b: { c: { d: [Object] } } } }"
- );
- // test inspect is working the same way
- assertEquals(
- inspect(nestedObj, { depth: 4 }),
- "{ a: { b: { c: { d: [Object] } } } }"
- );
-});
-
-test(function consoleTestWithCustomInspector(): void {
- class A {
- [customInspect](): string {
- return "b";
- }
- }
-
- assertEquals(stringify(new A()), "b");
-});
-
-test(function consoleTestWithIntegerFormatSpecifier(): void {
- assertEquals(stringify("%i"), "%i");
- assertEquals(stringify("%i", 42.0), "42");
- assertEquals(stringify("%i", 42), "42");
- assertEquals(stringify("%i", "42"), "42");
- assertEquals(stringify("%i", "42.0"), "42");
- assertEquals(stringify("%i", 1.5), "1");
- assertEquals(stringify("%i", -0.5), "0");
- assertEquals(stringify("%i", ""), "NaN");
- assertEquals(stringify("%i", Symbol()), "NaN");
- assertEquals(stringify("%i %d", 42, 43), "42 43");
- assertEquals(stringify("%d %i", 42), "42 %i");
- assertEquals(stringify("%d", 12345678901234567890123), "1");
- assertEquals(
- stringify("%i", 12345678901234567890123n),
- "12345678901234567890123n"
- );
-});
-
-test(function consoleTestWithFloatFormatSpecifier(): void {
- assertEquals(stringify("%f"), "%f");
- assertEquals(stringify("%f", 42.0), "42");
- assertEquals(stringify("%f", 42), "42");
- assertEquals(stringify("%f", "42"), "42");
- assertEquals(stringify("%f", "42.0"), "42");
- assertEquals(stringify("%f", 1.5), "1.5");
- assertEquals(stringify("%f", -0.5), "-0.5");
- assertEquals(stringify("%f", Math.PI), "3.141592653589793");
- assertEquals(stringify("%f", ""), "NaN");
- assertEquals(stringify("%f", Symbol("foo")), "NaN");
- assertEquals(stringify("%f", 5n), "5");
- assertEquals(stringify("%f %f", 42, 43), "42 43");
- assertEquals(stringify("%f %f", 42), "42 %f");
-});
-
-test(function consoleTestWithStringFormatSpecifier(): void {
- assertEquals(stringify("%s"), "%s");
- assertEquals(stringify("%s", undefined), "undefined");
- assertEquals(stringify("%s", "foo"), "foo");
- assertEquals(stringify("%s", 42), "42");
- assertEquals(stringify("%s", "42"), "42");
- assertEquals(stringify("%s %s", 42, 43), "42 43");
- assertEquals(stringify("%s %s", 42), "42 %s");
- assertEquals(stringify("%s", Symbol("foo")), "Symbol(foo)");
-});
-
-test(function consoleTestWithObjectFormatSpecifier(): void {
- assertEquals(stringify("%o"), "%o");
- assertEquals(stringify("%o", 42), "42");
- assertEquals(stringify("%o", "foo"), "foo");
- assertEquals(stringify("o: %o, a: %O", {}, []), "o: {}, a: []");
- assertEquals(stringify("%o", { a: 42 }), "{ a: 42 }");
- assertEquals(
- stringify("%o", { a: { b: { c: { d: new Set([1]) } } } }),
- "{ a: { b: { c: { d: [Set] } } } }"
- );
-});
-
-test(function consoleTestWithVariousOrInvalidFormatSpecifier(): void {
- assertEquals(stringify("%s:%s"), "%s:%s");
- assertEquals(stringify("%i:%i"), "%i:%i");
- assertEquals(stringify("%d:%d"), "%d:%d");
- assertEquals(stringify("%%s%s", "foo"), "%sfoo");
- assertEquals(stringify("%s:%s", undefined), "undefined:%s");
- assertEquals(stringify("%s:%s", "foo", "bar"), "foo:bar");
- assertEquals(stringify("%s:%s", "foo", "bar", "baz"), "foo:bar baz");
- assertEquals(stringify("%%%s%%", "hi"), "%hi%");
- assertEquals(stringify("%d:%d", 12), "12:%d");
- assertEquals(stringify("%i:%i", 12), "12:%i");
- assertEquals(stringify("%f:%f", 12), "12:%f");
- assertEquals(stringify("o: %o, a: %o", {}), "o: {}, a: %o");
- assertEquals(stringify("abc%", 1), "abc% 1");
-});
-
-test(function consoleTestCallToStringOnLabel(): void {
- const methods = ["count", "countReset", "time", "timeLog", "timeEnd"];
-
- for (const method of methods) {
- let hasCalled = false;
-
- console[method]({
- toString(): void {
- hasCalled = true;
- }
- });
-
- assertEquals(hasCalled, true);
- }
-});
-
-test(function consoleTestError(): void {
- class MyError extends Error {
- constructor(errStr: string) {
- super(errStr);
- this.name = "MyError";
- }
- }
- try {
- throw new MyError("This is an error");
- } catch (e) {
- assert(
- stringify(e)
- .split("\n")[0] // error has been caught
- .includes("MyError: This is an error")
- );
- }
-});
-
-test(function consoleTestClear(): void {
- const stdoutWrite = stdout.write;
- const uint8 = new TextEncoder().encode("\x1b[1;1H" + "\x1b[0J");
- let buffer = new Uint8Array(0);
-
- stdout.write = async (u8: Uint8Array): Promise<number> => {
- const tmp = new Uint8Array(buffer.length + u8.length);
- tmp.set(buffer, 0);
- tmp.set(u8, buffer.length);
- buffer = tmp;
-
- return await write(stdout.rid, u8);
- };
- console.clear();
- stdout.write = stdoutWrite;
- assertEquals(buffer, uint8);
-});
-
-// Test bound this issue
-test(function consoleDetachedLog(): void {
- const log = console.log;
- const dir = console.dir;
- const dirxml = console.dirxml;
- const debug = console.debug;
- const info = console.info;
- const warn = console.warn;
- const error = console.error;
- const consoleAssert = console.assert;
- const consoleCount = console.count;
- const consoleCountReset = console.countReset;
- const consoleTable = console.table;
- const consoleTime = console.time;
- const consoleTimeLog = console.timeLog;
- const consoleTimeEnd = console.timeEnd;
- const consoleGroup = console.group;
- const consoleGroupEnd = console.groupEnd;
- const consoleClear = console.clear;
- log("Hello world");
- dir("Hello world");
- dirxml("Hello world");
- debug("Hello world");
- info("Hello world");
- warn("Hello world");
- error("Hello world");
- consoleAssert(true);
- consoleCount("Hello world");
- consoleCountReset("Hello world");
- consoleTable({ test: "Hello world" });
- consoleTime("Hello world");
- consoleTimeLog("Hello world");
- consoleTimeEnd("Hello world");
- consoleGroup("Hello world");
- consoleGroupEnd();
- consoleClear();
-});
-
-class StringBuffer {
- chunks: string[] = [];
- add(x: string): void {
- this.chunks.push(x);
- }
- toString(): string {
- return this.chunks.join("");
- }
-}
-
-type ConsoleExamineFunc = (
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- csl: any,
- out: StringBuffer,
- err?: StringBuffer,
- both?: StringBuffer
-) => void;
-
-function mockConsole(f: ConsoleExamineFunc): void {
- const out = new StringBuffer();
- const err = new StringBuffer();
- const both = new StringBuffer();
- const csl = new Console(
- (x: string, isErr: boolean, printsNewLine: boolean): void => {
- const content = x + (printsNewLine ? "\n" : "");
- const buf = isErr ? err : out;
- buf.add(content);
- both.add(content);
- }
- );
- f(csl, out, err, both);
-}
-
-// console.group test
-test(function consoleGroup(): void {
- mockConsole(
- (console, out): void => {
- console.group("1");
- console.log("2");
- console.group("3");
- console.log("4");
- console.groupEnd();
- console.groupEnd();
- console.log("5");
- console.log("6");
-
- assertEquals(
- out.toString(),
- `1
- 2
- 3
- 4
-5
-6
-`
- );
- }
- );
-});
-
-// console.group with console.warn test
-test(function consoleGroupWarn(): void {
- mockConsole(
- (console, _out, _err, both): void => {
- console.warn("1");
- console.group();
- console.warn("2");
- console.group();
- console.warn("3");
- console.groupEnd();
- console.warn("4");
- console.groupEnd();
- console.warn("5");
-
- console.warn("6");
- console.warn("7");
- assertEquals(
- both.toString(),
- `1
- 2
- 3
- 4
-5
-6
-7
-`
- );
- }
- );
-});
-
-// console.table test
-test(function consoleTable(): void {
- mockConsole(
- (console, out): void => {
- console.table({ a: "test", b: 1 });
- assertEquals(
- out.toString(),
- `┌─────────┬────────┐
-│ (index) │ Values │
-├─────────┼────────┤
-│ a │ "test" │
-│ b │ 1 │
-└─────────┴────────┘
-`
- );
- }
- );
- mockConsole(
- (console, out): void => {
- console.table({ a: { b: 10 }, b: { b: 20, c: 30 } }, ["c"]);
- assertEquals(
- out.toString(),
- `┌─────────┬────┐
-│ (index) │ c │
-├─────────┼────┤
-│ a │ │
-│ b │ 30 │
-└─────────┴────┘
-`
- );
- }
- );
- mockConsole(
- (console, out): void => {
- console.table([1, 2, [3, [4]], [5, 6], [[7], [8]]]);
- assertEquals(
- out.toString(),
- `┌─────────┬───────┬───────┬────────┐
-│ (index) │ 0 │ 1 │ Values │
-├─────────┼───────┼───────┼────────┤
-│ 0 │ │ │ 1 │
-│ 1 │ │ │ 2 │
-│ 2 │ 3 │ [ 4 ] │ │
-│ 3 │ 5 │ 6 │ │
-│ 4 │ [ 7 ] │ [ 8 ] │ │
-└─────────┴───────┴───────┴────────┘
-`
- );
- }
- );
- mockConsole(
- (console, out): void => {
- console.table(new Set([1, 2, 3, "test"]));
- assertEquals(
- out.toString(),
- `┌───────────────────┬────────┐
-│ (iteration index) │ Values │
-├───────────────────┼────────┤
-│ 0 │ 1 │
-│ 1 │ 2 │
-│ 2 │ 3 │
-│ 3 │ "test" │
-└───────────────────┴────────┘
-`
- );
- }
- );
- mockConsole(
- (console, out): void => {
- console.table(new Map([[1, "one"], [2, "two"]]));
- assertEquals(
- out.toString(),
- `┌───────────────────┬─────┬────────┐
-│ (iteration index) │ Key │ Values │
-├───────────────────┼─────┼────────┤
-│ 0 │ 1 │ "one" │
-│ 1 │ 2 │ "two" │
-└───────────────────┴─────┴────────┘
-`
- );
- }
- );
- mockConsole(
- (console, out): void => {
- console.table({
- a: true,
- b: { c: { d: 10 }, e: [1, 2, [5, 6]] },
- f: "test",
- g: new Set([1, 2, 3, "test"]),
- h: new Map([[1, "one"]])
- });
- assertEquals(
- out.toString(),
- `┌─────────┬───────────┬───────────────────┬────────┐
-│ (index) │ c │ e │ Values │
-├─────────┼───────────┼───────────────────┼────────┤
-│ a │ │ │ true │
-│ b │ { d: 10 } │ [ 1, 2, [Array] ] │ │
-│ f │ │ │ "test" │
-│ g │ │ │ │
-│ h │ │ │ │
-└─────────┴───────────┴───────────────────┴────────┘
-`
- );
- }
- );
- mockConsole(
- (console, out): void => {
- console.table([
- 1,
- "test",
- false,
- { a: 10 },
- ["test", { b: 20, c: "test" }]
- ]);
- assertEquals(
- out.toString(),
- `┌─────────┬────────┬──────────────────────┬────┬────────┐
-│ (index) │ 0 │ 1 │ a │ Values │
-├─────────┼────────┼──────────────────────┼────┼────────┤
-│ 0 │ │ │ │ 1 │
-│ 1 │ │ │ │ "test" │
-│ 2 │ │ │ │ false │
-│ 3 │ │ │ 10 │ │
-│ 4 │ "test" │ { b: 20, c: "test" } │ │ │
-└─────────┴────────┴──────────────────────┴────┴────────┘
-`
- );
- }
- );
- mockConsole(
- (console, out): void => {
- console.table([]);
- assertEquals(
- out.toString(),
- `┌─────────┐
-│ (index) │
-├─────────┤
-└─────────┘
-`
- );
- }
- );
- mockConsole(
- (console, out): void => {
- console.table({});
- assertEquals(
- out.toString(),
- `┌─────────┐
-│ (index) │
-├─────────┤
-└─────────┘
-`
- );
- }
- );
- mockConsole(
- (console, out): void => {
- console.table(new Set());
- assertEquals(
- out.toString(),
- `┌───────────────────┐
-│ (iteration index) │
-├───────────────────┤
-└───────────────────┘
-`
- );
- }
- );
- mockConsole(
- (console, out): void => {
- console.table(new Map());
- assertEquals(
- out.toString(),
- `┌───────────────────┐
-│ (iteration index) │
-├───────────────────┤
-└───────────────────┘
-`
- );
- }
- );
- mockConsole(
- (console, out): void => {
- console.table("test");
- assertEquals(out.toString(), "test\n");
- }
- );
-});
-
-// console.log(Error) test
-test(function consoleLogShouldNotThrowError(): void {
- let result = 0;
- try {
- console.log(new Error("foo"));
- result = 1;
- } catch (e) {
- result = 2;
- }
- assertEquals(result, 1);
-
- // output errors to the console should not include "Uncaught"
- mockConsole(
- (console, out): void => {
- console.log(new Error("foo"));
- assertEquals(out.toString().includes("Uncaught"), false);
- }
- );
-});
-
-// console.dir test
-test(function consoleDir(): void {
- mockConsole(
- (console, out): void => {
- console.dir("DIR");
- assertEquals(out.toString(), "DIR\n");
- }
- );
- mockConsole(
- (console, out): void => {
- console.dir("DIR", { indentLevel: 2 });
- assertEquals(out.toString(), " DIR\n");
- }
- );
-});
-
-// console.dir test
-test(function consoleDirXml(): void {
- mockConsole(
- (console, out): void => {
- console.dirxml("DIRXML");
- assertEquals(out.toString(), "DIRXML\n");
- }
- );
- mockConsole(
- (console, out): void => {
- console.dirxml("DIRXML", { indentLevel: 2 });
- assertEquals(out.toString(), " DIRXML\n");
- }
- );
-});
-
-// console.trace test
-test(function consoleTrace(): void {
- mockConsole(
- (console, _out, err): void => {
- console.trace("%s", "custom message");
- assert(err.toString().includes("Trace: custom message"));
- }
- );
-});
diff --git a/js/copy_file.ts b/js/copy_file.ts
deleted file mode 100644
index 94d2b63db..000000000
--- a/js/copy_file.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.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 {
- sendSync(dispatch.OP_COPY_FILE, { from, to });
-}
-
-/** 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 async function copyFile(from: string, to: string): Promise<void> {
- await sendAsync(dispatch.OP_COPY_FILE, { from, to });
-}
diff --git a/js/copy_file_test.ts b/js/copy_file_test.ts
deleted file mode 100644
index 72ae43f3e..000000000
--- a/js/copy_file_test.ts
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-function readFileString(filename: string): string {
- const dataRead = Deno.readFileSync(filename);
- const dec = new TextDecoder("utf-8");
- return dec.decode(dataRead);
-}
-
-function writeFileString(filename: string, s: string): void {
- const enc = new TextEncoder();
- const data = enc.encode(s);
- Deno.writeFileSync(filename, data, { perm: 0o666 });
-}
-
-function assertSameContent(filename1: string, filename2: string): void {
- const data1 = Deno.readFileSync(filename1);
- const data2 = Deno.readFileSync(filename2);
- assertEquals(data1, data2);
-}
-
-testPerm({ read: true, write: true }, function copyFileSyncSuccess(): void {
- const tempDir = Deno.makeTempDirSync();
- const fromFilename = tempDir + "/from.txt";
- const toFilename = tempDir + "/to.txt";
- writeFileString(fromFilename, "Hello world!");
- Deno.copyFileSync(fromFilename, toFilename);
- // No change to original file
- assertEquals(readFileString(fromFilename), "Hello world!");
- // Original == Dest
- assertSameContent(fromFilename, toFilename);
-});
-
-testPerm({ write: true, read: true }, function copyFileSyncFailure(): void {
- const tempDir = Deno.makeTempDirSync();
- const fromFilename = tempDir + "/from.txt";
- const toFilename = tempDir + "/to.txt";
- // We skip initial writing here, from.txt does not exist
- let err;
- try {
- Deno.copyFileSync(fromFilename, toFilename);
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: true, read: false }, function copyFileSyncPerm1(): void {
- let caughtError = false;
- try {
- Deno.copyFileSync("/from.txt", "/to.txt");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ write: false, read: true }, function copyFileSyncPerm2(): void {
- let caughtError = false;
- try {
- Deno.copyFileSync("/from.txt", "/to.txt");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true, write: true }, function copyFileSyncOverwrite(): void {
- const tempDir = Deno.makeTempDirSync();
- const fromFilename = tempDir + "/from.txt";
- const toFilename = tempDir + "/to.txt";
- writeFileString(fromFilename, "Hello world!");
- // Make Dest exist and have different content
- writeFileString(toFilename, "Goodbye!");
- Deno.copyFileSync(fromFilename, toFilename);
- // No change to original file
- assertEquals(readFileString(fromFilename), "Hello world!");
- // Original == Dest
- assertSameContent(fromFilename, toFilename);
-});
-
-testPerm({ read: true, write: true }, async function copyFileSuccess(): Promise<
- void
-> {
- const tempDir = Deno.makeTempDirSync();
- const fromFilename = tempDir + "/from.txt";
- const toFilename = tempDir + "/to.txt";
- writeFileString(fromFilename, "Hello world!");
- await Deno.copyFile(fromFilename, toFilename);
- // No change to original file
- assertEquals(readFileString(fromFilename), "Hello world!");
- // Original == Dest
- assertSameContent(fromFilename, toFilename);
-});
-
-testPerm({ read: true, write: true }, async function copyFileFailure(): Promise<
- void
-> {
- const tempDir = Deno.makeTempDirSync();
- const fromFilename = tempDir + "/from.txt";
- const toFilename = tempDir + "/to.txt";
- // We skip initial writing here, from.txt does not exist
- let err;
- try {
- await Deno.copyFile(fromFilename, toFilename);
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm(
- { read: true, write: true },
- async function copyFileOverwrite(): Promise<void> {
- const tempDir = Deno.makeTempDirSync();
- const fromFilename = tempDir + "/from.txt";
- const toFilename = tempDir + "/to.txt";
- writeFileString(fromFilename, "Hello world!");
- // Make Dest exist and have different content
- writeFileString(toFilename, "Goodbye!");
- await Deno.copyFile(fromFilename, toFilename);
- // No change to original file
- assertEquals(readFileString(fromFilename), "Hello world!");
- // Original == Dest
- assertSameContent(fromFilename, toFilename);
- }
-);
-
-testPerm({ read: false, write: true }, async function copyFilePerm1(): Promise<
- void
-> {
- let caughtError = false;
- try {
- await Deno.copyFile("/from.txt", "/to.txt");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true, write: false }, async function copyFilePerm2(): Promise<
- void
-> {
- let caughtError = false;
- try {
- await Deno.copyFile("/from.txt", "/to.txt");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
diff --git a/js/core.ts b/js/core.ts
deleted file mode 100644
index d394d822f..000000000
--- a/js/core.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { window } from "./window.ts";
-
-// This allows us to access core in API even if we
-// dispose window.Deno
-export const core = window.Deno.core as DenoCore;
diff --git a/js/custom_event.ts b/js/custom_event.ts
deleted file mode 100644
index 922abd4b1..000000000
--- a/js/custom_event.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2018 the Deno authors. All rights reserved. MIT license.
-import * as domTypes from "./dom_types.ts";
-import * as event from "./event.ts";
-import { getPrivateValue, requiredArguments } from "./util.ts";
-
-// WeakMaps are recommended for private attributes (see MDN link below)
-// https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Add-on_SDK/Guides/Contributor_s_Guide/Private_Properties#Using_WeakMaps
-export const customEventAttributes = new WeakMap();
-
-export class CustomEvent extends event.Event implements domTypes.CustomEvent {
- constructor(
- type: string,
- customEventInitDict: domTypes.CustomEventInit = {}
- ) {
- requiredArguments("CustomEvent", arguments.length, 1);
- super(type, customEventInitDict);
- const { detail = null } = customEventInitDict;
- customEventAttributes.set(this, { detail });
- }
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- get detail(): any {
- return getPrivateValue(this, customEventAttributes, "detail");
- }
-
- initCustomEvent(
- type: string,
- bubbles?: boolean,
- cancelable?: boolean,
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- detail?: any
- ): void {
- if (this.dispatched) {
- return;
- }
-
- customEventAttributes.set(this, { detail });
- }
-
- get [Symbol.toStringTag](): string {
- return "CustomEvent";
- }
-}
-
-/** Built-in objects providing `get` methods for our
- * interceptable JavaScript operations.
- */
-Reflect.defineProperty(CustomEvent.prototype, "detail", { enumerable: true });
diff --git a/js/custom_event_test.ts b/js/custom_event_test.ts
deleted file mode 100644
index 4d2eb2c16..000000000
--- a/js/custom_event_test.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 the Deno authors. All rights reserved. MIT license.
-import { test, assertEquals } from "./test_util.ts";
-
-test(function customEventInitializedWithDetail(): void {
- const type = "touchstart";
- const detail = { message: "hello" };
- const customEventInit = {
- bubbles: true,
- cancelable: true,
- detail
- } as CustomEventInit;
- const event = new CustomEvent(type, customEventInit);
-
- assertEquals(event.bubbles, true);
- assertEquals(event.cancelable, true);
- assertEquals(event.currentTarget, null);
- assertEquals(event.detail, detail);
- assertEquals(event.isTrusted, false);
- assertEquals(event.target, null);
- assertEquals(event.type, type);
-});
-
-test(function toStringShouldBeWebCompatibility(): void {
- const type = "touchstart";
- const event = new CustomEvent(type, {});
- assertEquals(event.toString(), "[object CustomEvent]");
-});
diff --git a/js/deno.ts b/js/deno.ts
deleted file mode 100644
index 511e4f0ec..000000000
--- a/js/deno.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-// Public deno module.
-export { env, exit, isTTY, execPath, homeDir, hostname } from "./os.ts";
-export { chdir, cwd } from "./dir.ts";
-export {
- File,
- open,
- openSync,
- stdin,
- stdout,
- stderr,
- read,
- readSync,
- write,
- writeSync,
- seek,
- seekSync,
- close,
- OpenMode
-} from "./files.ts";
-export {
- EOF,
- copy,
- toAsyncIterator,
- SeekMode,
- Reader,
- SyncReader,
- Writer,
- SyncWriter,
- Closer,
- Seeker,
- SyncSeeker,
- ReadCloser,
- WriteCloser,
- ReadSeeker,
- WriteSeeker,
- ReadWriteCloser,
- ReadWriteSeeker
-} from "./io.ts";
-export {
- Buffer,
- readAll,
- readAllSync,
- writeAll,
- writeAllSync
-} from "./buffer.ts";
-export { mkdirSync, mkdir } from "./mkdir.ts";
-export {
- makeTempDirSync,
- makeTempDir,
- MakeTempDirOptions
-} from "./make_temp_dir.ts";
-export { chmodSync, chmod } from "./chmod.ts";
-export { chownSync, chown } from "./chown.ts";
-export { utimeSync, utime } from "./utime.ts";
-export { removeSync, remove, RemoveOption } from "./remove.ts";
-export { renameSync, rename } from "./rename.ts";
-export { readFileSync, readFile } from "./read_file.ts";
-export { readDirSync, readDir } from "./read_dir.ts";
-export { copyFileSync, copyFile } from "./copy_file.ts";
-export { readlinkSync, readlink } from "./read_link.ts";
-export { statSync, lstatSync, stat, lstat } from "./stat.ts";
-export { linkSync, link } from "./link.ts";
-export { symlinkSync, symlink } from "./symlink.ts";
-export { writeFileSync, writeFile, WriteFileOptions } from "./write_file.ts";
-export { applySourceMap } from "./error_stack.ts";
-export { ErrorKind, DenoError } from "./errors.ts";
-export {
- permissions,
- revokePermission,
- Permission,
- Permissions
-} from "./permissions.ts";
-export { truncateSync, truncate } from "./truncate.ts";
-export { FileInfo } from "./file_info.ts";
-export { connect, dial, listen, Listener, Conn } from "./net.ts";
-export { dialTLS } from "./tls.ts";
-export { metrics, Metrics } from "./metrics.ts";
-export { resources } from "./resources.ts";
-export {
- kill,
- run,
- RunOptions,
- Process,
- ProcessStatus,
- Signal
-} from "./process.ts";
-export { inspect, customInspect } from "./console.ts";
-export { build, OperatingSystem, Arch } from "./build.ts";
-export { version } from "./version.ts";
-export const args: string[] = [];
-
-// These are internal Deno APIs. We are marking them as internal so they do not
-// appear in the runtime type library.
-/** @internal */
-export { core } from "./core.ts";
-
-/** @internal */
-export { setPrepareStackTrace } from "./error_stack.ts";
-
-// TODO Don't expose Console nor stringifyArgs.
-/** @internal */
-export { Console, stringifyArgs } from "./console.ts";
-// TODO Don't expose DomIterableMixin.
-/** @internal */
-export { DomIterableMixin } from "./mixins/dom_iterable.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;
-
-// TODO(ry) This should not be exposed to Deno.
-export function _setGlobals(pid_: number, noColor_: boolean): void {
- pid = pid_;
- noColor = noColor_;
-}
diff --git a/js/diagnostics.ts b/js/diagnostics.ts
deleted file mode 100644
index 7cdb154b9..000000000
--- a/js/diagnostics.ts
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-// Diagnostic provides an abstraction for advice/errors received from a
-// compiler, which is strongly influenced by the format of TypeScript
-// diagnostics.
-
-/** The log category for a diagnostic message */
-export enum DiagnosticCategory {
- Log = 0,
- Debug = 1,
- Info = 2,
- Error = 3,
- Warning = 4,
- Suggestion = 5
-}
-
-export interface DiagnosticMessageChain {
- message: string;
- category: DiagnosticCategory;
- code: number;
- next?: DiagnosticMessageChain[];
-}
-
-export interface DiagnosticItem {
- /** A string message summarizing the diagnostic. */
- message: string;
-
- /** An ordered array of further diagnostics. */
- messageChain?: DiagnosticMessageChain;
-
- /** Information related to the diagnostic. This is present when there is a
- * suggestion or other additional diagnostic information */
- relatedInformation?: DiagnosticItem[];
-
- /** The text of the source line related to the diagnostic */
- sourceLine?: string;
-
- /** The line number that is related to the diagnostic */
- lineNumber?: number;
-
- /** The name of the script resource related to the diagnostic */
- scriptResourceName?: string;
-
- /** The start position related to the diagnostic */
- startPosition?: number;
-
- /** The end position related to the diagnostic */
- endPosition?: number;
-
- /** The category of the diagnostic */
- category: DiagnosticCategory;
-
- /** A number identifier */
- code: number;
-
- /** The the start column of the sourceLine related to the diagnostic */
- startColumn?: number;
-
- /** The end column of the sourceLine related to the diagnostic */
- endColumn?: number;
-}
-
-export interface Diagnostic {
- /** An array of diagnostic items. */
- items: DiagnosticItem[];
-}
-
-interface SourceInformation {
- sourceLine: string;
- lineNumber: number;
- scriptResourceName: string;
- startColumn: number;
- endColumn: number;
-}
-
-function fromDiagnosticCategory(
- category: ts.DiagnosticCategory
-): DiagnosticCategory {
- switch (category) {
- case ts.DiagnosticCategory.Error:
- return DiagnosticCategory.Error;
- case ts.DiagnosticCategory.Message:
- return DiagnosticCategory.Info;
- case ts.DiagnosticCategory.Suggestion:
- return DiagnosticCategory.Suggestion;
- case ts.DiagnosticCategory.Warning:
- return DiagnosticCategory.Warning;
- default:
- throw new Error(
- `Unexpected DiagnosticCategory: "${category}"/"${
- ts.DiagnosticCategory[category]
- }"`
- );
- }
-}
-
-function getSourceInformation(
- sourceFile: ts.SourceFile,
- start: number,
- length: number
-): SourceInformation {
- const scriptResourceName = sourceFile.fileName;
- const {
- line: lineNumber,
- character: startColumn
- } = sourceFile.getLineAndCharacterOfPosition(start);
- const endPosition = sourceFile.getLineAndCharacterOfPosition(start + length);
- const endColumn =
- lineNumber === endPosition.line ? endPosition.character : startColumn;
- const lastLineInFile = sourceFile.getLineAndCharacterOfPosition(
- sourceFile.text.length
- ).line;
- const lineStart = sourceFile.getPositionOfLineAndCharacter(lineNumber, 0);
- const lineEnd =
- lineNumber < lastLineInFile
- ? sourceFile.getPositionOfLineAndCharacter(lineNumber + 1, 0)
- : sourceFile.text.length;
- const sourceLine = sourceFile.text
- .slice(lineStart, lineEnd)
- .replace(/\s+$/g, "")
- .replace("\t", " ");
- return {
- sourceLine,
- lineNumber,
- scriptResourceName,
- startColumn,
- endColumn
- };
-}
-
-/** Converts a TypeScript diagnostic message chain to a Deno one. */
-function fromDiagnosticMessageChain(
- messageChain: ts.DiagnosticMessageChain[] | undefined
-): DiagnosticMessageChain[] | undefined {
- if (!messageChain) {
- return undefined;
- }
-
- return messageChain.map(({ messageText: message, code, category, next }) => {
- return {
- message,
- code,
- category: fromDiagnosticCategory(category),
- next: fromDiagnosticMessageChain(next)
- };
- });
-}
-
-/** Parse out information from a TypeScript diagnostic structure. */
-function parseDiagnostic(
- item: ts.Diagnostic | ts.DiagnosticRelatedInformation
-): DiagnosticItem {
- const {
- messageText,
- category: sourceCategory,
- code,
- file,
- start: startPosition,
- length
- } = item;
- const sourceInfo =
- file && startPosition && length
- ? getSourceInformation(file, startPosition, length)
- : undefined;
- const endPosition =
- startPosition && length ? startPosition + length : undefined;
- const category = fromDiagnosticCategory(sourceCategory);
-
- let message: string;
- let messageChain: DiagnosticMessageChain | undefined;
- if (typeof messageText === "string") {
- message = messageText;
- } else {
- message = messageText.messageText;
- messageChain = fromDiagnosticMessageChain([messageText])![0];
- }
-
- const base = {
- message,
- messageChain,
- code,
- category,
- startPosition,
- endPosition
- };
-
- return sourceInfo ? { ...base, ...sourceInfo } : base;
-}
-
-/** Convert a diagnostic related information array into a Deno diagnostic
- * array. */
-function parseRelatedInformation(
- relatedInformation: readonly ts.DiagnosticRelatedInformation[]
-): DiagnosticItem[] {
- const result: DiagnosticItem[] = [];
- for (const item of relatedInformation) {
- result.push(parseDiagnostic(item));
- }
- return result;
-}
-
-/** Convert TypeScript diagnostics to Deno diagnostics. */
-export function fromTypeScriptDiagnostic(
- diagnostics: readonly ts.Diagnostic[]
-): Diagnostic {
- const items: DiagnosticItem[] = [];
- for (const sourceDiagnostic of diagnostics) {
- const item: DiagnosticItem = parseDiagnostic(sourceDiagnostic);
- if (sourceDiagnostic.relatedInformation) {
- item.relatedInformation = parseRelatedInformation(
- sourceDiagnostic.relatedInformation
- );
- }
- items.push(item);
- }
- return { items };
-}
diff --git a/js/dir.ts b/js/dir.ts
deleted file mode 100644
index ef1111555..000000000
--- a/js/dir.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.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 {
- return sendSync(dispatch.OP_CWD);
-}
-
-/**
- * `chdir()` Change the current working directory to path.
- * throws `NotFound` exception if directory not available
- */
-export function chdir(directory: string): void {
- sendSync(dispatch.OP_CHDIR, { directory });
-}
diff --git a/js/dir_test.ts b/js/dir_test.ts
deleted file mode 100644
index 6c4e36d7a..000000000
--- a/js/dir_test.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, testPerm, assert, assertEquals } from "./test_util.ts";
-
-test(function dirCwdNotNull(): void {
- assert(Deno.cwd() != null);
-});
-
-testPerm({ write: true }, function dirCwdChdirSuccess(): void {
- const initialdir = Deno.cwd();
- const path = Deno.makeTempDirSync();
- Deno.chdir(path);
- const current = Deno.cwd();
- if (Deno.build.os === "mac") {
- assertEquals(current, "/private" + path);
- } else {
- assertEquals(current, path);
- }
- Deno.chdir(initialdir);
-});
-
-testPerm({ write: true }, function dirCwdError(): void {
- // excluding windows since it throws resource busy, while removeSync
- if (["linux", "mac"].includes(Deno.build.os)) {
- const initialdir = Deno.cwd();
- const path = Deno.makeTempDirSync();
- Deno.chdir(path);
- Deno.removeSync(path);
- try {
- Deno.cwd();
- throw Error("current directory removed, should throw error");
- } catch (err) {
- if (err instanceof Deno.DenoError) {
- console.log(err.name === "NotFound");
- } else {
- throw Error("raised different exception");
- }
- }
- Deno.chdir(initialdir);
- }
-});
-
-testPerm({ write: true }, function dirChdirError(): void {
- const path = Deno.makeTempDirSync() + "test";
- try {
- Deno.chdir(path);
- throw Error("directory not available, should throw error");
- } catch (err) {
- if (err instanceof Deno.DenoError) {
- console.log(err.name === "NotFound");
- } else {
- throw Error("raised different exception");
- }
- }
-});
diff --git a/js/dispatch.ts b/js/dispatch.ts
deleted file mode 100644
index bff4d0f5b..000000000
--- a/js/dispatch.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as minimal from "./dispatch_minimal.ts";
-import * as json from "./dispatch_json.ts";
-
-// These consts are shared with Rust. Update with care.
-export let OP_READ: number;
-export let OP_WRITE: number;
-export let OP_EXIT: number;
-export let OP_IS_TTY: number;
-export let OP_ENV: number;
-export let OP_EXEC_PATH: number;
-export let OP_UTIME: number;
-export let OP_SET_ENV: number;
-export let OP_GET_ENV: number;
-export let OP_HOME_DIR: number;
-export let OP_START: number;
-export let OP_APPLY_SOURCE_MAP: number;
-export let OP_FORMAT_ERROR: number;
-export let OP_CACHE: number;
-export let OP_FETCH_SOURCE_FILES: number;
-export let OP_OPEN: number;
-export let OP_CLOSE: number;
-export let OP_SEEK: number;
-export let OP_FETCH: number;
-export let OP_METRICS: number;
-export let OP_REPL_START: number;
-export let OP_REPL_READLINE: number;
-export let OP_ACCEPT: number;
-export let OP_DIAL: number;
-export let OP_SHUTDOWN: number;
-export let OP_LISTEN: number;
-export let OP_RESOURCES: number;
-export let OP_GET_RANDOM_VALUES: number;
-export let OP_GLOBAL_TIMER_STOP: number;
-export let OP_GLOBAL_TIMER: number;
-export let OP_NOW: number;
-export let OP_PERMISSIONS: number;
-export let OP_REVOKE_PERMISSION: number;
-export let OP_CREATE_WORKER: number;
-export let OP_HOST_GET_WORKER_CLOSED: number;
-export let OP_HOST_POST_MESSAGE: number;
-export let OP_HOST_GET_MESSAGE: number;
-export let OP_WORKER_POST_MESSAGE: number;
-export let OP_WORKER_GET_MESSAGE: number;
-export let OP_RUN: number;
-export let OP_RUN_STATUS: number;
-export let OP_KILL: number;
-export let OP_CHDIR: number;
-export let OP_MKDIR: number;
-export let OP_CHMOD: number;
-export let OP_CHOWN: number;
-export let OP_REMOVE: number;
-export let OP_COPY_FILE: number;
-export let OP_STAT: number;
-export let OP_READ_DIR: number;
-export let OP_RENAME: number;
-export let OP_LINK: number;
-export let OP_SYMLINK: number;
-export let OP_READ_LINK: number;
-export let OP_TRUNCATE: number;
-export let OP_MAKE_TEMP_DIR: number;
-export let OP_CWD: number;
-export let OP_FETCH_ASSET: number;
-export let OP_DIAL_TLS: number;
-export let OP_HOSTNAME: number;
-
-export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void {
- switch (opId) {
- case OP_WRITE:
- case OP_READ:
- minimal.asyncMsgFromRust(opId, ui8);
- break;
- case OP_EXIT:
- case OP_IS_TTY:
- case OP_ENV:
- case OP_EXEC_PATH:
- case OP_UTIME:
- case OP_OPEN:
- case OP_SEEK:
- case OP_FETCH:
- case OP_REPL_START:
- case OP_REPL_READLINE:
- case OP_ACCEPT:
- case OP_DIAL:
- case OP_GLOBAL_TIMER:
- case OP_HOST_GET_WORKER_CLOSED:
- case OP_HOST_GET_MESSAGE:
- case OP_WORKER_GET_MESSAGE:
- case OP_RUN_STATUS:
- case OP_MKDIR:
- case OP_CHMOD:
- case OP_CHOWN:
- case OP_REMOVE:
- case OP_COPY_FILE:
- case OP_STAT:
- case OP_READ_DIR:
- case OP_RENAME:
- case OP_LINK:
- case OP_SYMLINK:
- case OP_READ_LINK:
- case OP_TRUNCATE:
- case OP_MAKE_TEMP_DIR:
- case OP_DIAL_TLS:
- case OP_FETCH_SOURCE_FILES:
- json.asyncMsgFromRust(opId, ui8);
- break;
- default:
- throw Error("bad async opId");
- }
-}
diff --git a/js/dispatch_json.ts b/js/dispatch_json.ts
deleted file mode 100644
index 572ec855a..000000000
--- a/js/dispatch_json.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as util from "./util.ts";
-import { TextEncoder, TextDecoder } from "./text_encoding.ts";
-import { core } from "./core.ts";
-import { ErrorKind, DenoError } from "./errors.ts";
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-type Ok = any;
-
-interface JsonError {
- kind: ErrorKind;
- message: string;
-}
-
-interface JsonResponse {
- ok?: Ok;
- err?: JsonError;
- promiseId?: number; // Only present in async messages.
-}
-
-const promiseTable = new Map<number, util.Resolvable<JsonResponse>>();
-let _nextPromiseId = 1;
-
-function nextPromiseId(): number {
- return _nextPromiseId++;
-}
-
-function decode(ui8: Uint8Array): JsonResponse {
- const s = new TextDecoder().decode(ui8);
- return JSON.parse(s) as JsonResponse;
-}
-
-function encode(args: object): Uint8Array {
- const s = JSON.stringify(args);
- return new TextEncoder().encode(s);
-}
-
-function unwrapResponse(res: JsonResponse): Ok {
- if (res.err != null) {
- throw new DenoError(res.err!.kind, res.err!.message);
- }
- util.assert(res.ok != null);
- return res.ok!;
-}
-
-export function asyncMsgFromRust(opId: number, resUi8: Uint8Array): void {
- const res = decode(resUi8);
- util.assert(res.promiseId != null);
-
- const promise = promiseTable.get(res.promiseId!);
- util.assert(promise != null);
- promiseTable.delete(res.promiseId!);
- promise!.resolve(res);
-}
-
-export function sendSync(
- opId: number,
- args: object = {},
- zeroCopy?: Uint8Array
-): Ok {
- const argsUi8 = encode(args);
- const resUi8 = core.dispatch(opId, argsUi8, zeroCopy);
- util.assert(resUi8 != null);
-
- const res = decode(resUi8!);
- util.assert(res.promiseId == null);
- return unwrapResponse(res);
-}
-
-export async function sendAsync(
- opId: number,
- args: object = {},
- zeroCopy?: Uint8Array
-): Promise<Ok> {
- const promiseId = nextPromiseId();
- args = Object.assign(args, { promiseId });
- const promise = util.createResolvable<Ok>();
- promiseTable.set(promiseId, promise);
-
- const argsUi8 = encode(args);
- const resUi8 = core.dispatch(opId, argsUi8, zeroCopy);
- util.assert(resUi8 == null);
-
- const res = await promise;
- return unwrapResponse(res);
-}
diff --git a/js/dispatch_json_test.ts b/js/dispatch_json_test.ts
deleted file mode 100644
index 11dadc620..000000000
--- a/js/dispatch_json_test.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { testPerm, assertMatch, unreachable } from "./test_util.ts";
-
-const openErrorStackPattern = new RegExp(
- `^.*
- at unwrapResponse \\(.*dispatch_json\\.ts:.*\\)
- at Object.sendAsync \\(.*dispatch_json\\.ts:.*\\)
- at async Object\\.open \\(.*files\\.ts:.*\\).*$`,
- "ms"
-);
-
-testPerm({ read: true }, async function sendAsyncStackTrace(): Promise<void> {
- await Deno.open("nonexistent.txt")
- .then(unreachable)
- .catch(
- (error): void => {
- assertMatch(error.stack, openErrorStackPattern);
- }
- );
-});
diff --git a/js/dispatch_minimal.ts b/js/dispatch_minimal.ts
deleted file mode 100644
index 98636f85b..000000000
--- a/js/dispatch_minimal.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as util from "./util.ts";
-import { core } from "./core.ts";
-
-const promiseTableMin = new Map<number, util.Resolvable<number>>();
-// Note it's important that promiseId starts at 1 instead of 0, because sync
-// messages are indicated with promiseId 0. If we ever add wrap around logic for
-// overflows, this should be taken into account.
-let _nextPromiseId = 1;
-
-function nextPromiseId(): number {
- return _nextPromiseId++;
-}
-
-export interface RecordMinimal {
- promiseId: number;
- opId: number; // Maybe better called dispatchId
- arg: number;
- result: number;
-}
-
-export function recordFromBufMinimal(
- opId: number,
- buf32: Int32Array
-): RecordMinimal {
- if (buf32.length != 3) {
- throw Error("Bad message");
- }
- return {
- promiseId: buf32[0],
- opId,
- arg: buf32[1],
- result: buf32[2]
- };
-}
-
-const scratch32 = new Int32Array(3);
-const scratchBytes = new Uint8Array(
- scratch32.buffer,
- scratch32.byteOffset,
- scratch32.byteLength
-);
-util.assert(scratchBytes.byteLength === scratch32.length * 4);
-
-export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void {
- const buf32 = new Int32Array(ui8.buffer, ui8.byteOffset, ui8.byteLength / 4);
- const record = recordFromBufMinimal(opId, buf32);
- const { promiseId, result } = record;
- const promise = promiseTableMin.get(promiseId);
- promiseTableMin.delete(promiseId);
- promise!.resolve(result);
-}
-
-export function sendAsyncMinimal(
- opId: number,
- arg: number,
- zeroCopy: Uint8Array
-): Promise<number> {
- const promiseId = nextPromiseId(); // AKA cmdId
- scratch32[0] = promiseId;
- scratch32[1] = arg;
- scratch32[2] = 0; // result
- const promise = util.createResolvable<number>();
- promiseTableMin.set(promiseId, promise);
- core.dispatch(opId, scratchBytes, zeroCopy);
- return promise;
-}
-
-export function sendSyncMinimal(
- opId: number,
- arg: number,
- zeroCopy: Uint8Array
-): number {
- scratch32[0] = 0; // promiseId 0 indicates sync
- scratch32[1] = arg;
- const res = core.dispatch(opId, scratchBytes, zeroCopy)!;
- const res32 = new Int32Array(res.buffer, res.byteOffset, 3);
- const resRecord = recordFromBufMinimal(opId, res32);
- return resRecord.result;
-}
diff --git a/js/dom_file.ts b/js/dom_file.ts
deleted file mode 100644
index 1f9bf93a5..000000000
--- a/js/dom_file.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as domTypes from "./dom_types.ts";
-import * as blob from "./blob.ts";
-
-export class DomFileImpl extends blob.DenoBlob implements domTypes.DomFile {
- lastModified: number;
- name: string;
-
- constructor(
- fileBits: domTypes.BlobPart[],
- fileName: string,
- options?: domTypes.FilePropertyBag
- ) {
- options = options || {};
- super(fileBits, options);
-
- // 4.1.2.1 Replace any "/" character (U+002F SOLIDUS)
- // with a ":" (U + 003A COLON)
- this.name = String(fileName).replace(/\u002F/g, "\u003A");
- // 4.1.3.3 If lastModified is not provided, set lastModified to the current
- // date and time represented in number of milliseconds since the Unix Epoch.
- this.lastModified = options.lastModified || Date.now();
- }
-}
diff --git a/js/dom_types.ts b/js/dom_types.ts
deleted file mode 100644
index 308505cf5..000000000
--- a/js/dom_types.ts
+++ /dev/null
@@ -1,625 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-/*! ****************************************************************************
-Copyright (c) Microsoft Corporation. All rights reserved.
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use
-this file except in compliance with the License. You may obtain a copy of the
-License at http://www.apache.org/licenses/LICENSE-2.0
-
-THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
-ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
-WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
-MERCHANTABLITY OR NON-INFRINGEMENT.
-
-See the Apache Version 2.0 License for specific language governing permissions
-and limitations under the License.
-*******************************************************************************/
-
-/* eslint-disable @typescript-eslint/no-explicit-any */
-
-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;
-}
-
-// https://dom.spec.whatwg.org/#node
-export enum NodeType {
- ELEMENT_NODE = 1,
- TEXT_NODE = 3,
- DOCUMENT_FRAGMENT_NODE = 11
-}
-
-export const eventTargetHost: unique symbol = Symbol();
-export const eventTargetListeners: unique symbol = Symbol();
-export const eventTargetMode: unique symbol = Symbol();
-export const eventTargetNodeType: unique symbol = 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 extends DomIterable<string, string> {
- /**
- * 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: this) => 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;
-}
diff --git a/js/dom_util.ts b/js/dom_util.ts
deleted file mode 100644
index 725a35aaf..000000000
--- a/js/dom_util.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-// Utility functions for DOM nodes
-import * as domTypes from "./dom_types.ts";
-
-export function isNode(nodeImpl: domTypes.EventTarget | null): boolean {
- return Boolean(nodeImpl && "nodeType" in nodeImpl);
-}
-
-export function isShadowRoot(nodeImpl: domTypes.EventTarget | null): boolean {
- return Boolean(
- nodeImpl &&
- nodeImpl[domTypes.eventTargetNodeType] ===
- domTypes.NodeType.DOCUMENT_FRAGMENT_NODE &&
- nodeImpl[domTypes.eventTargetHost] != null
- );
-}
-
-export function isSlotable(nodeImpl: domTypes.EventTarget | null): boolean {
- return Boolean(
- nodeImpl &&
- (nodeImpl[domTypes.eventTargetNodeType] ===
- domTypes.NodeType.ELEMENT_NODE ||
- nodeImpl[domTypes.eventTargetNodeType] === domTypes.NodeType.TEXT_NODE)
- );
-}
-
-// https://dom.spec.whatwg.org/#node-trees
-// const domSymbolTree = Symbol("DOM Symbol Tree");
-
-// https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-ancestor
-export function isShadowInclusiveAncestor(
- ancestor: domTypes.EventTarget | null,
- node: domTypes.EventTarget | null
-): boolean {
- while (isNode(node)) {
- if (node === ancestor) {
- return true;
- }
-
- if (isShadowRoot(node)) {
- node = node && node[domTypes.eventTargetHost];
- } else {
- node = null; // domSymbolTree.parent(node);
- }
- }
-
- return false;
-}
-
-export function getRoot(
- node: domTypes.EventTarget | null
-): domTypes.EventTarget | null {
- const root = node;
-
- // for (const ancestor of domSymbolTree.ancestorsIterator(node)) {
- // root = ancestor;
- // }
-
- return root;
-}
-
-// https://dom.spec.whatwg.org/#retarget
-export function retarget(
- a: domTypes.EventTarget | null,
- b: domTypes.EventTarget
-): domTypes.EventTarget | null {
- while (true) {
- if (!isNode(a)) {
- return a;
- }
-
- const aRoot = getRoot(a);
-
- if (aRoot) {
- if (
- !isShadowRoot(aRoot) ||
- (isNode(b) && isShadowInclusiveAncestor(aRoot, b))
- ) {
- return a;
- }
-
- a = aRoot[domTypes.eventTargetHost];
- }
- }
-}
diff --git a/js/error_stack.ts b/js/error_stack.ts
deleted file mode 100644
index 98b0b02d4..000000000
--- a/js/error_stack.ts
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-// Some of the code here is adapted directly from V8 and licensed under a BSD
-// style license available here: https://github.com/v8/v8/blob/24886f2d1c565287d33d71e4109a53bf0b54b75c/LICENSE.v8
-import * as dispatch from "./dispatch.ts";
-import { sendSync } from "./dispatch_json.ts";
-import { assert } from "./util.ts";
-
-export 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 {
- const { filename, line, column } = location;
- // On this side, line/column are 1 based, but in the source maps, they are
- // 0 based, so we have to convert back and forth
- const res = sendSync(dispatch.OP_APPLY_SOURCE_MAP, {
- filename,
- line: line - 1,
- column: column - 1
- });
- return {
- filename: res.filename,
- line: res.line + 1,
- column: res.column + 1
- };
-}
-
-/** Mutate the call site so that it returns the location, instead of its
- * original location.
- */
-function patchCallSite(callSite: CallSite, location: Location): CallSite {
- return {
- getThis(): unknown {
- return callSite.getThis();
- },
- getTypeName(): string {
- return callSite.getTypeName();
- },
- getFunction(): Function {
- return callSite.getFunction();
- },
- getFunctionName(): string {
- return callSite.getFunctionName();
- },
- getMethodName(): string {
- return callSite.getMethodName();
- },
- getFileName(): string {
- return location.filename;
- },
- getLineNumber(): number {
- return location.line;
- },
- getColumnNumber(): number {
- return location.column;
- },
- getEvalOrigin(): string | null {
- return callSite.getEvalOrigin();
- },
- isToplevel(): boolean {
- return callSite.isToplevel();
- },
- isEval(): boolean {
- return callSite.isEval();
- },
- isNative(): boolean {
- return callSite.isNative();
- },
- isConstructor(): boolean {
- return callSite.isConstructor();
- },
- isAsync(): boolean {
- return callSite.isAsync();
- },
- isPromiseAll(): boolean {
- return callSite.isPromiseAll();
- },
- getPromiseIndex(): number | null {
- return callSite.getPromiseIndex();
- }
- };
-}
-
-/** Return a string representations of a CallSite's method call name
- *
- * This is adapted directly from V8.
- */
-function getMethodCall(callSite: CallSite): string {
- let result = "";
-
- const typeName = callSite.getTypeName();
- const methodName = callSite.getMethodName();
- const functionName = callSite.getFunctionName();
-
- if (functionName) {
- if (typeName) {
- const startsWithTypeName = functionName.startsWith(typeName);
- if (!startsWithTypeName) {
- result += `${typeName}.`;
- }
- }
- result += functionName;
-
- if (methodName) {
- if (!functionName.endsWith(methodName)) {
- result += ` [as ${methodName}]`;
- }
- }
- } else {
- if (typeName) {
- result += `${typeName}.`;
- }
- if (methodName) {
- result += methodName;
- } else {
- result += "<anonymous>";
- }
- }
-
- return result;
-}
-
-/** Return a string representations of a CallSite's file location
- *
- * This is adapted directly from V8.
- */
-function getFileLocation(callSite: CallSite): string {
- if (callSite.isNative()) {
- return "native";
- }
-
- let result = "";
-
- const fileName = callSite.getFileName();
- if (!fileName && callSite.isEval()) {
- const evalOrigin = callSite.getEvalOrigin();
- assert(evalOrigin != null);
- result += `${evalOrigin}, `;
- }
-
- if (fileName) {
- result += fileName;
- } else {
- result += "<anonymous>";
- }
-
- const lineNumber = callSite.getLineNumber();
- if (lineNumber != null) {
- result += `:${lineNumber}`;
-
- const columnNumber = callSite.getColumnNumber();
- if (columnNumber != null) {
- result += `:${columnNumber}`;
- }
- }
-
- return result;
-}
-
-/** Convert a CallSite to a string.
- *
- * This is adapted directly from V8.
- */
-function callSiteToString(callSite: CallSite): string {
- let result = "";
- const functionName = callSite.getFunctionName();
-
- const isTopLevel = callSite.isToplevel();
- const isAsync = callSite.isAsync();
- const isPromiseAll = callSite.isPromiseAll();
- const isConstructor = callSite.isConstructor();
- const isMethodCall = !(isTopLevel || isConstructor);
-
- if (isAsync) {
- result += "async ";
- }
- if (isPromiseAll) {
- result += `Promise.all (index ${callSite.getPromiseIndex})`;
- return result;
- }
- if (isMethodCall) {
- result += getMethodCall(callSite);
- } else if (isConstructor) {
- result += "new ";
- if (functionName) {
- result += functionName;
- } else {
- result += "<anonymous>";
- }
- } else if (functionName) {
- result += functionName;
- } else {
- result += getFileLocation(callSite);
- return result;
- }
-
- result += ` (${getFileLocation(callSite)})`;
- return result;
-}
-
-/** A replacement for the default stack trace preparer which will op into Rust
- * to apply source maps to individual sites
- */
-function prepareStackTrace(
- error: Error,
- structuredStackTrace: CallSite[]
-): string {
- return (
- `${error.name}: ${error.message}\n` +
- structuredStackTrace
- .map(
- (callSite): CallSite => {
- const filename = callSite.getFileName();
- const line = callSite.getLineNumber();
- const column = callSite.getColumnNumber();
- if (filename && line != null && column != null) {
- return patchCallSite(
- callSite,
- applySourceMap({
- filename,
- line,
- column
- })
- );
- }
- return callSite;
- }
- )
- .map((callSite): string => ` at ${callSiteToString(callSite)}`)
- .join("\n")
- );
-}
-
-/** Sets the `prepareStackTrace` method on the Error constructor which will
- * op into Rust to remap source code for caught errors where the `.stack` is
- * being accessed.
- *
- * See: https://v8.dev/docs/stack-trace-api
- */
-// @internal
-export function setPrepareStackTrace(ErrorConstructor: typeof Error): void {
- ErrorConstructor.prepareStackTrace = prepareStackTrace;
-}
diff --git a/js/error_stack_test.ts b/js/error_stack_test.ts
deleted file mode 100644
index 4c7edb2fd..000000000
--- a/js/error_stack_test.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert } from "./test_util.ts";
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-const { setPrepareStackTrace } = Deno as any;
-
-interface CallSite {
- getThis(): unknown;
- getTypeName(): string;
- getFunction(): Function;
- getFunctionName(): string;
- getMethodName(): string;
- getFileName(): string;
- getLineNumber(): number | null;
- getColumnNumber(): number | null;
- getEvalOrigin(): string | null;
- isToplevel(): boolean;
- isEval(): boolean;
- isNative(): boolean;
- isConstructor(): boolean;
- isAsync(): boolean;
- isPromiseAll(): boolean;
- getPromiseIndex(): number | null;
-}
-
-function getMockCallSite(
- filename: string,
- line: number | null,
- column: number | null
-): CallSite {
- return {
- getThis(): unknown {
- return undefined;
- },
- getTypeName(): string {
- return "";
- },
- getFunction(): Function {
- return (): void => {};
- },
- getFunctionName(): string {
- return "";
- },
- getMethodName(): string {
- return "";
- },
- getFileName(): string {
- return filename;
- },
- getLineNumber(): number | null {
- return line;
- },
- getColumnNumber(): number | null {
- return column;
- },
- getEvalOrigin(): null {
- return null;
- },
- isToplevel(): false {
- return false;
- },
- isEval(): false {
- return false;
- },
- isNative(): false {
- return false;
- },
- isConstructor(): false {
- return false;
- },
- isAsync(): false {
- return false;
- },
- isPromiseAll(): false {
- return false;
- },
- getPromiseIndex(): null {
- return null;
- }
- };
-}
-
-test(function prepareStackTrace(): void {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const MockError = {} as any;
- setPrepareStackTrace(MockError);
- assert(typeof MockError.prepareStackTrace === "function");
- const prepareStackTrace: (
- error: Error,
- structuredStackTrace: CallSite[]
- ) => string = MockError.prepareStackTrace;
- const result = prepareStackTrace(new Error("foo"), [
- getMockCallSite("CLI_SNAPSHOT.js", 23, 0)
- ]);
- assert(result.startsWith("Error: foo\n"));
- assert(result.includes(".ts:"), "should remap to something in 'js/'");
-});
-
-test(function applySourceMap(): void {
- const result = Deno.applySourceMap({
- filename: "CLI_SNAPSHOT.js",
- line: 23,
- column: 0
- });
- assert(result.filename.endsWith(".ts"));
- assert(result.line != null);
- assert(result.column != null);
-});
diff --git a/js/errors.ts b/js/errors.ts
deleted file mode 100644
index 02ddfa2f2..000000000
--- a/js/errors.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-/** 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 {
- constructor(readonly kind: T, msg: string) {
- super(msg);
- this.name = ErrorKind[kind];
- }
-}
-
-// Warning! The values in this enum are duplicated in cli/msg.rs
-// Update carefully!
-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
-}
diff --git a/js/event.ts b/js/event.ts
deleted file mode 100644
index 3efc1c517..000000000
--- a/js/event.ts
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as domTypes from "./dom_types.ts";
-import { getPrivateValue, requiredArguments } from "./util.ts";
-
-// WeakMaps are recommended for private attributes (see MDN link below)
-// https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Add-on_SDK/Guides/Contributor_s_Guide/Private_Properties#Using_WeakMaps
-export const eventAttributes = new WeakMap();
-
-function isTrusted(this: Event): boolean {
- return getPrivateValue(this, eventAttributes, "isTrusted");
-}
-
-export class Event implements domTypes.Event {
- // The default value is `false`.
- // Use `defineProperty` to define on each instance, NOT on the prototype.
- isTrusted!: boolean;
- // Each event has the following associated flags
- private _canceledFlag = false;
- private _dispatchedFlag = false;
- private _initializedFlag = false;
- private _inPassiveListenerFlag = false;
- private _stopImmediatePropagationFlag = false;
- private _stopPropagationFlag = false;
-
- // Property for objects on which listeners will be invoked
- private _path: domTypes.EventPath[] = [];
-
- constructor(type: string, eventInitDict: domTypes.EventInit = {}) {
- requiredArguments("Event", arguments.length, 1);
- type = String(type);
- this._initializedFlag = true;
- eventAttributes.set(this, {
- type,
- bubbles: eventInitDict.bubbles || false,
- cancelable: eventInitDict.cancelable || false,
- composed: eventInitDict.composed || false,
- currentTarget: null,
- eventPhase: domTypes.EventPhase.NONE,
- isTrusted: false,
- relatedTarget: null,
- target: null,
- timeStamp: Date.now()
- });
- Reflect.defineProperty(this, "isTrusted", {
- enumerable: true,
- get: isTrusted
- });
- }
-
- get bubbles(): boolean {
- return getPrivateValue(this, eventAttributes, "bubbles");
- }
-
- get cancelBubble(): boolean {
- return this._stopPropagationFlag;
- }
-
- set cancelBubble(value: boolean) {
- this._stopPropagationFlag = value;
- }
-
- get cancelBubbleImmediately(): boolean {
- return this._stopImmediatePropagationFlag;
- }
-
- set cancelBubbleImmediately(value: boolean) {
- this._stopImmediatePropagationFlag = value;
- }
-
- get cancelable(): boolean {
- return getPrivateValue(this, eventAttributes, "cancelable");
- }
-
- get composed(): boolean {
- return getPrivateValue(this, eventAttributes, "composed");
- }
-
- get currentTarget(): domTypes.EventTarget {
- return getPrivateValue(this, eventAttributes, "currentTarget");
- }
-
- set currentTarget(value: domTypes.EventTarget) {
- eventAttributes.set(this, {
- type: this.type,
- bubbles: this.bubbles,
- cancelable: this.cancelable,
- composed: this.composed,
- currentTarget: value,
- eventPhase: this.eventPhase,
- isTrusted: this.isTrusted,
- relatedTarget: this.relatedTarget,
- target: this.target,
- timeStamp: this.timeStamp
- });
- }
-
- get defaultPrevented(): boolean {
- return this._canceledFlag;
- }
-
- get dispatched(): boolean {
- return this._dispatchedFlag;
- }
-
- set dispatched(value: boolean) {
- this._dispatchedFlag = value;
- }
-
- get eventPhase(): number {
- return getPrivateValue(this, eventAttributes, "eventPhase");
- }
-
- set eventPhase(value: number) {
- eventAttributes.set(this, {
- type: this.type,
- bubbles: this.bubbles,
- cancelable: this.cancelable,
- composed: this.composed,
- currentTarget: this.currentTarget,
- eventPhase: value,
- isTrusted: this.isTrusted,
- relatedTarget: this.relatedTarget,
- target: this.target,
- timeStamp: this.timeStamp
- });
- }
-
- get initialized(): boolean {
- return this._initializedFlag;
- }
-
- set inPassiveListener(value: boolean) {
- this._inPassiveListenerFlag = value;
- }
-
- get path(): domTypes.EventPath[] {
- return this._path;
- }
-
- set path(value: domTypes.EventPath[]) {
- this._path = value;
- }
-
- get relatedTarget(): domTypes.EventTarget {
- return getPrivateValue(this, eventAttributes, "relatedTarget");
- }
-
- set relatedTarget(value: domTypes.EventTarget) {
- eventAttributes.set(this, {
- type: this.type,
- bubbles: this.bubbles,
- cancelable: this.cancelable,
- composed: this.composed,
- currentTarget: this.currentTarget,
- eventPhase: this.eventPhase,
- isTrusted: this.isTrusted,
- relatedTarget: value,
- target: this.target,
- timeStamp: this.timeStamp
- });
- }
-
- get target(): domTypes.EventTarget {
- return getPrivateValue(this, eventAttributes, "target");
- }
-
- set target(value: domTypes.EventTarget) {
- eventAttributes.set(this, {
- type: this.type,
- bubbles: this.bubbles,
- cancelable: this.cancelable,
- composed: this.composed,
- currentTarget: this.currentTarget,
- eventPhase: this.eventPhase,
- isTrusted: this.isTrusted,
- relatedTarget: this.relatedTarget,
- target: value,
- timeStamp: this.timeStamp
- });
- }
-
- get timeStamp(): Date {
- return getPrivateValue(this, eventAttributes, "timeStamp");
- }
-
- get type(): string {
- return getPrivateValue(this, eventAttributes, "type");
- }
-
- /** 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[] {
- if (this._path.length === 0) {
- return [];
- }
-
- const composedPath: domTypes.EventPath[] = [
- {
- item: this.currentTarget,
- itemInShadowTree: false,
- relatedTarget: null,
- rootOfClosedTree: false,
- slotInClosedTree: false,
- target: null,
- touchTargetList: []
- }
- ];
-
- let currentTargetIndex = 0;
- let currentTargetHiddenSubtreeLevel = 0;
-
- for (let index = this._path.length - 1; index >= 0; index--) {
- const { item, rootOfClosedTree, slotInClosedTree } = this._path[index];
-
- if (rootOfClosedTree) {
- currentTargetHiddenSubtreeLevel++;
- }
-
- if (item === this.currentTarget) {
- currentTargetIndex = index;
- break;
- }
-
- if (slotInClosedTree) {
- currentTargetHiddenSubtreeLevel--;
- }
- }
-
- let currentHiddenLevel = currentTargetHiddenSubtreeLevel;
- let maxHiddenLevel = currentTargetHiddenSubtreeLevel;
-
- for (let i = currentTargetIndex - 1; i >= 0; i--) {
- const { item, rootOfClosedTree, slotInClosedTree } = this._path[i];
-
- if (rootOfClosedTree) {
- currentHiddenLevel++;
- }
-
- if (currentHiddenLevel <= maxHiddenLevel) {
- composedPath.unshift({
- item,
- itemInShadowTree: false,
- relatedTarget: null,
- rootOfClosedTree: false,
- slotInClosedTree: false,
- target: null,
- touchTargetList: []
- });
- }
-
- if (slotInClosedTree) {
- currentHiddenLevel--;
-
- if (currentHiddenLevel < maxHiddenLevel) {
- maxHiddenLevel = currentHiddenLevel;
- }
- }
- }
-
- currentHiddenLevel = currentTargetHiddenSubtreeLevel;
- maxHiddenLevel = currentTargetHiddenSubtreeLevel;
-
- for (
- let index = currentTargetIndex + 1;
- index < this._path.length;
- index++
- ) {
- const { item, rootOfClosedTree, slotInClosedTree } = this._path[index];
-
- if (slotInClosedTree) {
- currentHiddenLevel++;
- }
-
- if (currentHiddenLevel <= maxHiddenLevel) {
- composedPath.push({
- item,
- itemInShadowTree: false,
- relatedTarget: null,
- rootOfClosedTree: false,
- slotInClosedTree: false,
- target: null,
- touchTargetList: []
- });
- }
-
- if (rootOfClosedTree) {
- currentHiddenLevel--;
-
- if (currentHiddenLevel < maxHiddenLevel) {
- maxHiddenLevel = currentHiddenLevel;
- }
- }
- }
-
- return composedPath;
- }
-
- /** Cancels the event (if it is cancelable).
- * See https://dom.spec.whatwg.org/#set-the-canceled-flag
- *
- * event.preventDefault();
- */
- preventDefault(): void {
- if (this.cancelable && !this._inPassiveListenerFlag) {
- this._canceledFlag = true;
- }
- }
-
- /** Stops the propagation of events further along in the DOM.
- *
- * event.stopPropagation();
- */
- stopPropagation(): void {
- this._stopPropagationFlag = true;
- }
-
- /** 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 {
- this._stopPropagationFlag = true;
- this._stopImmediatePropagationFlag = true;
- }
-}
-
-/** Built-in objects providing `get` methods for our
- * interceptable JavaScript operations.
- */
-Reflect.defineProperty(Event.prototype, "bubbles", { enumerable: true });
-Reflect.defineProperty(Event.prototype, "cancelable", { enumerable: true });
-Reflect.defineProperty(Event.prototype, "composed", { enumerable: true });
-Reflect.defineProperty(Event.prototype, "currentTarget", { enumerable: true });
-Reflect.defineProperty(Event.prototype, "defaultPrevented", {
- enumerable: true
-});
-Reflect.defineProperty(Event.prototype, "dispatched", { enumerable: true });
-Reflect.defineProperty(Event.prototype, "eventPhase", { enumerable: true });
-Reflect.defineProperty(Event.prototype, "target", { enumerable: true });
-Reflect.defineProperty(Event.prototype, "timeStamp", { enumerable: true });
-Reflect.defineProperty(Event.prototype, "type", { enumerable: true });
diff --git a/js/event_target.ts b/js/event_target.ts
deleted file mode 100644
index 08c39544c..000000000
--- a/js/event_target.ts
+++ /dev/null
@@ -1,503 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as domTypes from "./dom_types.ts";
-import { DenoError, ErrorKind } from "./errors.ts";
-import { hasOwnProperty, requiredArguments } from "./util.ts";
-import {
- getRoot,
- isNode,
- isShadowRoot,
- isShadowInclusiveAncestor,
- isSlotable,
- retarget
-} from "./dom_util.ts";
-import { window } from "./window.ts";
-
-// https://dom.spec.whatwg.org/#get-the-parent
-// Note: Nodes, shadow roots, and documents override this algorithm so we set it to null.
-function getEventTargetParent(
- _eventTarget: domTypes.EventTarget,
- _event: domTypes.Event
-): null {
- return null;
-}
-
-export const eventTargetAssignedSlot: unique symbol = Symbol();
-export const eventTargetHasActivationBehavior: unique symbol = Symbol();
-
-export class EventTarget implements domTypes.EventTarget {
- public [domTypes.eventTargetHost]: domTypes.EventTarget | null = null;
- public [domTypes.eventTargetListeners]: {
- [type in string]: domTypes.EventListener[]
- } = {};
- public [domTypes.eventTargetMode] = "";
- public [domTypes.eventTargetNodeType]: domTypes.NodeType =
- domTypes.NodeType.DOCUMENT_FRAGMENT_NODE;
- private [eventTargetAssignedSlot] = false;
- private [eventTargetHasActivationBehavior] = false;
-
- public addEventListener(
- type: string,
- callback: (event: domTypes.Event) => void | null,
- options?: domTypes.AddEventListenerOptions | boolean
- ): void {
- const this_ = this || window;
-
- requiredArguments("EventTarget.addEventListener", arguments.length, 2);
- const normalizedOptions: domTypes.AddEventListenerOptions = eventTargetHelpers.normalizeAddEventHandlerOptions(
- options
- );
-
- if (callback === null) {
- return;
- }
-
- const listeners = this_[domTypes.eventTargetListeners];
-
- if (!hasOwnProperty(listeners, type)) {
- listeners[type] = [];
- }
-
- for (let i = 0; i < listeners[type].length; ++i) {
- const listener = listeners[type][i];
- if (
- ((typeof listener.options === "boolean" &&
- listener.options === normalizedOptions.capture) ||
- (typeof listener.options === "object" &&
- listener.options.capture === normalizedOptions.capture)) &&
- listener.callback === callback
- ) {
- return;
- }
- }
-
- // eslint-disable-next-line @typescript-eslint/no-this-alias
- const eventTarget = this;
- listeners[type].push({
- callback,
- options: normalizedOptions,
- handleEvent(event: domTypes.Event): void {
- this.callback.call(eventTarget, event);
- }
- } as domTypes.EventListener);
- }
-
- public removeEventListener(
- type: string,
- callback: (event: domTypes.Event) => void | null,
- options?: domTypes.EventListenerOptions | boolean
- ): void {
- const this_ = this || window;
-
- requiredArguments("EventTarget.removeEventListener", arguments.length, 2);
- const listeners = this_[domTypes.eventTargetListeners];
- if (hasOwnProperty(listeners, type) && callback !== null) {
- listeners[type] = listeners[type].filter(
- (listener): boolean => listener.callback !== callback
- );
- }
-
- const normalizedOptions: domTypes.EventListenerOptions = eventTargetHelpers.normalizeEventHandlerOptions(
- options
- );
-
- if (callback === null) {
- // Optimization, not in the spec.
- return;
- }
-
- if (!listeners[type]) {
- return;
- }
-
- for (let i = 0; i < listeners[type].length; ++i) {
- const listener = listeners[type][i];
-
- if (
- ((typeof listener.options === "boolean" &&
- listener.options === normalizedOptions.capture) ||
- (typeof listener.options === "object" &&
- listener.options.capture === normalizedOptions.capture)) &&
- listener.callback === callback
- ) {
- listeners[type].splice(i, 1);
- break;
- }
- }
- }
-
- public dispatchEvent(event: domTypes.Event): boolean {
- const this_ = this || window;
-
- requiredArguments("EventTarget.dispatchEvent", arguments.length, 1);
- const listeners = this_[domTypes.eventTargetListeners];
- if (!hasOwnProperty(listeners, event.type)) {
- return true;
- }
-
- if (event.dispatched || !event.initialized) {
- throw new DenoError(
- ErrorKind.InvalidData,
- "Tried to dispatch an uninitialized event"
- );
- }
-
- if (event.eventPhase !== domTypes.EventPhase.NONE) {
- throw new DenoError(
- ErrorKind.InvalidData,
- "Tried to dispatch a dispatching event"
- );
- }
-
- return eventTargetHelpers.dispatch(this_, event);
- }
-
- get [Symbol.toStringTag](): string {
- return "EventTarget";
- }
-}
-
-const eventTargetHelpers = {
- // https://dom.spec.whatwg.org/#concept-event-dispatch
- dispatch(
- targetImpl: EventTarget,
- eventImpl: domTypes.Event,
- targetOverride?: domTypes.EventTarget
- ): boolean {
- let clearTargets = false;
- let activationTarget = null;
-
- eventImpl.dispatched = true;
-
- targetOverride = targetOverride || targetImpl;
- let relatedTarget = retarget(eventImpl.relatedTarget, targetImpl);
-
- if (
- targetImpl !== relatedTarget ||
- targetImpl === eventImpl.relatedTarget
- ) {
- const touchTargets: domTypes.EventTarget[] = [];
-
- eventTargetHelpers.appendToEventPath(
- eventImpl,
- targetImpl,
- targetOverride,
- relatedTarget,
- touchTargets,
- false
- );
-
- const isActivationEvent = eventImpl.type === "click";
-
- if (isActivationEvent && targetImpl[eventTargetHasActivationBehavior]) {
- activationTarget = targetImpl;
- }
-
- let slotInClosedTree = false;
- let slotable =
- isSlotable(targetImpl) && targetImpl[eventTargetAssignedSlot]
- ? targetImpl
- : null;
- let parent = getEventTargetParent(targetImpl, eventImpl);
-
- // Populate event path
- // https://dom.spec.whatwg.org/#event-path
- while (parent !== null) {
- if (slotable !== null) {
- slotable = null;
-
- const parentRoot = getRoot(parent);
- if (
- isShadowRoot(parentRoot) &&
- parentRoot &&
- parentRoot[domTypes.eventTargetMode] === "closed"
- ) {
- slotInClosedTree = true;
- }
- }
-
- relatedTarget = retarget(eventImpl.relatedTarget, parent);
-
- if (
- isNode(parent) &&
- isShadowInclusiveAncestor(getRoot(targetImpl), parent)
- ) {
- eventTargetHelpers.appendToEventPath(
- eventImpl,
- parent,
- null,
- relatedTarget,
- touchTargets,
- slotInClosedTree
- );
- } else if (parent === relatedTarget) {
- parent = null;
- } else {
- targetImpl = parent;
-
- if (
- isActivationEvent &&
- activationTarget === null &&
- targetImpl[eventTargetHasActivationBehavior]
- ) {
- activationTarget = targetImpl;
- }
-
- eventTargetHelpers.appendToEventPath(
- eventImpl,
- parent,
- targetImpl,
- relatedTarget,
- touchTargets,
- slotInClosedTree
- );
- }
-
- if (parent !== null) {
- parent = getEventTargetParent(parent, eventImpl);
- }
-
- slotInClosedTree = false;
- }
-
- let clearTargetsTupleIndex = -1;
- for (
- let i = eventImpl.path.length - 1;
- i >= 0 && clearTargetsTupleIndex === -1;
- i--
- ) {
- if (eventImpl.path[i].target !== null) {
- clearTargetsTupleIndex = i;
- }
- }
- const clearTargetsTuple = eventImpl.path[clearTargetsTupleIndex];
-
- clearTargets =
- (isNode(clearTargetsTuple.target) &&
- isShadowRoot(getRoot(clearTargetsTuple.target))) ||
- (isNode(clearTargetsTuple.relatedTarget) &&
- isShadowRoot(getRoot(clearTargetsTuple.relatedTarget)));
-
- eventImpl.eventPhase = domTypes.EventPhase.CAPTURING_PHASE;
-
- for (let i = eventImpl.path.length - 1; i >= 0; --i) {
- const tuple = eventImpl.path[i];
-
- if (tuple.target === null) {
- eventTargetHelpers.invokeEventListeners(targetImpl, tuple, eventImpl);
- }
- }
-
- for (let i = 0; i < eventImpl.path.length; i++) {
- const tuple = eventImpl.path[i];
-
- if (tuple.target !== null) {
- eventImpl.eventPhase = domTypes.EventPhase.AT_TARGET;
- } else {
- eventImpl.eventPhase = domTypes.EventPhase.BUBBLING_PHASE;
- }
-
- if (
- (eventImpl.eventPhase === domTypes.EventPhase.BUBBLING_PHASE &&
- eventImpl.bubbles) ||
- eventImpl.eventPhase === domTypes.EventPhase.AT_TARGET
- ) {
- eventTargetHelpers.invokeEventListeners(targetImpl, tuple, eventImpl);
- }
- }
- }
-
- eventImpl.eventPhase = domTypes.EventPhase.NONE;
-
- eventImpl.currentTarget = null;
- eventImpl.path = [];
- eventImpl.dispatched = false;
- eventImpl.cancelBubble = false;
- eventImpl.cancelBubbleImmediately = false;
-
- if (clearTargets) {
- eventImpl.target = null;
- eventImpl.relatedTarget = null;
- }
-
- // TODO: invoke activation targets if HTML nodes will be implemented
- // if (activationTarget !== null) {
- // if (!eventImpl.defaultPrevented) {
- // activationTarget._activationBehavior();
- // }
- // }
-
- return !eventImpl.defaultPrevented;
- },
-
- // https://dom.spec.whatwg.org/#concept-event-listener-invoke
- invokeEventListeners(
- targetImpl: EventTarget,
- tuple: domTypes.EventPath,
- eventImpl: domTypes.Event
- ): void {
- const tupleIndex = eventImpl.path.indexOf(tuple);
- for (let i = tupleIndex; i >= 0; i--) {
- const t = eventImpl.path[i];
- if (t.target) {
- eventImpl.target = t.target;
- break;
- }
- }
-
- eventImpl.relatedTarget = tuple.relatedTarget;
-
- if (eventImpl.cancelBubble) {
- return;
- }
-
- eventImpl.currentTarget = tuple.item;
-
- eventTargetHelpers.innerInvokeEventListeners(
- targetImpl,
- eventImpl,
- tuple.item[domTypes.eventTargetListeners]
- );
- },
-
- // https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
- innerInvokeEventListeners(
- targetImpl: EventTarget,
- eventImpl: domTypes.Event,
- targetListeners: { [type in string]: domTypes.EventListener[] }
- ): boolean {
- let found = false;
-
- const { type } = eventImpl;
-
- if (!targetListeners || !targetListeners[type]) {
- return found;
- }
-
- // Copy event listeners before iterating since the list can be modified during the iteration.
- const handlers = targetListeners[type].slice();
-
- for (let i = 0; i < handlers.length; i++) {
- const listener = handlers[i];
-
- let capture, once, passive;
- if (typeof listener.options === "boolean") {
- capture = listener.options;
- once = false;
- passive = false;
- } else {
- capture = listener.options.capture;
- once = listener.options.once;
- passive = listener.options.passive;
- }
-
- // Check if the event listener has been removed since the listeners has been cloned.
- if (!targetListeners[type].includes(listener)) {
- continue;
- }
-
- found = true;
-
- if (
- (eventImpl.eventPhase === domTypes.EventPhase.CAPTURING_PHASE &&
- !capture) ||
- (eventImpl.eventPhase === domTypes.EventPhase.BUBBLING_PHASE && capture)
- ) {
- continue;
- }
-
- if (once) {
- targetListeners[type].splice(
- targetListeners[type].indexOf(listener),
- 1
- );
- }
-
- if (passive) {
- eventImpl.inPassiveListener = true;
- }
-
- try {
- if (listener.callback) {
- listener.handleEvent(eventImpl);
- }
- } catch (error) {
- throw new DenoError(ErrorKind.Interrupted, error.message);
- }
-
- eventImpl.inPassiveListener = false;
-
- if (eventImpl.cancelBubbleImmediately) {
- return found;
- }
- }
-
- return found;
- },
-
- normalizeAddEventHandlerOptions(
- options: boolean | domTypes.AddEventListenerOptions | undefined
- ): domTypes.AddEventListenerOptions {
- if (typeof options === "boolean" || typeof options === "undefined") {
- const returnValue: domTypes.AddEventListenerOptions = {
- capture: Boolean(options),
- once: false,
- passive: false
- };
-
- return returnValue;
- } else {
- return options;
- }
- },
-
- normalizeEventHandlerOptions(
- options: boolean | domTypes.EventListenerOptions | undefined
- ): domTypes.EventListenerOptions {
- if (typeof options === "boolean" || typeof options === "undefined") {
- const returnValue: domTypes.EventListenerOptions = {
- capture: Boolean(options)
- };
-
- return returnValue;
- } else {
- return options;
- }
- },
-
- // https://dom.spec.whatwg.org/#concept-event-path-append
- appendToEventPath(
- eventImpl: domTypes.Event,
- target: domTypes.EventTarget,
- targetOverride: domTypes.EventTarget | null,
- relatedTarget: domTypes.EventTarget | null,
- touchTargets: domTypes.EventTarget[],
- slotInClosedTree: boolean
- ): void {
- const itemInShadowTree = isNode(target) && isShadowRoot(getRoot(target));
- const rootOfClosedTree =
- isShadowRoot(target) && target[domTypes.eventTargetMode] === "closed";
-
- eventImpl.path.push({
- item: target,
- itemInShadowTree,
- target: targetOverride,
- relatedTarget,
- touchTargetList: touchTargets,
- rootOfClosedTree,
- slotInClosedTree
- });
- }
-};
-
-/** Built-in objects providing `get` methods for our
- * interceptable JavaScript operations.
- */
-Reflect.defineProperty(EventTarget.prototype, "addEventListener", {
- enumerable: true
-});
-Reflect.defineProperty(EventTarget.prototype, "removeEventListener", {
- enumerable: true
-});
-Reflect.defineProperty(EventTarget.prototype, "dispatchEvent", {
- enumerable: true
-});
diff --git a/js/event_target_test.ts b/js/event_target_test.ts
deleted file mode 100644
index 9d7e7974c..000000000
--- a/js/event_target_test.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assertEquals } from "./test_util.ts";
-
-test(function addEventListenerTest(): void {
- const document = new EventTarget();
-
- assertEquals(document.addEventListener("x", null, false), undefined);
- assertEquals(document.addEventListener("x", null, true), undefined);
- assertEquals(document.addEventListener("x", null), undefined);
-});
-
-test(function constructedEventTargetCanBeUsedAsExpected(): void {
- const target = new EventTarget();
- const event = new Event("foo", { bubbles: true, cancelable: false });
- let callCount = 0;
-
- const listener = (e): void => {
- assertEquals(e, event);
- ++callCount;
- };
-
- target.addEventListener("foo", listener);
-
- target.dispatchEvent(event);
- assertEquals(callCount, 1);
-
- target.dispatchEvent(event);
- assertEquals(callCount, 2);
-
- target.removeEventListener("foo", listener);
- target.dispatchEvent(event);
- assertEquals(callCount, 2);
-});
-
-test(function anEventTargetCanBeSubclassed(): void {
- class NicerEventTarget extends EventTarget {
- on(type, callback?, options?): void {
- this.addEventListener(type, callback, options);
- }
-
- off(type, callback?, options?): void {
- this.removeEventListener(type, callback, options);
- }
- }
-
- const target = new NicerEventTarget();
- new Event("foo", { bubbles: true, cancelable: false });
- let callCount = 0;
-
- const listener = (): void => {
- ++callCount;
- };
-
- target.on("foo", listener);
- assertEquals(callCount, 0);
-
- target.off("foo", listener);
- assertEquals(callCount, 0);
-});
-
-test(function removingNullEventListenerShouldSucceed(): void {
- const document = new EventTarget();
- assertEquals(document.removeEventListener("x", null, false), undefined);
- assertEquals(document.removeEventListener("x", null, true), undefined);
- assertEquals(document.removeEventListener("x", null), undefined);
-});
-
-test(function constructedEventTargetUseObjectPrototype(): void {
- const target = new EventTarget();
- const event = new Event("toString", { bubbles: true, cancelable: false });
- let callCount = 0;
-
- const listener = (e): void => {
- assertEquals(e, event);
- ++callCount;
- };
-
- target.addEventListener("toString", listener);
-
- target.dispatchEvent(event);
- assertEquals(callCount, 1);
-
- target.dispatchEvent(event);
- assertEquals(callCount, 2);
-
- target.removeEventListener("toString", listener);
- target.dispatchEvent(event);
- assertEquals(callCount, 2);
-});
-
-test(function toStringShouldBeWebCompatible(): void {
- const target = new EventTarget();
- assertEquals(target.toString(), "[object EventTarget]");
-});
-
-test(function dispatchEventShouldNotThrowError(): void {
- let hasThrown = false;
-
- try {
- const target = new EventTarget();
- const event = new Event("hasOwnProperty", {
- bubbles: true,
- cancelable: false
- });
- const listener = (): void => {};
- target.addEventListener("hasOwnProperty", listener);
- target.dispatchEvent(event);
- } catch {
- hasThrown = true;
- }
-
- assertEquals(hasThrown, false);
-});
-
-test(function eventTargetThisShouldDefaultToWindow(): void {
- const {
- addEventListener,
- dispatchEvent,
- removeEventListener
- } = EventTarget.prototype;
- let n = 1;
- const event = new Event("hello");
- const listener = (): void => {
- n = 2;
- };
-
- addEventListener("hello", listener);
- window.dispatchEvent(event);
- assertEquals(n, 2);
- n = 1;
- removeEventListener("hello", listener);
- window.dispatchEvent(event);
- assertEquals(n, 1);
-
- window.addEventListener("hello", listener);
- dispatchEvent(event);
- assertEquals(n, 2);
- n = 1;
- window.removeEventListener("hello", listener);
- dispatchEvent(event);
- assertEquals(n, 1);
-});
diff --git a/js/event_test.ts b/js/event_test.ts
deleted file mode 100644
index 72f4f5855..000000000
--- a/js/event_test.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assertEquals, assertNotEquals } from "./test_util.ts";
-
-test(function eventInitializedWithType(): void {
- const type = "click";
- const event = new Event(type);
-
- assertEquals(event.isTrusted, false);
- assertEquals(event.target, null);
- assertEquals(event.currentTarget, null);
- assertEquals(event.type, "click");
- assertEquals(event.bubbles, false);
- assertEquals(event.cancelable, false);
-});
-
-test(function eventInitializedWithTypeAndDict(): void {
- const init = "submit";
- const eventInit = { bubbles: true, cancelable: true } as EventInit;
- const event = new Event(init, eventInit);
-
- assertEquals(event.isTrusted, false);
- assertEquals(event.target, null);
- assertEquals(event.currentTarget, null);
- assertEquals(event.type, "submit");
- assertEquals(event.bubbles, true);
- assertEquals(event.cancelable, true);
-});
-
-test(function eventComposedPathSuccess(): void {
- const type = "click";
- const event = new Event(type);
- const composedPath = event.composedPath();
-
- assertEquals(composedPath, []);
-});
-
-test(function eventStopPropagationSuccess(): void {
- const type = "click";
- const event = new Event(type);
-
- assertEquals(event.cancelBubble, false);
- event.stopPropagation();
- assertEquals(event.cancelBubble, true);
-});
-
-test(function eventStopImmediatePropagationSuccess(): void {
- const type = "click";
- const event = new Event(type);
-
- assertEquals(event.cancelBubble, false);
- assertEquals(event.cancelBubbleImmediately, false);
- event.stopImmediatePropagation();
- assertEquals(event.cancelBubble, true);
- assertEquals(event.cancelBubbleImmediately, true);
-});
-
-test(function eventPreventDefaultSuccess(): void {
- const type = "click";
- const event = new Event(type);
-
- assertEquals(event.defaultPrevented, false);
- event.preventDefault();
- assertEquals(event.defaultPrevented, false);
-
- const eventInit = { bubbles: true, cancelable: true } as EventInit;
- const cancelableEvent = new Event(type, eventInit);
- assertEquals(cancelableEvent.defaultPrevented, false);
- cancelableEvent.preventDefault();
- assertEquals(cancelableEvent.defaultPrevented, true);
-});
-
-test(function eventInitializedWithNonStringType(): void {
- const type = undefined;
- const event = new Event(type);
-
- assertEquals(event.isTrusted, false);
- assertEquals(event.target, null);
- assertEquals(event.currentTarget, null);
- assertEquals(event.type, "undefined");
- assertEquals(event.bubbles, false);
- assertEquals(event.cancelable, false);
-});
-
-// ref https://github.com/web-platform-tests/wpt/blob/master/dom/events/Event-isTrusted.any.js
-test(function eventIsTrusted(): void {
- const desc1 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted");
- assertNotEquals(desc1, undefined);
- assertEquals(typeof desc1.get, "function");
-
- const desc2 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted");
- assertNotEquals(desc2, undefined);
- assertEquals(typeof desc2.get, "function");
-
- assertEquals(desc1.get, desc2.get);
-});
diff --git a/js/fetch.ts b/js/fetch.ts
deleted file mode 100644
index 0a5f793a8..000000000
--- a/js/fetch.ts
+++ /dev/null
@@ -1,478 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import {
- assert,
- createResolvable,
- notImplemented,
- isTypedArray
-} from "./util.ts";
-import * as domTypes from "./dom_types.ts";
-import { TextDecoder, TextEncoder } from "./text_encoding.ts";
-import { DenoBlob, bytesSymbol as blobBytesSymbol } from "./blob.ts";
-import { Headers } from "./headers.ts";
-import * as io from "./io.ts";
-import { read, close } from "./files.ts";
-import { Buffer } from "./buffer.ts";
-import { FormData } from "./form_data.ts";
-import { URLSearchParams } from "./url_search_params.ts";
-import * as dispatch from "./dispatch.ts";
-import { sendAsync } from "./dispatch_json.ts";
-
-function getHeaderValueParams(value: string): Map<string, string> {
- const params = new Map();
- // Forced to do so for some Map constructor param mismatch
- value
- .split(";")
- .slice(1)
- .map((s): string[] => s.trim().split("="))
- .filter((arr): boolean => arr.length > 1)
- .map(([k, v]): [string, string] => [k, v.replace(/^"([^"]*)"$/, "$1")])
- .forEach(([k, v]): Map<string, string> => params.set(k, v));
- return params;
-}
-
-function hasHeaderValueOf(s: string, value: string): boolean {
- return new RegExp(`^${value}[\t\s]*;?`).test(s);
-}
-
-class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser {
- private _bodyUsed = false;
- private _bodyPromise: null | Promise<ArrayBuffer> = null;
- private _data: ArrayBuffer | null = null;
- readonly locked: boolean = false; // TODO
- readonly body: null | Body = this;
-
- constructor(private rid: number, readonly contentType: string) {}
-
- private async _bodyBuffer(): Promise<ArrayBuffer> {
- assert(this._bodyPromise == null);
- const buf = new Buffer();
- try {
- const nread = await buf.readFrom(this);
- const ui8 = buf.bytes();
- assert(ui8.byteLength === nread);
- this._data = ui8.buffer.slice(
- ui8.byteOffset,
- ui8.byteOffset + nread
- ) as ArrayBuffer;
- assert(this._data.byteLength === nread);
- } finally {
- this.close();
- }
-
- return this._data;
- }
-
- async arrayBuffer(): Promise<ArrayBuffer> {
- // If we've already bufferred the response, just return it.
- if (this._data != null) {
- return this._data;
- }
-
- // If there is no _bodyPromise yet, start it.
- if (this._bodyPromise == null) {
- this._bodyPromise = this._bodyBuffer();
- }
-
- return this._bodyPromise;
- }
-
- async blob(): Promise<domTypes.Blob> {
- const arrayBuffer = await this.arrayBuffer();
- return new DenoBlob([arrayBuffer], {
- type: this.contentType
- });
- }
-
- // ref: https://fetch.spec.whatwg.org/#body-mixin
- async formData(): Promise<domTypes.FormData> {
- const formData = new FormData();
- const enc = new TextEncoder();
- if (hasHeaderValueOf(this.contentType, "multipart/form-data")) {
- const params = getHeaderValueParams(this.contentType);
- if (!params.has("boundary")) {
- // TypeError is required by spec
- throw new TypeError("multipart/form-data must provide a boundary");
- }
- // ref: https://tools.ietf.org/html/rfc2046#section-5.1
- const boundary = params.get("boundary")!;
- const dashBoundary = `--${boundary}`;
- const delimiter = `\r\n${dashBoundary}`;
- const closeDelimiter = `${delimiter}--`;
-
- const body = await this.text();
- let bodyParts: string[];
- const bodyEpilogueSplit = body.split(closeDelimiter);
- if (bodyEpilogueSplit.length < 2) {
- bodyParts = [];
- } else {
- // discard epilogue
- const bodyEpilogueTrimmed = bodyEpilogueSplit[0];
- // first boundary treated special due to optional prefixed \r\n
- const firstBoundaryIndex = bodyEpilogueTrimmed.indexOf(dashBoundary);
- if (firstBoundaryIndex < 0) {
- throw new TypeError("Invalid boundary");
- }
- const bodyPreambleTrimmed = bodyEpilogueTrimmed
- .slice(firstBoundaryIndex + dashBoundary.length)
- .replace(/^[\s\r\n\t]+/, ""); // remove transport-padding CRLF
- // trimStart might not be available
- // Be careful! body-part allows trailing \r\n!
- // (as long as it is not part of `delimiter`)
- bodyParts = bodyPreambleTrimmed
- .split(delimiter)
- .map((s): string => s.replace(/^[\s\r\n\t]+/, ""));
- // TODO: LWSP definition is actually trickier,
- // but should be fine in our case since without headers
- // we should just discard the part
- }
- for (const bodyPart of bodyParts) {
- const headers = new Headers();
- const headerOctetSeperatorIndex = bodyPart.indexOf("\r\n\r\n");
- if (headerOctetSeperatorIndex < 0) {
- continue; // Skip unknown part
- }
- const headerText = bodyPart.slice(0, headerOctetSeperatorIndex);
- const octets = bodyPart.slice(headerOctetSeperatorIndex + 4);
-
- // TODO: use textproto.readMIMEHeader from deno_std
- const rawHeaders = headerText.split("\r\n");
- for (const rawHeader of rawHeaders) {
- const sepIndex = rawHeader.indexOf(":");
- if (sepIndex < 0) {
- continue; // Skip this header
- }
- const key = rawHeader.slice(0, sepIndex);
- const value = rawHeader.slice(sepIndex + 1);
- headers.set(key, value);
- }
- if (!headers.has("content-disposition")) {
- continue; // Skip unknown part
- }
- // Content-Transfer-Encoding Deprecated
- const contentDisposition = headers.get("content-disposition")!;
- const partContentType = headers.get("content-type") || "text/plain";
- // TODO: custom charset encoding (needs TextEncoder support)
- // const contentTypeCharset =
- // getHeaderValueParams(partContentType).get("charset") || "";
- if (!hasHeaderValueOf(contentDisposition, "form-data")) {
- continue; // Skip, might not be form-data
- }
- const dispositionParams = getHeaderValueParams(contentDisposition);
- if (!dispositionParams.has("name")) {
- continue; // Skip, unknown name
- }
- const dispositionName = dispositionParams.get("name")!;
- if (dispositionParams.has("filename")) {
- const filename = dispositionParams.get("filename")!;
- const blob = new DenoBlob([enc.encode(octets)], {
- type: partContentType
- });
- // TODO: based on spec
- // https://xhr.spec.whatwg.org/#dom-formdata-append
- // https://xhr.spec.whatwg.org/#create-an-entry
- // Currently it does not mention how I could pass content-type
- // to the internally created file object...
- formData.append(dispositionName, blob, filename);
- } else {
- formData.append(dispositionName, octets);
- }
- }
- return formData;
- } else if (
- hasHeaderValueOf(this.contentType, "application/x-www-form-urlencoded")
- ) {
- // From https://github.com/github/fetch/blob/master/fetch.js
- // Copyright (c) 2014-2016 GitHub, Inc. MIT License
- const body = await this.text();
- try {
- body
- .trim()
- .split("&")
- .forEach(
- (bytes): void => {
- if (bytes) {
- const split = bytes.split("=");
- const name = split.shift()!.replace(/\+/g, " ");
- const value = split.join("=").replace(/\+/g, " ");
- formData.append(
- decodeURIComponent(name),
- decodeURIComponent(value)
- );
- }
- }
- );
- } catch (e) {
- throw new TypeError("Invalid form urlencoded format");
- }
- return formData;
- } else {
- throw new TypeError("Invalid form data");
- }
- }
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- async json(): Promise<any> {
- const text = await this.text();
- return JSON.parse(text);
- }
-
- async text(): Promise<string> {
- const ab = await this.arrayBuffer();
- const decoder = new TextDecoder("utf-8");
- return decoder.decode(ab);
- }
-
- read(p: Uint8Array): Promise<number | io.EOF> {
- this._bodyUsed = true;
- return read(this.rid, p);
- }
-
- close(): void {
- close(this.rid);
- }
-
- async cancel(): Promise<void> {
- return notImplemented();
- }
-
- getReader(): domTypes.ReadableStreamReader {
- return notImplemented();
- }
-
- tee(): [domTypes.ReadableStream, domTypes.ReadableStream] {
- return notImplemented();
- }
-
- [Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array> {
- return io.toAsyncIterator(this);
- }
-
- get bodyUsed(): boolean {
- return this._bodyUsed;
- }
-}
-
-export class Response implements domTypes.Response {
- readonly type = "basic"; // TODO
- readonly redirected: boolean;
- headers: domTypes.Headers;
- readonly trailer: Promise<domTypes.Headers>;
- readonly body: Body;
-
- constructor(
- readonly url: string,
- readonly status: number,
- readonly statusText: string,
- headersList: Array<[string, string]>,
- rid: number,
- redirected_: boolean,
- body_: null | Body = null
- ) {
- this.trailer = createResolvable();
- this.headers = new Headers(headersList);
- const contentType = this.headers.get("content-type") || "";
-
- if (body_ == null) {
- this.body = new Body(rid, contentType);
- } else {
- this.body = body_;
- }
-
- this.redirected = redirected_;
- }
-
- async arrayBuffer(): Promise<ArrayBuffer> {
- return this.body.arrayBuffer();
- }
-
- async blob(): Promise<domTypes.Blob> {
- return this.body.blob();
- }
-
- async formData(): Promise<domTypes.FormData> {
- return this.body.formData();
- }
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- async json(): Promise<any> {
- return this.body.json();
- }
-
- async text(): Promise<string> {
- return this.body.text();
- }
-
- get ok(): boolean {
- return 200 <= this.status && this.status < 300;
- }
-
- get bodyUsed(): boolean {
- return this.body.bodyUsed;
- }
-
- clone(): domTypes.Response {
- if (this.bodyUsed) {
- throw new TypeError(
- "Failed to execute 'clone' on 'Response': Response body is already used"
- );
- }
-
- const iterators = this.headers.entries();
- const headersList: Array<[string, string]> = [];
- for (const header of iterators) {
- headersList.push(header);
- }
-
- return new Response(
- this.url,
- this.status,
- this.statusText,
- headersList,
- -1,
- this.redirected,
- this.body
- );
- }
-}
-
-interface FetchResponse {
- bodyRid: number;
- status: number;
- statusText: string;
- headers: Array<[string, string]>;
-}
-
-async function sendFetchReq(
- url: string,
- method: string | null,
- headers: domTypes.Headers | null,
- body: ArrayBufferView | undefined
-): Promise<FetchResponse> {
- let headerArray: Array<[string, string]> = [];
- if (headers) {
- headerArray = Array.from(headers.entries());
- }
-
- let zeroCopy = undefined;
- if (body) {
- zeroCopy = new Uint8Array(body.buffer, body.byteOffset, body.byteLength);
- }
-
- const args = {
- method,
- url,
- headers: headerArray
- };
-
- return (await sendAsync(dispatch.OP_FETCH, args, zeroCopy)) as FetchResponse;
-}
-
-/** Fetch a resource from the network. */
-export async function fetch(
- input: domTypes.Request | string,
- init?: domTypes.RequestInit
-): Promise<Response> {
- let url: string;
- let method: string | null = null;
- let headers: domTypes.Headers | null = null;
- let body: ArrayBufferView | undefined;
- let redirected = false;
- let remRedirectCount = 20; // TODO: use a better way to handle
-
- if (typeof input === "string") {
- url = input;
- if (init != null) {
- method = init.method || null;
- if (init.headers) {
- headers =
- init.headers instanceof Headers
- ? init.headers
- : new Headers(init.headers);
- } else {
- headers = null;
- }
-
- // ref: https://fetch.spec.whatwg.org/#body-mixin
- // Body should have been a mixin
- // but we are treating it as a separate class
- if (init.body) {
- if (!headers) {
- headers = new Headers();
- }
- let contentType = "";
- if (typeof init.body === "string") {
- body = new TextEncoder().encode(init.body);
- contentType = "text/plain;charset=UTF-8";
- } else if (isTypedArray(init.body)) {
- body = init.body;
- } else if (init.body instanceof URLSearchParams) {
- body = new TextEncoder().encode(init.body.toString());
- contentType = "application/x-www-form-urlencoded;charset=UTF-8";
- } else if (init.body instanceof DenoBlob) {
- body = init.body[blobBytesSymbol];
- contentType = init.body.type;
- } else {
- // TODO: FormData, ReadableStream
- notImplemented();
- }
- if (contentType && !headers.has("content-type")) {
- headers.set("content-type", contentType);
- }
- }
- }
- } else {
- url = input.url;
- method = input.method;
- headers = input.headers;
-
- //@ts-ignore
- if (input._bodySource) {
- body = new DataView(await input.arrayBuffer());
- }
- }
-
- while (remRedirectCount) {
- const fetchResponse = await sendFetchReq(url, method, headers, body);
-
- const response = new Response(
- url,
- fetchResponse.status,
- fetchResponse.statusText,
- fetchResponse.headers,
- fetchResponse.bodyRid,
- redirected
- );
- if ([301, 302, 303, 307, 308].includes(response.status)) {
- // We're in a redirect status
- switch ((init && init.redirect) || "follow") {
- case "error":
- throw notImplemented();
- case "manual":
- throw notImplemented();
- case "follow":
- default:
- let redirectUrl = response.headers.get("Location");
- if (redirectUrl == null) {
- return response; // Unspecified
- }
- if (
- !redirectUrl.startsWith("http://") &&
- !redirectUrl.startsWith("https://")
- ) {
- redirectUrl =
- url.split("//")[0] +
- "//" +
- url.split("//")[1].split("/")[0] +
- redirectUrl; // TODO: handle relative redirection more gracefully
- }
- url = redirectUrl;
- redirected = true;
- remRedirectCount--;
- }
- } else {
- return response;
- }
- }
- // Return a network error due to too many redirections
- throw notImplemented();
-}
diff --git a/js/fetch_test.ts b/js/fetch_test.ts
deleted file mode 100644
index 56c693681..000000000
--- a/js/fetch_test.ts
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import {
- test,
- testPerm,
- assert,
- assertEquals,
- assertStrContains,
- assertThrows
-} from "./test_util.ts";
-
-testPerm({ net: true }, async function fetchConnectionError(): Promise<void> {
- let err;
- try {
- await fetch("http://localhost:4000");
- } catch (err_) {
- err = err_;
- }
- assertEquals(err.kind, Deno.ErrorKind.HttpOther);
- assertEquals(err.name, "HttpOther");
- assertStrContains(err.message, "error trying to connect");
-});
-
-testPerm({ net: true }, async function fetchJsonSuccess(): Promise<void> {
- const response = await fetch("http://localhost:4545/package.json");
- const json = await response.json();
- assertEquals(json.name, "deno");
-});
-
-test(async function fetchPerm(): Promise<void> {
- let err;
- try {
- await fetch("http://localhost:4545/package.json");
- } catch (err_) {
- err = err_;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ net: true }, async function fetchUrl(): Promise<void> {
- const response = await fetch("http://localhost:4545/package.json");
- assertEquals(response.url, "http://localhost:4545/package.json");
-});
-
-testPerm({ net: true }, async function fetchHeaders(): Promise<void> {
- const response = await fetch("http://localhost:4545/package.json");
- const headers = response.headers;
- assertEquals(headers.get("Content-Type"), "application/json");
- assert(headers.get("Server").startsWith("SimpleHTTP"));
-});
-
-testPerm({ net: true }, async function fetchBlob(): Promise<void> {
- const response = await fetch("http://localhost:4545/package.json");
- const headers = response.headers;
- const blob = await response.blob();
- assertEquals(blob.type, headers.get("Content-Type"));
- assertEquals(blob.size, Number(headers.get("Content-Length")));
-});
-
-testPerm({ net: true }, async function fetchBodyUsed(): Promise<void> {
- const response = await fetch("http://localhost:4545/package.json");
- assertEquals(response.bodyUsed, false);
- assertThrows(
- (): void => {
- // Assigning to read-only property throws in the strict mode.
- response.bodyUsed = true;
- }
- );
- await response.blob();
- assertEquals(response.bodyUsed, true);
-});
-
-testPerm({ net: true }, async function fetchAsyncIterator(): Promise<void> {
- const response = await fetch("http://localhost:4545/package.json");
- const headers = response.headers;
- let total = 0;
- for await (const chunk of response.body) {
- total += chunk.length;
- }
-
- assertEquals(total, Number(headers.get("Content-Length")));
-});
-
-testPerm({ net: true }, async function responseClone(): Promise<void> {
- const response = await fetch("http://localhost:4545/package.json");
- const response1 = response.clone();
- assert(response !== response1);
- assertEquals(response.status, response1.status);
- assertEquals(response.statusText, response1.statusText);
- const ab = await response.arrayBuffer();
- const ab1 = await response1.arrayBuffer();
- for (let i = 0; i < ab.byteLength; i++) {
- assertEquals(ab[i], ab1[i]);
- }
-});
-
-testPerm({ net: true }, async function fetchEmptyInvalid(): Promise<void> {
- let err;
- try {
- await fetch("");
- } catch (err_) {
- err = err_;
- }
- assertEquals(err.kind, Deno.ErrorKind.RelativeUrlWithoutBase);
- assertEquals(err.name, "RelativeUrlWithoutBase");
-});
-
-testPerm({ net: true }, async function fetchMultipartFormDataSuccess(): Promise<
- void
-> {
- const response = await fetch(
- "http://localhost:4545/tests/subdir/multipart_form_data.txt"
- );
- const formData = await response.formData();
- assert(formData.has("field_1"));
- assertEquals(formData.get("field_1").toString(), "value_1 \r\n");
- assert(formData.has("field_2"));
- /* TODO(ry) Re-enable this test once we bring back the global File type.
- const file = formData.get("field_2") as File;
- assertEquals(file.name, "file.js");
- */
- // Currently we cannot read from file...
-});
-
-testPerm(
- { net: true },
- async function fetchURLEncodedFormDataSuccess(): Promise<void> {
- const response = await fetch(
- "http://localhost:4545/tests/subdir/form_urlencoded.txt"
- );
- const formData = await response.formData();
- assert(formData.has("field_1"));
- assertEquals(formData.get("field_1").toString(), "Hi");
- assert(formData.has("field_2"));
- assertEquals(formData.get("field_2").toString(), "<Deno>");
- }
-);
-
-testPerm({ net: true }, async function fetchWithRedirection(): Promise<void> {
- const response = await fetch("http://localhost:4546/"); // will redirect to http://localhost:4545/
- assertEquals(response.status, 200);
- assertEquals(response.statusText, "OK");
- assertEquals(response.url, "http://localhost:4545/");
- const body = await response.text();
- assert(body.includes("<title>Directory listing for /</title>"));
-});
-
-testPerm({ net: true }, async function fetchWithRelativeRedirection(): Promise<
- void
-> {
- const response = await fetch("http://localhost:4545/tests"); // will redirect to /tests/
- assertEquals(response.status, 200);
- assertEquals(response.statusText, "OK");
- const body = await response.text();
- assert(body.includes("<title>Directory listing for /tests/</title>"));
-});
-
-// The feature below is not implemented, but the test should work after implementation
-/*
-testPerm({ net: true }, async function fetchWithInfRedirection(): Promise<
- void
-> {
- const response = await fetch("http://localhost:4549/tests"); // will redirect to the same place
- assertEquals(response.status, 0); // network error
-});
-*/
-
-testPerm({ net: true }, async function fetchInitStringBody(): Promise<void> {
- const data = "Hello World";
- const response = await fetch("http://localhost:4545/echo_server", {
- method: "POST",
- body: data
- });
- const text = await response.text();
- assertEquals(text, data);
- assert(response.headers.get("content-type").startsWith("text/plain"));
-});
-
-testPerm({ net: true }, async function fetchRequestInitStringBody(): Promise<
- void
-> {
- const data = "Hello World";
- const req = new Request("http://localhost:4545/echo_server", {
- method: "POST",
- body: data
- });
- const response = await fetch(req);
- const text = await response.text();
- assertEquals(text, data);
-});
-
-testPerm({ net: true }, async function fetchInitTypedArrayBody(): Promise<
- void
-> {
- const data = "Hello World";
- const response = await fetch("http://localhost:4545/echo_server", {
- method: "POST",
- body: new TextEncoder().encode(data)
- });
- const text = await response.text();
- assertEquals(text, data);
-});
-
-testPerm({ net: true }, async function fetchInitURLSearchParamsBody(): Promise<
- void
-> {
- const data = "param1=value1&param2=value2";
- const params = new URLSearchParams(data);
- const response = await fetch("http://localhost:4545/echo_server", {
- method: "POST",
- body: params
- });
- const text = await response.text();
- assertEquals(text, data);
- assert(
- response.headers
- .get("content-type")
- .startsWith("application/x-www-form-urlencoded")
- );
-});
-
-testPerm({ net: true }, async function fetchInitBlobBody(): Promise<void> {
- const data = "const a = 1";
- const blob = new Blob([data], {
- type: "text/javascript"
- });
- const response = await fetch("http://localhost:4545/echo_server", {
- method: "POST",
- body: blob
- });
- const text = await response.text();
- assertEquals(text, data);
- assert(response.headers.get("content-type").startsWith("text/javascript"));
-});
-
-testPerm({ net: true }, async function fetchUserAgent(): Promise<void> {
- const data = "Hello World";
- const response = await fetch("http://localhost:4545/echo_server", {
- method: "POST",
- body: new TextEncoder().encode(data)
- });
- assertEquals(response.headers.get("user-agent"), `Deno/${Deno.version.deno}`);
- await response.text();
-});
-
-// TODO(ry) The following tests work but are flaky. There's a race condition
-// somewhere. Here is what one of these flaky failures looks like:
-//
-// test fetchPostBodyString_permW0N1E0R0
-// assertEquals failed. actual = expected = POST /blah HTTP/1.1
-// hello: World
-// foo: Bar
-// host: 127.0.0.1:4502
-// content-length: 11
-// hello world
-// Error: actual: expected: POST /blah HTTP/1.1
-// hello: World
-// foo: Bar
-// host: 127.0.0.1:4502
-// content-length: 11
-// hello world
-// at Object.assertEquals (file:///C:/deno/js/testing/util.ts:29:11)
-// at fetchPostBodyString (file
-
-/*
-function bufferServer(addr: string): Deno.Buffer {
- const listener = Deno.listen(addr);
- const buf = new Deno.Buffer();
- listener.accept().then(async conn => {
- const p1 = buf.readFrom(conn);
- const p2 = conn.write(
- new TextEncoder().encode(
- "HTTP/1.0 404 Not Found\r\nContent-Length: 2\r\n\r\nNF"
- )
- );
- // Wait for both an EOF on the read side of the socket and for the write to
- // complete before closing it. Due to keep-alive, the EOF won't be sent
- // until the Connection close (HTTP/1.0) response, so readFrom() can't
- // proceed write. Conversely, if readFrom() is async, waiting for the
- // write() to complete is not a guarantee that we've read the incoming
- // request.
- await Promise.all([p1, p2]);
- conn.close();
- listener.close();
- });
- return buf;
-}
-
-testPerm({ net: true }, async function fetchRequest():Promise<void> {
- const addr = "127.0.0.1:4501";
- const buf = bufferServer(addr);
- const response = await fetch(`http://${addr}/blah`, {
- method: "POST",
- headers: [["Hello", "World"], ["Foo", "Bar"]]
- });
- assertEquals(response.status, 404);
- assertEquals(response.headers.get("Content-Length"), "2");
-
- const actual = new TextDecoder().decode(buf.bytes());
- const expected = [
- "POST /blah HTTP/1.1\r\n",
- "hello: World\r\n",
- "foo: Bar\r\n",
- `host: ${addr}\r\n\r\n`
- ].join("");
- assertEquals(actual, expected);
-});
-
-testPerm({ net: true }, async function fetchPostBodyString():Promise<void> {
- const addr = "127.0.0.1:4502";
- const buf = bufferServer(addr);
- const body = "hello world";
- const response = await fetch(`http://${addr}/blah`, {
- method: "POST",
- headers: [["Hello", "World"], ["Foo", "Bar"]],
- body
- });
- assertEquals(response.status, 404);
- assertEquals(response.headers.get("Content-Length"), "2");
-
- const actual = new TextDecoder().decode(buf.bytes());
- const expected = [
- "POST /blah HTTP/1.1\r\n",
- "hello: World\r\n",
- "foo: Bar\r\n",
- `host: ${addr}\r\n`,
- `content-length: ${body.length}\r\n\r\n`,
- body
- ].join("");
- assertEquals(actual, expected);
-});
-
-testPerm({ net: true }, async function fetchPostBodyTypedArray():Promise<void> {
- const addr = "127.0.0.1:4503";
- const buf = bufferServer(addr);
- const bodyStr = "hello world";
- const body = new TextEncoder().encode(bodyStr);
- const response = await fetch(`http://${addr}/blah`, {
- method: "POST",
- headers: [["Hello", "World"], ["Foo", "Bar"]],
- body
- });
- assertEquals(response.status, 404);
- assertEquals(response.headers.get("Content-Length"), "2");
-
- const actual = new TextDecoder().decode(buf.bytes());
- const expected = [
- "POST /blah HTTP/1.1\r\n",
- "hello: World\r\n",
- "foo: Bar\r\n",
- `host: ${addr}\r\n`,
- `content-length: ${body.byteLength}\r\n\r\n`,
- bodyStr
- ].join("");
- assertEquals(actual, expected);
-});
-*/
diff --git a/js/file_info.ts b/js/file_info.ts
deleted file mode 100644
index a98989e79..000000000
--- a/js/file_info.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { StatResponse } from "./stat.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;
-}
-
-// @internal
-export class FileInfoImpl implements FileInfo {
- private readonly _isFile: boolean;
- private readonly _isSymlink: boolean;
- len: number;
- modified: number | null;
- accessed: number | null;
- created: number | null;
- mode: number | null;
- name: string | null;
-
- /* @internal */
- constructor(private _res: StatResponse) {
- const modified = this._res.modified;
- const accessed = this._res.accessed;
- const created = this._res.created;
- const hasMode = this._res.hasMode;
- const mode = this._res.mode; // negative for invalid mode (Windows)
- const name = this._res.name;
-
- this._isFile = this._res.isFile;
- this._isSymlink = this._res.isSymlink;
- this.len = this._res.len;
- this.modified = modified ? modified : null;
- this.accessed = accessed ? accessed : null;
- this.created = created ? created : null;
- // null on Windows
- this.mode = hasMode ? mode : null;
- this.name = name ? name : null;
- }
-
- isFile(): boolean {
- return this._isFile;
- }
-
- isDirectory(): boolean {
- return !this._isFile && !this._isSymlink;
- }
-
- isSymlink(): boolean {
- return this._isSymlink;
- }
-}
diff --git a/js/file_test.ts b/js/file_test.ts
deleted file mode 100644
index 345dcd8fe..000000000
--- a/js/file_test.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert, assertEquals } from "./test_util.ts";
-
-function testFirstArgument(arg1, expectedSize): void {
- const file = new File(arg1, "name");
- assert(file instanceof File);
- assertEquals(file.name, "name");
- assertEquals(file.size, expectedSize);
- assertEquals(file.type, "");
-}
-
-test(function fileEmptyFileBits(): void {
- testFirstArgument([], 0);
-});
-
-test(function fileStringFileBits(): void {
- testFirstArgument(["bits"], 4);
-});
-
-test(function fileUnicodeStringFileBits(): void {
- testFirstArgument(["𝓽𝓮𝔁𝓽"], 16);
-});
-
-test(function fileStringObjectFileBits(): void {
- testFirstArgument([new String("string object")], 13);
-});
-
-test(function fileEmptyBlobFileBits(): void {
- testFirstArgument([new Blob()], 0);
-});
-
-test(function fileBlobFileBits(): void {
- testFirstArgument([new Blob(["bits"])], 4);
-});
-
-test(function fileEmptyFileFileBits(): void {
- testFirstArgument([new File([], "world.txt")], 0);
-});
-
-test(function fileFileFileBits(): void {
- testFirstArgument([new File(["bits"], "world.txt")], 4);
-});
-
-test(function fileArrayBufferFileBits(): void {
- testFirstArgument([new ArrayBuffer(8)], 8);
-});
-
-test(function fileTypedArrayFileBits(): void {
- testFirstArgument([new Uint8Array([0x50, 0x41, 0x53, 0x53])], 4);
-});
-
-test(function fileVariousFileBits(): void {
- testFirstArgument(
- [
- "bits",
- new Blob(["bits"]),
- new Blob(),
- new Uint8Array([0x50, 0x41]),
- new Uint16Array([0x5353]),
- new Uint32Array([0x53534150])
- ],
- 16
- );
-});
-
-test(function fileNumberInFileBits(): void {
- testFirstArgument([12], 2);
-});
-
-test(function fileArrayInFileBits(): void {
- testFirstArgument([[1, 2, 3]], 5);
-});
-
-test(function fileObjectInFileBits(): void {
- // "[object Object]"
- testFirstArgument([{}], 15);
-});
-
-function testSecondArgument(arg2, expectedFileName): void {
- const file = new File(["bits"], arg2);
- assert(file instanceof File);
- assertEquals(file.name, expectedFileName);
-}
-
-test(function fileUsingFileName(): void {
- testSecondArgument("dummy", "dummy");
-});
-
-test(function fileUsingSpecialCharacterInFileName(): void {
- testSecondArgument("dummy/foo", "dummy:foo");
-});
-
-test(function fileUsingNullFileName(): void {
- testSecondArgument(null, "null");
-});
-
-test(function fileUsingNumberFileName(): void {
- testSecondArgument(1, "1");
-});
-
-test(function fileUsingEmptyStringFileName(): void {
- testSecondArgument("", "");
-});
diff --git a/js/files.ts b/js/files.ts
deleted file mode 100644
index b83a147e1..000000000
--- a/js/files.ts
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import {
- EOF,
- Reader,
- Writer,
- Seeker,
- Closer,
- SeekMode,
- SyncReader,
- SyncWriter,
- SyncSeeker
-} from "./io.ts";
-import { sendAsyncMinimal, sendSyncMinimal } from "./dispatch_minimal.ts";
-import * as dispatch from "./dispatch.ts";
-import {
- sendSync as sendSyncJson,
- sendAsync as sendAsyncJson
-} from "./dispatch_json.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 = "r"): File {
- const rid = sendSyncJson(dispatch.OP_OPEN, { filename, mode });
- return new File(rid);
-}
-
-/** Open a file and return an instance of the `File` object.
- *
- * (async () => {
- * const file = await Deno.open("/foo/bar.txt");
- * })();
- */
-export async function open(
- filename: string,
- mode: OpenMode = "r"
-): Promise<File> {
- const rid = await sendAsyncJson(dispatch.OP_OPEN, { filename, mode });
- return new File(rid);
-}
-
-/** 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 {
- const nread = sendSyncMinimal(dispatch.OP_READ, rid, p);
- if (nread < 0) {
- throw new Error("read error");
- } else if (nread == 0) {
- return EOF;
- } else {
- return nread;
- }
-}
-
-/** 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 async function read(rid: number, p: Uint8Array): Promise<number | EOF> {
- const nread = await sendAsyncMinimal(dispatch.OP_READ, rid, p);
- if (nread < 0) {
- throw new Error("read error");
- } else if (nread == 0) {
- return EOF;
- } else {
- return nread;
- }
-}
-
-/** 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 {
- const result = sendSyncMinimal(dispatch.OP_WRITE, rid, p);
- if (result < 0) {
- throw new Error("write error");
- } else {
- return result;
- }
-}
-
-/** 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 async function write(rid: number, p: Uint8Array): Promise<number> {
- const result = await sendAsyncMinimal(dispatch.OP_WRITE, rid, p);
- if (result < 0) {
- throw new Error("write error");
- } else {
- return result;
- }
-}
-
-/** 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 {
- sendSyncJson(dispatch.OP_SEEK, { rid, offset, whence });
-}
-
-/** 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 async function seek(
- rid: number,
- offset: number,
- whence: SeekMode
-): Promise<void> {
- await sendAsyncJson(dispatch.OP_SEEK, { rid, offset, whence });
-}
-
-/** Close the file ID. */
-export function close(rid: number): void {
- sendSyncJson(dispatch.OP_CLOSE, { rid });
-}
-
-/** The Deno abstraction for reading and writing files. */
-export class File
- implements
- Reader,
- SyncReader,
- Writer,
- SyncWriter,
- Seeker,
- SyncSeeker,
- Closer {
- constructor(readonly rid: number) {}
-
- write(p: Uint8Array): Promise<number> {
- return write(this.rid, p);
- }
-
- writeSync(p: Uint8Array): number {
- return writeSync(this.rid, p);
- }
-
- read(p: Uint8Array): Promise<number | EOF> {
- return read(this.rid, p);
- }
-
- readSync(p: Uint8Array): number | EOF {
- return readSync(this.rid, p);
- }
-
- seek(offset: number, whence: SeekMode): Promise<void> {
- return seek(this.rid, offset, whence);
- }
-
- seekSync(offset: number, whence: SeekMode): void {
- return seekSync(this.rid, offset, whence);
- }
-
- close(): void {
- close(this.rid);
- }
-}
-
-/** An instance of `File` for stdin. */
-export const stdin = new File(0);
-/** An instance of `File` for stdout. */
-export const stdout = new File(1);
-/** An instance of `File` for stderr. */
-export const stderr = new File(2);
-
-export type OpenMode =
- /** Read-only. Default. Starts at beginning of file. */
- | "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+";
-
-/** A factory function for creating instances of `File` associated with the
- * supplied file name.
- * @internal
- */
-export function create(filename: string): Promise<File> {
- return open(filename, "w+");
-}
diff --git a/js/files_test.ts b/js/files_test.ts
deleted file mode 100644
index 004cb662b..000000000
--- a/js/files_test.ts
+++ /dev/null
@@ -1,329 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, testPerm, assert, assertEquals } from "./test_util.ts";
-
-test(function filesStdioFileDescriptors(): void {
- assertEquals(Deno.stdin.rid, 0);
- assertEquals(Deno.stdout.rid, 1);
- assertEquals(Deno.stderr.rid, 2);
-});
-
-testPerm({ read: true }, async function filesCopyToStdout(): Promise<void> {
- const filename = "package.json";
- const file = await Deno.open(filename);
- assert(file.rid > 2);
- const bytesWritten = await Deno.copy(Deno.stdout, file);
- const fileSize = Deno.statSync(filename).len;
- assertEquals(bytesWritten, fileSize);
- console.log("bytes written", bytesWritten);
-});
-
-testPerm({ read: true }, async function filesToAsyncIterator(): Promise<void> {
- const filename = "tests/hello.txt";
- const file = await Deno.open(filename);
-
- let totalSize = 0;
- for await (const buf of Deno.toAsyncIterator(file)) {
- totalSize += buf.byteLength;
- }
-
- assertEquals(totalSize, 12);
-});
-
-test(async function readerToAsyncIterator(): Promise<void> {
- // ref: https://github.com/denoland/deno/issues/2330
- const encoder = new TextEncoder();
-
- class TestReader implements Deno.Reader {
- private offset = 0;
- private buf = new Uint8Array(encoder.encode(this.s));
-
- constructor(private readonly s: string) {}
-
- async read(p: Uint8Array): Promise<number | Deno.EOF> {
- const n = Math.min(p.byteLength, this.buf.byteLength - this.offset);
- p.set(this.buf.slice(this.offset, this.offset + n));
- this.offset += n;
-
- if (n === 0) {
- return Deno.EOF;
- }
-
- return n;
- }
- }
-
- const reader = new TestReader("hello world!");
-
- let totalSize = 0;
- for await (const buf of Deno.toAsyncIterator(reader)) {
- totalSize += buf.byteLength;
- }
-
- assertEquals(totalSize, 12);
-});
-
-testPerm({ write: false }, async function writePermFailure(): Promise<void> {
- const filename = "tests/hello.txt";
- const writeModes: Deno.OpenMode[] = ["w", "a", "x"];
- for (const mode of writeModes) {
- let err;
- try {
- await Deno.open(filename, mode);
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
- }
-});
-
-testPerm({ read: false }, async function readPermFailure(): Promise<void> {
- let caughtError = false;
- try {
- await Deno.open("package.json", "r");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ write: true }, async function writeNullBufferFailure(): Promise<
- void
-> {
- const tempDir = Deno.makeTempDirSync();
- const filename = tempDir + "hello.txt";
- const file = await Deno.open(filename, "w");
-
- // writing null should throw an error
- let err;
- try {
- await file.write(null);
- } catch (e) {
- err = e;
- }
- // TODO: Check error kind when dispatch_minimal pipes errors properly
- assert(!!err);
-
- file.close();
- await Deno.remove(tempDir, { recursive: true });
-});
-
-testPerm(
- { write: true, read: true },
- async function readNullBufferFailure(): Promise<void> {
- const tempDir = Deno.makeTempDirSync();
- const filename = tempDir + "hello.txt";
- const file = await Deno.open(filename, "w+");
-
- // reading file into null buffer should throw an error
- let err;
- try {
- await file.read(null);
- } catch (e) {
- err = e;
- }
- // TODO: Check error kind when dispatch_minimal pipes errors properly
- assert(!!err);
-
- file.close();
- await Deno.remove(tempDir, { recursive: true });
- }
-);
-
-testPerm(
- { write: false, read: false },
- async function readWritePermFailure(): Promise<void> {
- const filename = "tests/hello.txt";
- const writeModes: Deno.OpenMode[] = ["r+", "w+", "a+", "x+"];
- for (const mode of writeModes) {
- let err;
- try {
- await Deno.open(filename, mode);
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
- }
- }
-);
-
-testPerm({ read: true, write: true }, async function createFile(): Promise<
- void
-> {
- const tempDir = await Deno.makeTempDir();
- const filename = tempDir + "/test.txt";
- const f = await Deno.open(filename, "w");
- let fileInfo = Deno.statSync(filename);
- assert(fileInfo.isFile());
- assert(fileInfo.len === 0);
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- await f.write(data);
- fileInfo = Deno.statSync(filename);
- assert(fileInfo.len === 5);
- f.close();
-
- // TODO: test different modes
- await Deno.remove(tempDir, { recursive: true });
-});
-
-testPerm({ read: true, write: true }, async function openModeWrite(): Promise<
- void
-> {
- const tempDir = Deno.makeTempDirSync();
- const encoder = new TextEncoder();
- const filename = tempDir + "hello.txt";
- const data = encoder.encode("Hello world!\n");
-
- let file = await Deno.open(filename, "w");
- // assert file was created
- let fileInfo = Deno.statSync(filename);
- assert(fileInfo.isFile());
- assertEquals(fileInfo.len, 0);
- // write some data
- await file.write(data);
- fileInfo = Deno.statSync(filename);
- assertEquals(fileInfo.len, 13);
- // assert we can't read from file
- let thrown = false;
- try {
- const buf = new Uint8Array(20);
- await file.read(buf);
- } catch (e) {
- thrown = true;
- } finally {
- assert(thrown, "'w' mode shouldn't allow to read file");
- }
- file.close();
- // assert that existing file is truncated on open
- file = await Deno.open(filename, "w");
- file.close();
- const fileSize = Deno.statSync(filename).len;
- assertEquals(fileSize, 0);
- await Deno.remove(tempDir, { recursive: true });
-});
-
-testPerm(
- { read: true, write: true },
- async function openModeWriteRead(): Promise<void> {
- const tempDir = Deno.makeTempDirSync();
- const encoder = new TextEncoder();
- const filename = tempDir + "hello.txt";
- const data = encoder.encode("Hello world!\n");
-
- const file = await Deno.open(filename, "w+");
- // assert file was created
- let fileInfo = Deno.statSync(filename);
- assert(fileInfo.isFile());
- assertEquals(fileInfo.len, 0);
- // write some data
- await file.write(data);
- fileInfo = Deno.statSync(filename);
- assertEquals(fileInfo.len, 13);
-
- const buf = new Uint8Array(20);
- await file.seek(0, Deno.SeekMode.SEEK_START);
- const result = await file.read(buf);
- assertEquals(result, 13);
- file.close();
-
- await Deno.remove(tempDir, { recursive: true });
- }
-);
-
-testPerm({ read: true }, async function seekStart(): Promise<void> {
- const filename = "tests/hello.txt";
- const file = await Deno.open(filename);
- // Deliberately move 1 step forward
- await file.read(new Uint8Array(1)); // "H"
- // Skipping "Hello "
- await file.seek(6, Deno.SeekMode.SEEK_START);
- const buf = new Uint8Array(6);
- await file.read(buf);
- const decoded = new TextDecoder().decode(buf);
- assertEquals(decoded, "world!");
-});
-
-testPerm({ read: true }, function seekSyncStart(): void {
- const filename = "tests/hello.txt";
- const file = Deno.openSync(filename);
- // Deliberately move 1 step forward
- file.readSync(new Uint8Array(1)); // "H"
- // Skipping "Hello "
- file.seekSync(6, Deno.SeekMode.SEEK_START);
- const buf = new Uint8Array(6);
- file.readSync(buf);
- const decoded = new TextDecoder().decode(buf);
- assertEquals(decoded, "world!");
-});
-
-testPerm({ read: true }, async function seekCurrent(): Promise<void> {
- const filename = "tests/hello.txt";
- const file = await Deno.open(filename);
- // Deliberately move 1 step forward
- await file.read(new Uint8Array(1)); // "H"
- // Skipping "ello "
- await file.seek(5, Deno.SeekMode.SEEK_CURRENT);
- const buf = new Uint8Array(6);
- await file.read(buf);
- const decoded = new TextDecoder().decode(buf);
- assertEquals(decoded, "world!");
-});
-
-testPerm({ read: true }, function seekSyncCurrent(): void {
- const filename = "tests/hello.txt";
- const file = Deno.openSync(filename);
- // Deliberately move 1 step forward
- file.readSync(new Uint8Array(1)); // "H"
- // Skipping "ello "
- file.seekSync(5, Deno.SeekMode.SEEK_CURRENT);
- const buf = new Uint8Array(6);
- file.readSync(buf);
- const decoded = new TextDecoder().decode(buf);
- assertEquals(decoded, "world!");
-});
-
-testPerm({ read: true }, async function seekEnd(): Promise<void> {
- const filename = "tests/hello.txt";
- const file = await Deno.open(filename);
- await file.seek(-6, Deno.SeekMode.SEEK_END);
- const buf = new Uint8Array(6);
- await file.read(buf);
- const decoded = new TextDecoder().decode(buf);
- assertEquals(decoded, "world!");
-});
-
-testPerm({ read: true }, function seekSyncEnd(): void {
- const filename = "tests/hello.txt";
- const file = Deno.openSync(filename);
- file.seekSync(-6, Deno.SeekMode.SEEK_END);
- const buf = new Uint8Array(6);
- file.readSync(buf);
- const decoded = new TextDecoder().decode(buf);
- assertEquals(decoded, "world!");
-});
-
-testPerm({ read: true }, async function seekMode(): Promise<void> {
- const filename = "tests/hello.txt";
- const file = await Deno.open(filename);
- let err;
- try {
- await file.seek(1, -1);
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.InvalidSeekMode);
- assertEquals(err.name, "InvalidSeekMode");
-
- // We should still be able to read the file
- // since it is still open.
- const buf = new Uint8Array(1);
- await file.read(buf); // "H"
- assertEquals(new TextDecoder().decode(buf), "H");
-});
diff --git a/js/form_data.ts b/js/form_data.ts
deleted file mode 100644
index 89efb3c00..000000000
--- a/js/form_data.ts
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as domTypes from "./dom_types.ts";
-import * as blob from "./blob.ts";
-import * as domFile from "./dom_file.ts";
-import { DomIterableMixin } from "./mixins/dom_iterable.ts";
-import { requiredArguments } from "./util.ts";
-
-const dataSymbol = Symbol("data");
-
-class FormDataBase {
- private [dataSymbol]: Array<[string, domTypes.FormDataEntryValue]> = [];
-
- /** Appends a new value onto an existing key inside a `FormData`
- * object, or adds the key if it does not already exist.
- *
- * formData.append('name', 'first');
- * formData.append('name', 'second');
- */
- append(name: string, value: string): void;
- append(name: string, value: blob.DenoBlob, filename?: string): void;
- append(name: string, value: string | blob.DenoBlob, filename?: string): void {
- requiredArguments("FormData.append", arguments.length, 2);
- name = String(name);
- if (value instanceof blob.DenoBlob) {
- const dfile = new domFile.DomFileImpl([value], filename || name);
- this[dataSymbol].push([name, dfile]);
- } else {
- this[dataSymbol].push([name, String(value)]);
- }
- }
-
- /** Deletes a key/value pair from a `FormData` object.
- *
- * formData.delete('name');
- */
- delete(name: string): void {
- requiredArguments("FormData.delete", arguments.length, 1);
- name = String(name);
- let i = 0;
- while (i < this[dataSymbol].length) {
- if (this[dataSymbol][i][0] === name) {
- this[dataSymbol].splice(i, 1);
- } else {
- i++;
- }
- }
- }
-
- /** Returns an array of all the values associated with a given key
- * from within a `FormData`.
- *
- * formData.getAll('name');
- */
- getAll(name: string): domTypes.FormDataEntryValue[] {
- requiredArguments("FormData.getAll", arguments.length, 1);
- name = String(name);
- const values = [];
- for (const entry of this[dataSymbol]) {
- if (entry[0] === name) {
- values.push(entry[1]);
- }
- }
-
- return values;
- }
-
- /** Returns the first value associated with a given key from within a
- * `FormData` object.
- *
- * formData.get('name');
- */
- get(name: string): domTypes.FormDataEntryValue | null {
- requiredArguments("FormData.get", arguments.length, 1);
- name = String(name);
- for (const entry of this[dataSymbol]) {
- if (entry[0] === name) {
- return entry[1];
- }
- }
-
- return null;
- }
-
- /** Returns a boolean stating whether a `FormData` object contains a
- * certain key/value pair.
- *
- * formData.has('name');
- */
- has(name: string): boolean {
- requiredArguments("FormData.has", arguments.length, 1);
- name = String(name);
- return this[dataSymbol].some((entry): boolean => entry[0] === name);
- }
-
- /** Sets a new value for an existing key inside a `FormData` object, or
- * adds the key/value if it does not already exist.
- * ref: https://xhr.spec.whatwg.org/#dom-formdata-set
- *
- * formData.set('name', 'value');
- */
- set(name: string, value: string): void;
- set(name: string, value: blob.DenoBlob, filename?: string): void;
- set(name: string, value: string | blob.DenoBlob, filename?: string): void {
- requiredArguments("FormData.set", arguments.length, 2);
- name = String(name);
-
- // If there are any entries in the context object’s entry list whose name
- // is name, replace the first such entry with entry and remove the others
- let found = false;
- let i = 0;
- while (i < this[dataSymbol].length) {
- if (this[dataSymbol][i][0] === name) {
- if (!found) {
- if (value instanceof blob.DenoBlob) {
- const dfile = new domFile.DomFileImpl([value], filename || name);
- this[dataSymbol][i][1] = dfile;
- } else {
- this[dataSymbol][i][1] = String(value);
- }
- found = true;
- } else {
- this[dataSymbol].splice(i, 1);
- continue;
- }
- }
- i++;
- }
-
- // Otherwise, append entry to the context object’s entry list.
- if (!found) {
- if (value instanceof blob.DenoBlob) {
- const dfile = new domFile.DomFileImpl([value], filename || name);
- this[dataSymbol].push([name, dfile]);
- } else {
- this[dataSymbol].push([name, String(value)]);
- }
- }
- }
-
- get [Symbol.toStringTag](): string {
- return "FormData";
- }
-}
-
-export class FormData extends DomIterableMixin<
- string,
- domTypes.FormDataEntryValue,
- typeof FormDataBase
->(FormDataBase, dataSymbol) {}
diff --git a/js/form_data_test.ts b/js/form_data_test.ts
deleted file mode 100644
index fe8b6cf32..000000000
--- a/js/form_data_test.ts
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert, assertEquals } from "./test_util.ts";
-
-test(function formDataHasCorrectNameProp(): void {
- assertEquals(FormData.name, "FormData");
-});
-
-test(function formDataParamsAppendSuccess(): void {
- const formData = new FormData();
- formData.append("a", "true");
- assertEquals(formData.get("a"), "true");
-});
-
-test(function formDataParamsDeleteSuccess(): void {
- const formData = new FormData();
- formData.append("a", "true");
- formData.append("b", "false");
- assertEquals(formData.get("b"), "false");
- formData.delete("b");
- assertEquals(formData.get("a"), "true");
- assertEquals(formData.get("b"), null);
-});
-
-test(function formDataParamsGetAllSuccess(): void {
- const formData = new FormData();
- formData.append("a", "true");
- formData.append("b", "false");
- formData.append("a", "null");
- assertEquals(formData.getAll("a"), ["true", "null"]);
- assertEquals(formData.getAll("b"), ["false"]);
- assertEquals(formData.getAll("c"), []);
-});
-
-test(function formDataParamsGetSuccess(): void {
- const formData = new FormData();
- formData.append("a", "true");
- formData.append("b", "false");
- formData.append("a", "null");
- formData.append("d", undefined);
- formData.append("e", null);
- assertEquals(formData.get("a"), "true");
- assertEquals(formData.get("b"), "false");
- assertEquals(formData.get("c"), null);
- assertEquals(formData.get("d"), "undefined");
- assertEquals(formData.get("e"), "null");
-});
-
-test(function formDataParamsHasSuccess(): void {
- const formData = new FormData();
- formData.append("a", "true");
- formData.append("b", "false");
- assert(formData.has("a"));
- assert(formData.has("b"));
- assert(!formData.has("c"));
-});
-
-test(function formDataParamsSetSuccess(): void {
- const formData = new FormData();
- formData.append("a", "true");
- formData.append("b", "false");
- formData.append("a", "null");
- assertEquals(formData.getAll("a"), ["true", "null"]);
- assertEquals(formData.getAll("b"), ["false"]);
- formData.set("a", "false");
- assertEquals(formData.getAll("a"), ["false"]);
- formData.set("d", undefined);
- assertEquals(formData.get("d"), "undefined");
- formData.set("e", null);
- assertEquals(formData.get("e"), "null");
-});
-
-test(function formDataSetEmptyBlobSuccess(): void {
- const formData = new FormData();
- formData.set("a", new Blob([]), "blank.txt");
- formData.get("a");
- /* TODO Fix this test.
- assert(file instanceof File);
- if (typeof file !== "string") {
- assertEquals(file.name, "blank.txt");
- }
- */
-});
-
-test(function formDataParamsForEachSuccess(): void {
- const init = [["a", "54"], ["b", "true"]];
- const formData = new FormData();
- for (const [name, value] of init) {
- formData.append(name, value);
- }
- let callNum = 0;
- formData.forEach(
- (value, key, parent): void => {
- assertEquals(formData, parent);
- assertEquals(value, init[callNum][1]);
- assertEquals(key, init[callNum][0]);
- callNum++;
- }
- );
- assertEquals(callNum, init.length);
-});
-
-test(function formDataParamsArgumentsCheck(): void {
- const methodRequireOneParam = ["delete", "getAll", "get", "has", "forEach"];
-
- const methodRequireTwoParams = ["append", "set"];
-
- methodRequireOneParam.forEach(
- (method): void => {
- const formData = new FormData();
- let hasThrown = 0;
- let errMsg = "";
- try {
- formData[method]();
- hasThrown = 1;
- } catch (err) {
- errMsg = err.message;
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 2);
- assertEquals(
- errMsg,
- `FormData.${method} requires at least 1 argument, but only 0 present`
- );
- }
- );
-
- methodRequireTwoParams.forEach(
- (method: string): void => {
- const formData = new FormData();
- let hasThrown = 0;
- let errMsg = "";
-
- try {
- formData[method]();
- hasThrown = 1;
- } catch (err) {
- errMsg = err.message;
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 2);
- assertEquals(
- errMsg,
- `FormData.${method} requires at least 2 arguments, but only 0 present`
- );
-
- hasThrown = 0;
- errMsg = "";
- try {
- formData[method]("foo");
- hasThrown = 1;
- } catch (err) {
- errMsg = err.message;
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 2);
- assertEquals(
- errMsg,
- `FormData.${method} requires at least 2 arguments, but only 1 present`
- );
- }
- );
-});
-
-test(function toStringShouldBeWebCompatibility(): void {
- const formData = new FormData();
- assertEquals(formData.toString(), "[object FormData]");
-});
diff --git a/js/format_error.ts b/js/format_error.ts
deleted file mode 100644
index 801da0d0b..000000000
--- a/js/format_error.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as dispatch from "./dispatch.ts";
-import { sendSync } from "./dispatch_json.ts";
-
-// TODO(bartlomieju): move to `repl.ts`?
-export function formatError(errString: string): string {
- const res = sendSync(dispatch.OP_FORMAT_ERROR, { error: errString });
- return res.error;
-}
diff --git a/js/get_random_values.ts b/js/get_random_values.ts
deleted file mode 100644
index e54f34785..000000000
--- a/js/get_random_values.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as dispatch from "./dispatch.ts";
-import { sendSync } from "./dispatch_json.ts";
-import { assert } from "./util.ts";
-
-/** Synchronously collects cryptographically secure random values. The
- * underlying CSPRNG in use is Rust's `rand::rngs::ThreadRng`.
- *
- * const arr = new Uint8Array(32);
- * crypto.getRandomValues(arr);
- */
-export function getRandomValues<
- T extends
- | Int8Array
- | Uint8Array
- | Uint8ClampedArray
- | Int16Array
- | Uint16Array
- | Int32Array
- | Uint32Array
->(typedArray: T): T {
- assert(typedArray !== null, "Input must not be null");
- assert(typedArray.length <= 65536, "Input must not be longer than 65536");
- const ui8 = new Uint8Array(
- typedArray.buffer,
- typedArray.byteOffset,
- typedArray.byteLength
- );
- sendSync(dispatch.OP_GET_RANDOM_VALUES, {}, ui8);
- return typedArray;
-}
diff --git a/js/get_random_values_test.ts b/js/get_random_values_test.ts
deleted file mode 100644
index 68c13d597..000000000
--- a/js/get_random_values_test.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assertNotEquals, assertStrictEq } from "./test_util.ts";
-
-test(function getRandomValuesInt8Array(): void {
- const arr = new Int8Array(32);
- crypto.getRandomValues(arr);
- assertNotEquals(arr, new Int8Array(32));
-});
-
-test(function getRandomValuesUint8Array(): void {
- const arr = new Uint8Array(32);
- crypto.getRandomValues(arr);
- assertNotEquals(arr, new Uint8Array(32));
-});
-
-test(function getRandomValuesUint8ClampedArray(): void {
- const arr = new Uint8ClampedArray(32);
- crypto.getRandomValues(arr);
- assertNotEquals(arr, new Uint8ClampedArray(32));
-});
-
-test(function getRandomValuesInt16Array(): void {
- const arr = new Int16Array(4);
- crypto.getRandomValues(arr);
- assertNotEquals(arr, new Int16Array(4));
-});
-
-test(function getRandomValuesUint16Array(): void {
- const arr = new Uint16Array(4);
- crypto.getRandomValues(arr);
- assertNotEquals(arr, new Uint16Array(4));
-});
-
-test(function getRandomValuesInt32Array(): void {
- const arr = new Int32Array(8);
- crypto.getRandomValues(arr);
- assertNotEquals(arr, new Int32Array(8));
-});
-
-test(function getRandomValuesUint32Array(): void {
- const arr = new Uint32Array(8);
- crypto.getRandomValues(arr);
- assertNotEquals(arr, new Uint32Array(8));
-});
-
-test(function getRandomValuesReturnValue(): void {
- const arr = new Uint32Array(8);
- const rtn = crypto.getRandomValues(arr);
- assertNotEquals(arr, new Uint32Array(8));
- assertStrictEq(rtn, arr);
-});
diff --git a/js/globals.ts b/js/globals.ts
deleted file mode 100644
index b734b8da3..000000000
--- a/js/globals.ts
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-// This is a "special" module, in that it define the global runtime scope of
-// Deno, and therefore it defines a lot of the runtime environment that code
-// is evaluated in. We use this file to automatically build the runtime type
-// library.
-
-// Modules which will make up part of the global public API surface should be
-// imported as namespaces, so when the runtime type library is generated they
-// can be expressed as a namespace in the type library.
-import { window } from "./window.ts";
-import * as blob from "./blob.ts";
-import * as consoleTypes from "./console.ts";
-import * as csprng from "./get_random_values.ts";
-import * as customEvent from "./custom_event.ts";
-import * as Deno from "./deno.ts";
-import * as domTypes from "./dom_types.ts";
-import * as domFile from "./dom_file.ts";
-import * as event from "./event.ts";
-import * as eventTarget from "./event_target.ts";
-import * as formData from "./form_data.ts";
-import * as fetchTypes from "./fetch.ts";
-import * as headers from "./headers.ts";
-import * as textEncoding from "./text_encoding.ts";
-import * as timers from "./timers.ts";
-import * as url from "./url.ts";
-import * as urlSearchParams from "./url_search_params.ts";
-import * as workers from "./workers.ts";
-import * as performanceUtil from "./performance.ts";
-
-import * as request from "./request.ts";
-
-// These imports are not exposed and therefore are fine to just import the
-// symbols required.
-import { core } from "./core.ts";
-
-// During the build process, augmentations to the variable `window` in this
-// 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 {
- interface CallSite {
- getThis(): unknown;
- getTypeName(): string;
- getFunction(): Function;
- getFunctionName(): string;
- getMethodName(): string;
- getFileName(): string;
- getLineNumber(): number | null;
- getColumnNumber(): number | null;
- getEvalOrigin(): string | null;
- isToplevel(): boolean;
- isEval(): boolean;
- isNative(): boolean;
- isConstructor(): boolean;
- isAsync(): boolean;
- isPromiseAll(): boolean;
- getPromiseIndex(): number | null;
- }
-
- interface ErrorConstructor {
- prepareStackTrace(error: Error, structuredStackTrace: CallSite[]): string;
- }
-
- interface Object {
- [consoleTypes.customInspect]?(): string;
- }
-}
-
-// A self reference to the global object.
-window.window = window;
-
-// This is the Deno namespace, it is handled differently from other window
-// properties when building the runtime type library, as the whole module
-// is flattened into a single namespace.
-window.Deno = Deno;
-
-// Globally available functions and object instances.
-window.atob = textEncoding.atob;
-window.btoa = textEncoding.btoa;
-window.fetch = fetchTypes.fetch;
-window.clearTimeout = timers.clearTimeout;
-window.clearInterval = timers.clearInterval;
-window.console = new consoleTypes.Console(core.print);
-window.setTimeout = timers.setTimeout;
-window.setInterval = timers.setInterval;
-window.location = (undefined as unknown) as domTypes.Location;
-window.onload = undefined as undefined | Function;
-window.onunload = undefined as undefined | Function;
-// The following Crypto interface implementation is not up to par with the
-// standard https://www.w3.org/TR/WebCryptoAPI/#crypto-interface as it does not
-// yet incorporate the SubtleCrypto interface as its "subtle" property.
-window.crypto = (csprng as unknown) as Crypto;
-// window.queueMicrotask added by hand to self-maintained lib.deno_runtime.d.ts
-
-// When creating the runtime type library, we use modifications to `window` to
-// determine what is in the global namespace. When we put a class in the
-// namespace, we also need its global instance type as well, otherwise users
-// won't be able to refer to instances.
-// We have to export the type aliases, so that TypeScript _knows_ they are
-// being used, which it cannot statically determine within this module.
-window.Blob = blob.DenoBlob;
-export type Blob = domTypes.Blob;
-
-export type Body = domTypes.Body;
-
-window.File = domFile.DomFileImpl as domTypes.DomFileConstructor;
-export type File = domTypes.DomFile;
-
-export type CustomEventInit = domTypes.CustomEventInit;
-window.CustomEvent = customEvent.CustomEvent;
-export type CustomEvent = domTypes.CustomEvent;
-export type EventInit = domTypes.EventInit;
-window.Event = event.Event;
-export type Event = domTypes.Event;
-export type EventListener = domTypes.EventListener;
-window.EventTarget = eventTarget.EventTarget;
-export type EventTarget = domTypes.EventTarget;
-window.URL = url.URL;
-export type URL = url.URL;
-window.URLSearchParams = urlSearchParams.URLSearchParams;
-export type URLSearchParams = domTypes.URLSearchParams;
-
-// Using the `as` keyword to use standard compliant interfaces as the Deno
-// implementations contain some implementation details we wouldn't want to
-// expose in the runtime type library.
-window.Headers = headers.Headers as domTypes.HeadersConstructor;
-export type Headers = domTypes.Headers;
-window.FormData = formData.FormData as domTypes.FormDataConstructor;
-export type FormData = domTypes.FormData;
-
-window.TextEncoder = textEncoding.TextEncoder;
-export type TextEncoder = textEncoding.TextEncoder;
-window.TextDecoder = textEncoding.TextDecoder;
-export type TextDecoder = textEncoding.TextDecoder;
-
-window.Request = request.Request as domTypes.RequestConstructor;
-export type Request = domTypes.Request;
-
-window.Response = fetchTypes.Response;
-export type Response = domTypes.Response;
-
-window.performance = new performanceUtil.Performance();
-
-// This variable functioning correctly depends on `declareAsLet`
-// in //tools/ts_library_builder/main.ts
-window.onmessage = workers.onmessage;
-
-window.workerMain = workers.workerMain;
-window.workerClose = workers.workerClose;
-window.postMessage = workers.postMessage;
-
-window.Worker = workers.WorkerImpl;
-export type Worker = workers.Worker;
-
-window[domTypes.eventTargetHost] = null;
-window[domTypes.eventTargetListeners] = {};
-window[domTypes.eventTargetMode] = "";
-window[domTypes.eventTargetNodeType] = 0;
-window[eventTarget.eventTargetAssignedSlot] = false;
-window[eventTarget.eventTargetHasActivationBehavior] = false;
-window.addEventListener = eventTarget.EventTarget.prototype.addEventListener;
-window.dispatchEvent = eventTarget.EventTarget.prototype.dispatchEvent;
-window.removeEventListener =
- eventTarget.EventTarget.prototype.removeEventListener;
-
-// Registers the handler for window.onload function.
-window.addEventListener(
- "load",
- (e: domTypes.Event): void => {
- const onload = window.onload;
- if (typeof onload === "function") {
- onload(e);
- }
- }
-);
-// Registers the handler for window.onunload function.
-window.addEventListener(
- "unload",
- (e: domTypes.Event): void => {
- const onunload = window.onunload;
- if (typeof onunload === "function") {
- onunload(e);
- }
- }
-);
-
-// below are interfaces that are available in TypeScript but
-// have different signatures
-export interface ImportMeta {
- url: string;
- main: boolean;
-}
-
-export interface Crypto {
- readonly subtle: null;
- getRandomValues: <
- T extends
- | Int8Array
- | Uint8Array
- | Uint8ClampedArray
- | Int16Array
- | Uint16Array
- | Int32Array
- | Uint32Array
- >(
- typedArray: T
- ) => T;
-}
diff --git a/js/globals_test.ts b/js/globals_test.ts
deleted file mode 100644
index d7c50c5b1..000000000
--- a/js/globals_test.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert } from "./test_util.ts";
-
-test(function globalThisExists(): void {
- assert(globalThis != null);
-});
-
-test(function windowExists(): void {
- assert(window != null);
-});
-
-test(function windowWindowExists(): void {
- assert(window.window === window);
-});
-
-test(function globalThisEqualsWindow(): void {
- assert(globalThis === window);
-});
-
-test(function DenoNamespaceExists(): void {
- assert(Deno != null);
-});
-
-test(function DenoNamespaceEqualsWindowDeno(): void {
- assert(Deno === window.Deno);
-});
-
-test(function DenoNamespaceIsFrozen(): void {
- assert(Object.isFrozen(Deno));
-});
-
-test(function webAssemblyExists(): void {
- assert(typeof WebAssembly.compile === "function");
-});
-
-test(function DenoNamespaceImmutable(): void {
- const denoCopy = window.Deno;
- try {
- // @ts-ignore
- Deno = 1;
- } catch {}
- assert(denoCopy === Deno);
- try {
- // @ts-ignore
- window.Deno = 1;
- } catch {}
- assert(denoCopy === Deno);
- try {
- delete window.Deno;
- } catch {}
- assert(denoCopy === Deno);
-
- const { readFile } = Deno;
- try {
- // @ts-ignore
- Deno.readFile = 1;
- } catch {}
- assert(readFile === Deno.readFile);
- try {
- delete window.Deno.readFile;
- } catch {}
- assert(readFile === Deno.readFile);
-
- // @ts-ignore
- const { print } = Deno.core;
- try {
- // @ts-ignore
- Deno.core.print = 1;
- } catch {}
- // @ts-ignore
- assert(print === Deno.core.print);
- try {
- // @ts-ignore
- delete Deno.core.print;
- } catch {}
- // @ts-ignore
- assert(print === Deno.core.print);
-});
-
-test(async function windowQueueMicrotask(): Promise<void> {
- let resolve1: () => void | undefined;
- let resolve2: () => void | undefined;
- let microtaskDone = false;
- const p1 = new Promise(
- (res): void => {
- resolve1 = (): void => {
- microtaskDone = true;
- res();
- };
- }
- );
- const p2 = new Promise(
- (res): void => {
- resolve2 = (): void => {
- assert(microtaskDone);
- res();
- };
- }
- );
- window.queueMicrotask(resolve1!);
- setTimeout(resolve2!, 0);
- await p1;
- await p2;
-});
diff --git a/js/headers.ts b/js/headers.ts
deleted file mode 100644
index dc0de54dd..000000000
--- a/js/headers.ts
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as domTypes from "./dom_types.ts";
-import { DomIterableMixin } from "./mixins/dom_iterable.ts";
-import { requiredArguments } from "./util.ts";
-
-// From node-fetch
-// Copyright (c) 2016 David Frank. MIT License.
-const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/;
-const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-function isHeaders(value: any): value is domTypes.Headers {
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
- return value instanceof Headers;
-}
-
-const headerMap = Symbol("header map");
-
-// ref: https://fetch.spec.whatwg.org/#dom-headers
-class HeadersBase {
- private [headerMap]: Map<string, string>;
- // TODO: headerGuard? Investigate if it is needed
- // node-fetch did not implement this but it is in the spec
-
- private _normalizeParams(name: string, value?: string): string[] {
- name = String(name).toLowerCase();
- value = String(value).trim();
- return [name, value];
- }
-
- // The following name/value validations are copied from
- // https://github.com/bitinn/node-fetch/blob/master/src/headers.js
- // Copyright (c) 2016 David Frank. MIT License.
- private _validateName(name: string): void {
- if (invalidTokenRegex.test(name) || name === "") {
- throw new TypeError(`${name} is not a legal HTTP header name`);
- }
- }
-
- private _validateValue(value: string): void {
- if (invalidHeaderCharRegex.test(value)) {
- throw new TypeError(`${value} is not a legal HTTP header value`);
- }
- }
-
- constructor(init?: domTypes.HeadersInit) {
- if (init === null) {
- throw new TypeError(
- "Failed to construct 'Headers'; The provided value was not valid"
- );
- } else if (isHeaders(init)) {
- this[headerMap] = new Map(init);
- } else {
- this[headerMap] = new Map();
- if (Array.isArray(init)) {
- for (const tuple of init) {
- // If header does not contain exactly two items,
- // then throw a TypeError.
- // ref: https://fetch.spec.whatwg.org/#concept-headers-fill
- requiredArguments(
- "Headers.constructor tuple array argument",
- tuple.length,
- 2
- );
-
- const [name, value] = this._normalizeParams(tuple[0], tuple[1]);
- this._validateName(name);
- this._validateValue(value);
- const existingValue = this[headerMap].get(name);
- this[headerMap].set(
- name,
- existingValue ? `${existingValue}, ${value}` : value
- );
- }
- } else if (init) {
- const names = Object.keys(init);
- for (const rawName of names) {
- const rawValue = init[rawName];
- const [name, value] = this._normalizeParams(rawName, rawValue);
- this._validateName(name);
- this._validateValue(value);
- this[headerMap].set(name, value);
- }
- }
- }
- }
-
- // ref: https://fetch.spec.whatwg.org/#concept-headers-append
- append(name: string, value: string): void {
- requiredArguments("Headers.append", arguments.length, 2);
- const [newname, newvalue] = this._normalizeParams(name, value);
- this._validateName(newname);
- this._validateValue(newvalue);
- const v = this[headerMap].get(newname);
- const str = v ? `${v}, ${newvalue}` : newvalue;
- this[headerMap].set(newname, str);
- }
-
- delete(name: string): void {
- requiredArguments("Headers.delete", arguments.length, 1);
- const [newname] = this._normalizeParams(name);
- this._validateName(newname);
- this[headerMap].delete(newname);
- }
-
- get(name: string): string | null {
- requiredArguments("Headers.get", arguments.length, 1);
- const [newname] = this._normalizeParams(name);
- this._validateName(newname);
- const value = this[headerMap].get(newname);
- return value || null;
- }
-
- has(name: string): boolean {
- requiredArguments("Headers.has", arguments.length, 1);
- const [newname] = this._normalizeParams(name);
- this._validateName(newname);
- return this[headerMap].has(newname);
- }
-
- set(name: string, value: string): void {
- requiredArguments("Headers.set", arguments.length, 2);
- const [newname, newvalue] = this._normalizeParams(name, value);
- this._validateName(newname);
- this._validateValue(newvalue);
- this[headerMap].set(newname, newvalue);
- }
-
- get [Symbol.toStringTag](): string {
- return "Headers";
- }
-}
-
-// @internal
-export class Headers extends DomIterableMixin<
- string,
- string,
- typeof HeadersBase
->(HeadersBase, headerMap) {}
diff --git a/js/headers_test.ts b/js/headers_test.ts
deleted file mode 100644
index f08283c51..000000000
--- a/js/headers_test.ts
+++ /dev/null
@@ -1,331 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert, assertEquals } from "./test_util.ts";
-
-// Logic heavily copied from web-platform-tests, make
-// sure pass mostly header basic test
-// ref: https://github.com/web-platform-tests/wpt/blob/7c50c216081d6ea3c9afe553ee7b64534020a1b2/fetch/api/headers/headers-basic.html
-test(function newHeaderTest(): void {
- new Headers();
- new Headers(undefined);
- new Headers({});
- try {
- new Headers(null);
- } catch (e) {
- assertEquals(
- e.message,
- "Failed to construct 'Headers'; The provided value was not valid"
- );
- }
-});
-
-const headerDict = {
- name1: "value1",
- name2: "value2",
- name3: "value3",
- name4: undefined,
- "Content-Type": "value4"
-};
-const headerSeq = [];
-for (const name in headerDict) {
- headerSeq.push([name, headerDict[name]]);
-}
-
-test(function newHeaderWithSequence(): void {
- const headers = new Headers(headerSeq);
- for (const name in headerDict) {
- assertEquals(headers.get(name), String(headerDict[name]));
- }
- assertEquals(headers.get("length"), null);
-});
-
-test(function newHeaderWithRecord(): void {
- const headers = new Headers(headerDict);
- for (const name in headerDict) {
- assertEquals(headers.get(name), String(headerDict[name]));
- }
-});
-
-test(function newHeaderWithHeadersInstance(): void {
- const headers = new Headers(headerDict);
- const headers2 = new Headers(headers);
- for (const name in headerDict) {
- assertEquals(headers2.get(name), String(headerDict[name]));
- }
-});
-
-test(function headerAppendSuccess(): void {
- const headers = new Headers();
- for (const name in headerDict) {
- headers.append(name, headerDict[name]);
- assertEquals(headers.get(name), String(headerDict[name]));
- }
-});
-
-test(function headerSetSuccess(): void {
- const headers = new Headers();
- for (const name in headerDict) {
- headers.set(name, headerDict[name]);
- assertEquals(headers.get(name), String(headerDict[name]));
- }
-});
-
-test(function headerHasSuccess(): void {
- const headers = new Headers(headerDict);
- for (const name in headerDict) {
- assert(headers.has(name), "headers has name " + name);
- assert(
- !headers.has("nameNotInHeaders"),
- "headers do not have header: nameNotInHeaders"
- );
- }
-});
-
-test(function headerDeleteSuccess(): void {
- const headers = new Headers(headerDict);
- for (const name in headerDict) {
- assert(headers.has(name), "headers have a header: " + name);
- headers.delete(name);
- assert(!headers.has(name), "headers do not have anymore a header: " + name);
- }
-});
-
-test(function headerGetSuccess(): void {
- const headers = new Headers(headerDict);
- for (const name in headerDict) {
- assertEquals(headers.get(name), String(headerDict[name]));
- assertEquals(headers.get("nameNotInHeaders"), null);
- }
-});
-
-test(function headerEntriesSuccess(): void {
- const headers = new Headers(headerDict);
- const iterators = headers.entries();
- for (const it of iterators) {
- const key = it[0];
- const value = it[1];
- assert(headers.has(key));
- assertEquals(value, headers.get(key));
- }
-});
-
-test(function headerKeysSuccess(): void {
- const headers = new Headers(headerDict);
- const iterators = headers.keys();
- for (const it of iterators) {
- assert(headers.has(it));
- }
-});
-
-test(function headerValuesSuccess(): void {
- const headers = new Headers(headerDict);
- const iterators = headers.values();
- const entries = headers.entries();
- const values = [];
- for (const pair of entries) {
- values.push(pair[1]);
- }
- for (const it of iterators) {
- assert(values.includes(it));
- }
-});
-
-const headerEntriesDict = {
- name1: "value1",
- Name2: "value2",
- name: "value3",
- "content-Type": "value4",
- "Content-Typ": "value5",
- "Content-Types": "value6"
-};
-
-test(function headerForEachSuccess(): void {
- const headers = new Headers(headerEntriesDict);
- const keys = Object.keys(headerEntriesDict);
- keys.forEach(
- (key): void => {
- const value = headerEntriesDict[key];
- const newkey = key.toLowerCase();
- headerEntriesDict[newkey] = value;
- }
- );
- let callNum = 0;
- headers.forEach(
- (value, key, container): void => {
- assertEquals(headers, container);
- assertEquals(value, headerEntriesDict[key]);
- callNum++;
- }
- );
- assertEquals(callNum, keys.length);
-});
-
-test(function headerSymbolIteratorSuccess(): void {
- assert(Symbol.iterator in Headers.prototype);
- const headers = new Headers(headerEntriesDict);
- for (const header of headers) {
- const key = header[0];
- const value = header[1];
- assert(headers.has(key));
- assertEquals(value, headers.get(key));
- }
-});
-
-test(function headerTypesAvailable(): void {
- function newHeaders(): Headers {
- return new Headers();
- }
- const headers = newHeaders();
- assert(headers instanceof Headers);
-});
-
-// Modified from https://github.com/bitinn/node-fetch/blob/7d3293200a91ad52b5ca7962f9d6fd1c04983edb/test/test.js#L2001-L2014
-// Copyright (c) 2016 David Frank. MIT License.
-test(function headerIllegalReject(): void {
- let errorCount = 0;
- try {
- new Headers({ "He y": "ok" });
- } catch (e) {
- errorCount++;
- }
- try {
- new Headers({ "Hé-y": "ok" });
- } catch (e) {
- errorCount++;
- }
- try {
- new Headers({ "He-y": "ăk" });
- } catch (e) {
- errorCount++;
- }
- const headers = new Headers();
- try {
- headers.append("Hé-y", "ok");
- } catch (e) {
- errorCount++;
- }
- try {
- headers.delete("Hé-y");
- } catch (e) {
- errorCount++;
- }
- try {
- headers.get("Hé-y");
- } catch (e) {
- errorCount++;
- }
- try {
- headers.has("Hé-y");
- } catch (e) {
- errorCount++;
- }
- try {
- headers.set("Hé-y", "ok");
- } catch (e) {
- errorCount++;
- }
- try {
- headers.set("", "ok");
- } catch (e) {
- errorCount++;
- }
- assertEquals(errorCount, 9);
- // 'o k' is valid value but invalid name
- new Headers({ "He-y": "o k" });
-});
-
-// If pair does not contain exactly two items,then throw a TypeError.
-test(function headerParamsShouldThrowTypeError(): void {
- let hasThrown = 0;
-
- try {
- new Headers(([["1"]] as unknown) as Array<[string, string]>);
- hasThrown = 1;
- } catch (err) {
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
-
- assertEquals(hasThrown, 2);
-});
-
-test(function headerParamsArgumentsCheck(): void {
- const methodRequireOneParam = ["delete", "get", "has", "forEach"];
-
- const methodRequireTwoParams = ["append", "set"];
-
- methodRequireOneParam.forEach(
- (method): void => {
- const headers = new Headers();
- let hasThrown = 0;
- let errMsg = "";
- try {
- headers[method]();
- hasThrown = 1;
- } catch (err) {
- errMsg = err.message;
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 2);
- assertEquals(
- errMsg,
- `Headers.${method} requires at least 1 argument, but only 0 present`
- );
- }
- );
-
- methodRequireTwoParams.forEach(
- (method): void => {
- const headers = new Headers();
- let hasThrown = 0;
- let errMsg = "";
-
- try {
- headers[method]();
- hasThrown = 1;
- } catch (err) {
- errMsg = err.message;
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 2);
- assertEquals(
- errMsg,
- `Headers.${method} requires at least 2 arguments, but only 0 present`
- );
-
- hasThrown = 0;
- errMsg = "";
- try {
- headers[method]("foo");
- hasThrown = 1;
- } catch (err) {
- errMsg = err.message;
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 2);
- assertEquals(
- errMsg,
- `Headers.${method} requires at least 2 arguments, but only 1 present`
- );
- }
- );
-});
-
-test(function toStringShouldBeWebCompatibility(): void {
- const headers = new Headers();
- assertEquals(headers.toString(), "[object Headers]");
-});
diff --git a/js/io.ts b/js/io.ts
deleted file mode 100644
index 1a7bf8c4c..000000000
--- a/js/io.ts
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-// Interfaces 100% copied from Go.
-// Documentation liberally lifted from them too.
-// Thank you! We love Go!
-
-// TODO(kt3k): EOF should be `unique symbol` type.
-// That might require some changes of ts_library_builder.
-// See #2591 for more details.
-export const EOF = null;
-export type EOF = null;
-
-// Seek whence values.
-// https://golang.org/pkg/io/#pkg-constants
-export enum SeekMode {
- SEEK_START = 0,
- SEEK_CURRENT = 1,
- SEEK_END = 2
-}
-
-// Reader is the interface that wraps the basic read() method.
-// https://golang.org/pkg/io/#Reader
-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;
-}
-
-// Writer is the interface that wraps the basic write() method.
-// https://golang.org/pkg/io/#Writer
-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;
-}
-// https://golang.org/pkg/io/#Closer
-export interface Closer {
- // The behavior of Close after the first call is undefined. Specific
- // implementations may document their own behavior.
- close(): void;
-}
-
-// https://golang.org/pkg/io/#Seeker
-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;
-}
-
-// https://golang.org/pkg/io/#ReadCloser
-export interface ReadCloser extends Reader, Closer {}
-
-// https://golang.org/pkg/io/#WriteCloser
-export interface WriteCloser extends Writer, Closer {}
-
-// https://golang.org/pkg/io/#ReadSeeker
-export interface ReadSeeker extends Reader, Seeker {}
-
-// https://golang.org/pkg/io/#WriteSeeker
-export interface WriteSeeker extends Writer, Seeker {}
-
-// https://golang.org/pkg/io/#ReadWriteCloser
-export interface ReadWriteCloser extends Reader, Writer, Closer {}
-
-// https://golang.org/pkg/io/#ReadWriteSeeker
-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.
- */
-// https://golang.org/pkg/io/#Copy
-export async function copy(dst: Writer, src: Reader): Promise<number> {
- let n = 0;
- const b = new Uint8Array(32 * 1024);
- let gotEOF = false;
- while (gotEOF === false) {
- const result = await src.read(b);
- if (result === EOF) {
- gotEOF = true;
- } else {
- n += await dst.write(b.subarray(0, result));
- }
- }
- return n;
-}
-
-/** Turns `r` into async iterator.
- *
- * for await (const chunk of toAsyncIterator(reader)) {
- * console.log(chunk)
- * }
- */
-export function toAsyncIterator(r: Reader): AsyncIterableIterator<Uint8Array> {
- const b = new Uint8Array(1024);
- // Keep track if end-of-file has been reached, then
- // signal that iterator is done during subsequent next()
- // call. This is required because `r` can return a `number | EOF`
- // with data read and EOF reached. But if iterator returns
- // `done` then `value` is discarded.
- //
- // See https://github.com/denoland/deno/issues/2330 for reference.
- let sawEof = false;
-
- return {
- [Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array> {
- return this;
- },
-
- async next(): Promise<IteratorResult<Uint8Array>> {
- if (sawEof) {
- return { value: new Uint8Array(), done: true };
- }
-
- const result = await r.read(b);
- if (result === EOF) {
- sawEof = true;
- return { value: new Uint8Array(), done: true };
- }
-
- return {
- value: b.subarray(0, result),
- done: false
- };
- }
- };
-}
diff --git a/js/lib.deno_runtime.d.ts b/js/lib.deno_runtime.d.ts
deleted file mode 100644
index 94b6b61cd..000000000
--- a/js/lib.deno_runtime.d.ts
+++ /dev/null
@@ -1,2800 +0,0 @@
-// 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;
- };
- /** Get the hostname.
- * Requires the `--allow-env` flag.
- *
- * console.log(Deno.hostname());
- */
- export function hostname(): string;
- /** 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 value of an environment variable at invocation.
- * If the variable is not present, `undefined` will be returned.
- *
- * 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(key: string): string | undefined;
- /**
- * 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 Transport = "tcp";
- interface Addr {
- transport: Transport;
- 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;
- }
-
- export interface ListenOptions {
- port: number;
- hostname?: string;
- transport?: Transport;
- }
-
- /** Listen announces on the local transport address.
- *
- * @param options
- * @param options.port The port to connect to. (Required.)
- * @param options.hostname A literal IP address or host name that can be
- * resolved to an IP address. If not specified, defaults to 0.0.0.0
- * @param options.transport Defaults to "tcp". Later we plan to add "tcp4",
- * "tcp6", "udp", "udp4", "udp6", "ip", "ip4", "ip6", "unix", "unixgram" and
- * "unixpacket".
- *
- * Examples:
- *
- * listen({ port: 80 })
- * listen({ hostname: "192.0.2.1", port: 80 })
- * listen({ hostname: "[2001:db8::1]", port: 80 });
- * listen({ hostname: "golang.org", port: 80, transport: "tcp" })
- */
- export function listen(options: ListenOptions): Listener;
-
- export interface DialOptions {
- port: number;
- hostname?: string;
- transport?: Transport;
- }
-
- /** Dial connects to the address on the named transport.
- *
- * @param options
- * @param options.port The port to connect to. (Required.)
- * @param options.hostname A literal IP address or host name that can be
- * resolved to an IP address. If not specified, defaults to 127.0.0.1
- * @param options.transport Defaults to "tcp". Later we plan to add "tcp4",
- * "tcp6", "udp", "udp4", "udp6", "ip", "ip4", "ip6", "unix", "unixgram" and
- * "unixpacket".
- *
- * Examples:
- *
- * dial({ port: 80 })
- * dial({ hostname: "192.0.2.1", port: 80 })
- * dial({ hostname: "[2001:db8::1]", port: 80 });
- * dial({ hostname: "golang.org", port: 80, transport: "tcp" })
- */
- export function dial(options: DialOptions): Promise<Conn>;
-
- export interface DialTLSOptions {
- port: number;
- hostname?: string;
- }
-
- /**
- * dialTLS establishes a secure connection over TLS (transport layer security).
- */
- export function dialTLS(options: DialTLSOptions): 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;
- }>;
- /** 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;
-
- // @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 & typeof globalThis;
- 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;
- onunload: Function | undefined;
- crypto: Crypto;
- Blob: typeof blob.DenoBlob;
- File: domTypes.DomFileConstructor;
- CustomEvent: typeof customEvent.CustomEvent;
- Event: typeof event.Event;
- 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;
- queueMicrotask: (task: () => void) => void;
- Deno: typeof Deno;
-}
-
-declare const window: Window & typeof globalThis;
-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 onunload: 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 = domTypes.Blob;
-declare type Body = domTypes.Body;
-declare type File = domTypes.DomFile;
-declare type CustomEventInit = domTypes.CustomEventInit;
-declare type CustomEvent = domTypes.CustomEvent;
-declare type EventInit = domTypes.EventInit;
-declare type Event = domTypes.Event;
-declare type EventListener = domTypes.EventListener;
-declare type EventTarget = domTypes.EventTarget;
-declare type URL = url.URL;
-declare type URLSearchParams = domTypes.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 extends DomIterable<string, string> {
- /**
- * 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: this) => 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;
- }
- 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?: boolean;
- }
- 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: this) => 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(): IterableIterator<string>;
- /** Returns an iterator allowing to go through all values contained
- * in this object.
- *
- * for (const value of searchParams.values()) {
- * console.log(value);
- * }
- */
- values(): IterableIterator<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(): IterableIterator<[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](): IterableIterator<[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/js/lib.rs b/js/lib.rs
deleted file mode 100644
index 89688b9a5..000000000
--- a/js/lib.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-pub const TS_VERSION: &str = env!("TS_VERSION");
-
-pub static CLI_SNAPSHOT: &[u8] =
- include_bytes!(concat!(env!("OUT_DIR"), "/CLI_SNAPSHOT.bin"));
-pub static CLI_SNAPSHOT_MAP: &[u8] =
- include_bytes!(concat!(env!("OUT_DIR"), "/CLI_SNAPSHOT.js.map"));
-pub static CLI_SNAPSHOT_DTS: &[u8] =
- include_bytes!(concat!(env!("OUT_DIR"), "/CLI_SNAPSHOT.d.ts"));
-
-pub static COMPILER_SNAPSHOT: &[u8] =
- include_bytes!(concat!(env!("OUT_DIR"), "/COMPILER_SNAPSHOT.bin"));
-pub static COMPILER_SNAPSHOT_MAP: &[u8] =
- include_bytes!(concat!(env!("OUT_DIR"), "/COMPILER_SNAPSHOT.js.map"));
-pub static COMPILER_SNAPSHOT_DTS: &[u8] =
- include_bytes!(concat!(env!("OUT_DIR"), "/COMPILER_SNAPSHOT.d.ts"));
-
-static DENO_RUNTIME: &str = include_str!("lib.deno_runtime.d.ts");
-
-/// Same as deno_typescript::get_asset but also has lib.deno_runtime.d.ts
-pub fn get_asset(name: &str) -> Option<&'static str> {
- match name {
- "lib.deno_runtime.d.ts" => Some(DENO_RUNTIME),
- _ => deno_typescript::get_asset(name),
- }
-}
-
-#[test]
-fn cli_snapshot() {
- let mut isolate =
- deno::Isolate::new(deno::StartupData::Snapshot(CLI_SNAPSHOT), false);
- deno::js_check(isolate.execute(
- "<anon>",
- r#"
- if (!window) {
- throw Error("bad");
- }
- console.log("we have console.log!!!");
- "#,
- ));
-}
-
-#[test]
-fn compiler_snapshot() {
- let mut isolate =
- deno::Isolate::new(deno::StartupData::Snapshot(COMPILER_SNAPSHOT), false);
- deno::js_check(isolate.execute(
- "<anon>",
- r#"
- if (!compilerMain) {
- throw Error("bad");
- }
- console.log(`ts version: ${ts.version}`);
- "#,
- ));
-}
diff --git a/js/lib.web_assembly.d.ts b/js/lib.web_assembly.d.ts
deleted file mode 100644
index 8c357840a..000000000
--- a/js/lib.web_assembly.d.ts
+++ /dev/null
@@ -1,173 +0,0 @@
-// 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/js/link.ts b/js/link.ts
deleted file mode 100644
index a6f732926..000000000
--- a/js/link.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.ts";
-
-/** Synchronously creates `newname` as a hard link to `oldname`.
- *
- * Deno.linkSync("old/name", "new/name");
- */
-export function linkSync(oldname: string, newname: string): void {
- sendSync(dispatch.OP_LINK, { oldname, newname });
-}
-
-/** Creates `newname` as a hard link to `oldname`.
- *
- * await Deno.link("old/name", "new/name");
- */
-export async function link(oldname: string, newname: string): Promise<void> {
- await sendAsync(dispatch.OP_LINK, { oldname, newname });
-}
diff --git a/js/link_test.ts b/js/link_test.ts
deleted file mode 100644
index 9425e6eab..000000000
--- a/js/link_test.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-testPerm({ read: true, write: true }, function linkSyncSuccess(): void {
- const testDir = Deno.makeTempDirSync();
- const oldData = "Hardlink";
- const oldName = testDir + "/oldname";
- const newName = testDir + "/newname";
- Deno.writeFileSync(oldName, new TextEncoder().encode(oldData));
- // Create the hard link.
- Deno.linkSync(oldName, newName);
- // We should expect reading the same content.
- const newData = new TextDecoder().decode(Deno.readFileSync(newName));
- assertEquals(oldData, newData);
- // Writing to newname also affects oldname.
- const newData2 = "Modified";
- Deno.writeFileSync(newName, new TextEncoder().encode(newData2));
- assertEquals(newData2, new TextDecoder().decode(Deno.readFileSync(oldName)));
- // Writing to oldname also affects newname.
- const newData3 = "ModifiedAgain";
- Deno.writeFileSync(oldName, new TextEncoder().encode(newData3));
- assertEquals(newData3, new TextDecoder().decode(Deno.readFileSync(newName)));
- // Remove oldname. File still accessible through newname.
- Deno.removeSync(oldName);
- const newNameStat = Deno.statSync(newName);
- assert(newNameStat.isFile());
- assert(!newNameStat.isSymlink()); // Not a symlink.
- assertEquals(newData3, new TextDecoder().decode(Deno.readFileSync(newName)));
-});
-
-testPerm({ read: true, write: true }, function linkSyncExists(): void {
- const testDir = Deno.makeTempDirSync();
- const oldName = testDir + "/oldname";
- const newName = testDir + "/newname";
- Deno.writeFileSync(oldName, new TextEncoder().encode("oldName"));
- // newname is already created.
- Deno.writeFileSync(newName, new TextEncoder().encode("newName"));
-
- let err;
- try {
- Deno.linkSync(oldName, newName);
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.AlreadyExists);
- assertEquals(err.name, "AlreadyExists");
-});
-
-testPerm({ read: true, write: true }, function linkSyncNotFound(): void {
- const testDir = Deno.makeTempDirSync();
- const oldName = testDir + "/oldname";
- const newName = testDir + "/newname";
-
- let err;
- try {
- Deno.linkSync(oldName, newName);
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ read: false, write: true }, function linkSyncReadPerm(): void {
- let err;
- try {
- Deno.linkSync("oldbaddir", "newbaddir");
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ read: true, write: false }, function linkSyncWritePerm(): void {
- let err;
- try {
- Deno.linkSync("oldbaddir", "newbaddir");
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ read: true, write: true }, async function linkSuccess(): Promise<
- void
-> {
- const testDir = Deno.makeTempDirSync();
- const oldData = "Hardlink";
- const oldName = testDir + "/oldname";
- const newName = testDir + "/newname";
- Deno.writeFileSync(oldName, new TextEncoder().encode(oldData));
- // Create the hard link.
- await Deno.link(oldName, newName);
- // We should expect reading the same content.
- const newData = new TextDecoder().decode(Deno.readFileSync(newName));
- assertEquals(oldData, newData);
- // Writing to newname also affects oldname.
- const newData2 = "Modified";
- Deno.writeFileSync(newName, new TextEncoder().encode(newData2));
- assertEquals(newData2, new TextDecoder().decode(Deno.readFileSync(oldName)));
- // Writing to oldname also affects newname.
- const newData3 = "ModifiedAgain";
- Deno.writeFileSync(oldName, new TextEncoder().encode(newData3));
- assertEquals(newData3, new TextDecoder().decode(Deno.readFileSync(newName)));
- // Remove oldname. File still accessible through newname.
- Deno.removeSync(oldName);
- const newNameStat = Deno.statSync(newName);
- assert(newNameStat.isFile());
- assert(!newNameStat.isSymlink()); // Not a symlink.
- assertEquals(newData3, new TextDecoder().decode(Deno.readFileSync(newName)));
-});
diff --git a/js/location.ts b/js/location.ts
deleted file mode 100644
index d495f99ca..000000000
--- a/js/location.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { URL } from "./url.ts";
-import { notImplemented } from "./util.ts";
-import { Location } from "./dom_types.ts";
-import { window } from "./window.ts";
-
-export class LocationImpl implements Location {
- constructor(url: string) {
- const u = new URL(url);
- this.url = u;
- this.hash = u.hash;
- this.host = u.host;
- this.href = u.href;
- this.hostname = u.hostname;
- this.origin = u.protocol + "//" + u.host;
- this.pathname = u.pathname;
- this.protocol = u.protocol;
- this.port = u.port;
- this.search = u.search;
- }
-
- private url: URL;
-
- toString(): string {
- return this.url.toString();
- }
-
- readonly ancestorOrigins: string[] = [];
- hash: string;
- host: string;
- hostname: string;
- href: string;
- readonly origin: string;
- pathname: string;
- port: string;
- protocol: string;
- search: string;
- assign(_url: string): void {
- throw notImplemented();
- }
- reload(): void {
- throw notImplemented();
- }
- replace(_url: string): void {
- throw notImplemented();
- }
-}
-
-export function setLocation(url: string): void {
- window.location = new LocationImpl(url);
- Object.freeze(window.location);
-}
diff --git a/js/location_test.ts b/js/location_test.ts
deleted file mode 100644
index c8daab16d..000000000
--- a/js/location_test.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert } from "./test_util.ts";
-
-test(function locationBasic(): void {
- // location example: file:///Users/rld/src/deno/js/unit_tests.ts
- console.log("location", window.location.toString());
- assert(window.location.toString().endsWith("unit_tests.ts"));
-});
diff --git a/js/main.ts b/js/main.ts
deleted file mode 100644
index 09e7ce453..000000000
--- a/js/main.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import "./globals.ts";
-
-import { assert, log } from "./util.ts";
-import * as os from "./os.ts";
-import { args } from "./deno.ts";
-import { setPrepareStackTrace } from "./error_stack.ts";
-import { replLoop } from "./repl.ts";
-import { setVersions } from "./version.ts";
-import { window } from "./window.ts";
-import { setLocation } from "./location.ts";
-import { setBuildInfo } from "./build.ts";
-import { setSignals } from "./process.ts";
-
-function denoMain(preserveDenoNamespace = true, name?: string): void {
- const s = os.start(preserveDenoNamespace, name);
-
- setBuildInfo(s.os, s.arch);
- setSignals();
- setVersions(s.denoVersion, s.v8Version, s.tsVersion);
-
- setPrepareStackTrace(Error);
-
- if (s.mainModule) {
- assert(s.mainModule.length > 0);
- setLocation(s.mainModule);
- }
-
- log("cwd", s.cwd);
-
- for (let i = 1; i < s.argv.length; i++) {
- args.push(s.argv[i]);
- }
- log("args", args);
- Object.freeze(args);
-
- if (!s.mainModule) {
- replLoop();
- }
-}
-window["denoMain"] = denoMain;
diff --git a/js/make_temp_dir.ts b/js/make_temp_dir.ts
deleted file mode 100644
index 14494b5da..000000000
--- a/js/make_temp_dir.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.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 {
- return sendSync(dispatch.OP_MAKE_TEMP_DIR, options);
-}
-
-/** 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 async function makeTempDir(
- options: MakeTempDirOptions = {}
-): Promise<string> {
- return await sendAsync(dispatch.OP_MAKE_TEMP_DIR, options);
-}
diff --git a/js/make_temp_dir_test.ts b/js/make_temp_dir_test.ts
deleted file mode 100644
index aa44b65c5..000000000
--- a/js/make_temp_dir_test.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, testPerm, assert, assertEquals } from "./test_util.ts";
-
-testPerm({ write: true }, function makeTempDirSyncSuccess(): void {
- const dir1 = Deno.makeTempDirSync({ prefix: "hello", suffix: "world" });
- const dir2 = Deno.makeTempDirSync({ prefix: "hello", suffix: "world" });
- // Check that both dirs are different.
- assert(dir1 !== dir2);
- for (const dir of [dir1, dir2]) {
- // Check that the prefix and suffix are applied.
- const lastPart = dir.replace(/^.*[\\\/]/, "");
- assert(lastPart.startsWith("hello"));
- assert(lastPart.endsWith("world"));
- }
- // Check that the `dir` option works.
- const dir3 = Deno.makeTempDirSync({ dir: dir1 });
- assert(dir3.startsWith(dir1));
- assert(/^[\\\/]/.test(dir3.slice(dir1.length)));
- // Check that creating a temp dir inside a nonexisting directory fails.
- let err;
- try {
- Deno.makeTempDirSync({ dir: "/baddir" });
- } catch (err_) {
- err = err_;
- }
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-test(function makeTempDirSyncPerm(): void {
- // makeTempDirSync should require write permissions (for now).
- let err;
- try {
- Deno.makeTempDirSync({ dir: "/baddir" });
- } catch (err_) {
- err = err_;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ write: true }, async function makeTempDirSuccess(): Promise<void> {
- const dir1 = await Deno.makeTempDir({ prefix: "hello", suffix: "world" });
- const dir2 = await Deno.makeTempDir({ prefix: "hello", suffix: "world" });
- // Check that both dirs are different.
- assert(dir1 !== dir2);
- for (const dir of [dir1, dir2]) {
- // Check that the prefix and suffix are applied.
- const lastPart = dir.replace(/^.*[\\\/]/, "");
- assert(lastPart.startsWith("hello"));
- assert(lastPart.endsWith("world"));
- }
- // Check that the `dir` option works.
- const dir3 = await Deno.makeTempDir({ dir: dir1 });
- assert(dir3.startsWith(dir1));
- assert(/^[\\\/]/.test(dir3.slice(dir1.length)));
- // Check that creating a temp dir inside a nonexisting directory fails.
- let err;
- try {
- await Deno.makeTempDir({ dir: "/baddir" });
- } catch (err_) {
- err = err_;
- }
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
diff --git a/js/metrics.ts b/js/metrics.ts
deleted file mode 100644
index b32c29789..000000000
--- a/js/metrics.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as dispatch from "./dispatch.ts";
-import { sendSync } from "./dispatch_json.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 {
- return sendSync(dispatch.OP_METRICS);
-}
diff --git a/js/metrics_test.ts b/js/metrics_test.ts
deleted file mode 100644
index de41a0cb1..000000000
--- a/js/metrics_test.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, testPerm, assert } from "./test_util.ts";
-
-test(async function metrics(): Promise<void> {
- const m1 = Deno.metrics();
- assert(m1.opsDispatched > 0);
- assert(m1.opsCompleted > 0);
- assert(m1.bytesSentControl > 0);
- assert(m1.bytesSentData >= 0);
- assert(m1.bytesReceived > 0);
-
- // Write to stdout to ensure a "data" message gets sent instead of just
- // control messages.
- const dataMsg = new Uint8Array([41, 42, 43]);
- await Deno.stdout.write(dataMsg);
-
- const m2 = Deno.metrics();
- assert(m2.opsDispatched > m1.opsDispatched);
- assert(m2.opsCompleted > m1.opsCompleted);
- assert(m2.bytesSentControl > m1.bytesSentControl);
- assert(m2.bytesSentData >= m1.bytesSentData + dataMsg.byteLength);
- assert(m2.bytesReceived > m1.bytesReceived);
-});
-
-testPerm({ write: true }, function metricsUpdatedIfNoResponseSync(): void {
- const filename = Deno.makeTempDirSync() + "/test.txt";
-
- const data = new Uint8Array([41, 42, 43]);
- Deno.writeFileSync(filename, data, { perm: 0o666 });
-
- const metrics = Deno.metrics();
- assert(metrics.opsDispatched === metrics.opsCompleted);
-});
-
-testPerm(
- { write: true },
- async function metricsUpdatedIfNoResponseAsync(): Promise<void> {
- const filename = Deno.makeTempDirSync() + "/test.txt";
-
- const data = new Uint8Array([41, 42, 43]);
- await Deno.writeFile(filename, data, { perm: 0o666 });
-
- const metrics = Deno.metrics();
- assert(metrics.opsDispatched === metrics.opsCompleted);
- }
-);
diff --git a/js/mixins/dom_iterable.ts b/js/mixins/dom_iterable.ts
deleted file mode 100644
index bbd1905ce..000000000
--- a/js/mixins/dom_iterable.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { DomIterable } from "../dom_types.ts";
-import { window } from "../window.ts";
-import { requiredArguments } from "../util.ts";
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-type Constructor<T = {}> = new (...args: any[]) => T;
-
-/** Mixes in a DOM iterable methods into a base class, assumes that there is
- * a private data iterable that is part of the base class, located at
- * `[dataSymbol]`.
- * TODO Don't expose DomIterableMixin from "deno" namespace.
- */
-export function DomIterableMixin<K, V, TBase extends Constructor>(
- Base: TBase,
- dataSymbol: symbol
-): TBase & Constructor<DomIterable<K, V>> {
- // we have to cast `this` as `any` because there is no way to describe the
- // Base class in a way where the Symbol `dataSymbol` is defined. So the
- // runtime code works, but we do lose a little bit of type safety.
-
- // Additionally, we have to not use .keys() nor .values() since the internal
- // slot differs in type - some have a Map, which yields [K, V] in
- // Symbol.iterator, and some have an Array, which yields V, in this case
- // [K, V] too as they are arrays of tuples.
-
- const DomIterable = class extends Base {
- *entries(): IterableIterator<[K, V]> {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- for (const entry of (this as any)[dataSymbol]) {
- yield entry;
- }
- }
-
- *keys(): IterableIterator<K> {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- for (const [key] of (this as any)[dataSymbol]) {
- yield key;
- }
- }
-
- *values(): IterableIterator<V> {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- for (const [, value] of (this as any)[dataSymbol]) {
- yield value;
- }
- }
-
- forEach(
- callbackfn: (value: V, key: K, parent: this) => void,
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- thisArg?: any
- ): void {
- requiredArguments(
- `${this.constructor.name}.forEach`,
- arguments.length,
- 1
- );
- callbackfn = callbackfn.bind(thisArg == null ? window : Object(thisArg));
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- for (const [key, value] of (this as any)[dataSymbol]) {
- callbackfn(value, key, this);
- }
- }
-
- *[Symbol.iterator](): IterableIterator<[K, V]> {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- for (const entry of (this as any)[dataSymbol]) {
- yield entry;
- }
- }
- };
-
- // we want the Base class name to be the name of the class.
- Object.defineProperty(DomIterable, "name", {
- value: Base.name,
- configurable: true
- });
-
- return DomIterable;
-}
diff --git a/js/mixins/dom_iterable_test.ts b/js/mixins/dom_iterable_test.ts
deleted file mode 100644
index 4c84fa68e..000000000
--- a/js/mixins/dom_iterable_test.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert, assertEquals } from "../test_util.ts";
-
-// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
-function setup() {
- const dataSymbol = Symbol("data symbol");
- class Base {
- private [dataSymbol] = new Map<string, number>();
-
- constructor(
- data: Array<[string, number]> | IterableIterator<[string, number]>
- ) {
- for (const [key, value] of data) {
- this[dataSymbol].set(key, value);
- }
- }
- }
-
- return {
- Base,
- // This is using an internal API we don't want published as types, so having
- // to cast to any to "trick" TypeScript
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- DomIterable: (Deno as any).DomIterableMixin(Base, dataSymbol)
- };
-}
-
-test(function testDomIterable(): void {
- const { DomIterable, Base } = setup();
-
- const fixture: Array<[string, number]> = [["foo", 1], ["bar", 2]];
-
- const domIterable = new DomIterable(fixture);
-
- assertEquals(Array.from(domIterable.entries()), fixture);
- assertEquals(Array.from(domIterable.values()), [1, 2]);
- assertEquals(Array.from(domIterable.keys()), ["foo", "bar"]);
-
- let result: Array<[string, number]> = [];
- for (const [key, value] of domIterable) {
- assert(key != null);
- assert(value != null);
- result.push([key, value]);
- }
- assertEquals(fixture, result);
-
- result = [];
- const scope = {};
- function callback(value, key, parent): void {
- assertEquals(parent, domIterable);
- assert(key != null);
- assert(value != null);
- assert(this === scope);
- result.push([key, value]);
- }
- domIterable.forEach(callback, scope);
- assertEquals(fixture, result);
-
- assertEquals(DomIterable.name, Base.name);
-});
-
-test(function testDomIterableScope(): void {
- const { DomIterable } = setup();
-
- const domIterable = new DomIterable([["foo", 1]]);
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- function checkScope(thisArg: any, expected: any): void {
- function callback(): void {
- assertEquals(this, expected);
- }
- domIterable.forEach(callback, thisArg);
- }
-
- checkScope(0, Object(0));
- checkScope("", Object(""));
- checkScope(null, window);
- checkScope(undefined, window);
-});
diff --git a/js/mkdir.ts b/js/mkdir.ts
deleted file mode 100644
index bc09ba358..000000000
--- a/js/mkdir.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.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 = false, mode = 0o777): void {
- sendSync(dispatch.OP_MKDIR, { path, recursive, mode });
-}
-
-/** 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 async function mkdir(
- path: string,
- recursive = false,
- mode = 0o777
-): Promise<void> {
- await sendAsync(dispatch.OP_MKDIR, { path, recursive, mode });
-}
diff --git a/js/mkdir_test.ts b/js/mkdir_test.ts
deleted file mode 100644
index 9e97265f0..000000000
--- a/js/mkdir_test.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-testPerm({ read: true, write: true }, function mkdirSyncSuccess(): void {
- const path = Deno.makeTempDirSync() + "/dir";
- Deno.mkdirSync(path);
- const pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory());
-});
-
-testPerm({ read: true, write: true }, function mkdirSyncMode(): void {
- const path = Deno.makeTempDirSync() + "/dir";
- Deno.mkdirSync(path, false, 0o755); // no perm for x
- const pathInfo = Deno.statSync(path);
- if (pathInfo.mode !== null) {
- // Skip windows
- assertEquals(pathInfo.mode & 0o777, 0o755);
- }
-});
-
-testPerm({ write: false }, function mkdirSyncPerm(): void {
- let err;
- try {
- Deno.mkdirSync("/baddir");
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ read: true, write: true }, async function mkdirSuccess(): Promise<
- void
-> {
- const path = Deno.makeTempDirSync() + "/dir";
- await Deno.mkdir(path);
- const pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory());
-});
-
-testPerm({ write: true }, function mkdirErrIfExists(): void {
- let err;
- try {
- Deno.mkdirSync(".");
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.AlreadyExists);
- assertEquals(err.name, "AlreadyExists");
-});
-
-testPerm({ read: true, write: true }, function mkdirSyncRecursive(): void {
- const path = Deno.makeTempDirSync() + "/nested/directory";
- Deno.mkdirSync(path, true);
- const pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory());
-});
-
-testPerm({ read: true, write: true }, async function mkdirRecursive(): Promise<
- void
-> {
- const path = Deno.makeTempDirSync() + "/nested/directory";
- await Deno.mkdir(path, true);
- const pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory());
-});
diff --git a/js/mock_builtin.js b/js/mock_builtin.js
deleted file mode 100644
index 9c6730d69..000000000
--- a/js/mock_builtin.js
+++ /dev/null
@@ -1,2 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-export default undefined;
diff --git a/js/net.ts b/js/net.ts
deleted file mode 100644
index a7ad2b73c..000000000
--- a/js/net.ts
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { EOF, Reader, Writer, Closer } from "./io.ts";
-import { notImplemented } from "./util.ts";
-import { read, write, close } from "./files.ts";
-import * as dispatch from "./dispatch.ts";
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-
-export type Transport = "tcp";
-// TODO support other types:
-// export type Transport = "tcp" | "tcp4" | "tcp6" | "unix" | "unixpacket";
-
-// TODO(ry) Replace 'address' with 'hostname' and 'port', similar to DialOptions
-// and ListenOptions.
-export interface Addr {
- transport: Transport;
- address: string;
-}
-
-/** A Listener is a generic transport 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>;
-}
-
-enum ShutdownMode {
- // See http://man7.org/linux/man-pages/man2/shutdown.2.html
- // Corresponding to SHUT_RD, SHUT_WR, SHUT_RDWR
- Read = 0,
- Write,
- ReadWrite // unused
-}
-
-function shutdown(rid: number, how: ShutdownMode): void {
- sendSync(dispatch.OP_SHUTDOWN, { rid, how });
-}
-
-export class ConnImpl implements Conn {
- constructor(
- readonly rid: number,
- readonly remoteAddr: string,
- readonly localAddr: string
- ) {}
-
- write(p: Uint8Array): Promise<number> {
- return write(this.rid, p);
- }
-
- read(p: Uint8Array): Promise<number | EOF> {
- return read(this.rid, p);
- }
-
- close(): void {
- close(this.rid);
- }
-
- /** closeRead shuts down (shutdown(2)) the reading side of the TCP connection.
- * Most callers should just use close().
- */
- closeRead(): void {
- shutdown(this.rid, ShutdownMode.Read);
- }
-
- /** closeWrite shuts down (shutdown(2)) the writing side of the TCP
- * connection. Most callers should just use close().
- */
- closeWrite(): void {
- shutdown(this.rid, ShutdownMode.Write);
- }
-}
-
-class ListenerImpl implements Listener {
- constructor(
- readonly rid: number,
- private transport: Transport,
- private localAddr: string
- ) {}
-
- async accept(): Promise<Conn> {
- const res = await sendAsync(dispatch.OP_ACCEPT, { rid: this.rid });
- return new ConnImpl(res.rid, res.remoteAddr, res.localAddr);
- }
-
- close(): void {
- close(this.rid);
- }
-
- addr(): Addr {
- return {
- transport: this.transport,
- address: this.localAddr
- };
- }
-
- async next(): Promise<IteratorResult<Conn>> {
- return {
- done: false,
- value: await this.accept()
- };
- }
-
- [Symbol.asyncIterator](): AsyncIterator<Conn> {
- return this;
- }
-}
-
-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;
-}
-
-export interface ListenOptions {
- port: number;
- hostname?: string;
- transport?: Transport;
-}
-
-/** Listen announces on the local transport address.
- *
- * @param options
- * @param options.port The port to connect to. (Required.)
- * @param options.hostname A literal IP address or host name that can be
- * resolved to an IP address. If not specified, defaults to 0.0.0.0
- * @param options.transport Defaults to "tcp". Later we plan to add "tcp4",
- * "tcp6", "udp", "udp4", "udp6", "ip", "ip4", "ip6", "unix", "unixgram" and
- * "unixpacket".
- *
- * Examples:
- *
- * listen({ port: 80 })
- * listen({ hostname: "192.0.2.1", port: 80 })
- * listen({ hostname: "[2001:db8::1]", port: 80 });
- * listen({ hostname: "golang.org", port: 80, transport: "tcp" })
- */
-export function listen(options: ListenOptions): Listener {
- const hostname = options.hostname || "0.0.0.0";
- const transport = options.transport || "tcp";
- const res = sendSync(dispatch.OP_LISTEN, {
- hostname,
- port: options.port,
- transport
- });
- return new ListenerImpl(res.rid, transport, res.localAddr);
-}
-
-export interface DialOptions {
- port: number;
- hostname?: string;
- transport?: Transport;
-}
-
-/** Dial connects to the address on the named transport.
- *
- * @param options
- * @param options.port The port to connect to. (Required.)
- * @param options.hostname A literal IP address or host name that can be
- * resolved to an IP address. If not specified, defaults to 127.0.0.1
- * @param options.transport Defaults to "tcp". Later we plan to add "tcp4",
- * "tcp6", "udp", "udp4", "udp6", "ip", "ip4", "ip6", "unix", "unixgram" and
- * "unixpacket".
- *
- * Examples:
- *
- * dial({ port: 80 })
- * dial({ hostname: "192.0.2.1", port: 80 })
- * dial({ hostname: "[2001:db8::1]", port: 80 });
- * dial({ hostname: "golang.org", port: 80, transport: "tcp" })
- */
-export async function dial(options: DialOptions): Promise<Conn> {
- const res = await sendAsync(dispatch.OP_DIAL, {
- hostname: options.hostname || "127.0.0.1",
- port: options.port,
- transport: options.transport || "tcp"
- });
- return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!);
-}
-
-/** **RESERVED** */
-export async function connect(
- _transport: Transport,
- _address: string
-): Promise<Conn> {
- return notImplemented();
-}
diff --git a/js/net_test.ts b/js/net_test.ts
deleted file mode 100644
index 33f4f7d07..000000000
--- a/js/net_test.ts
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-testPerm({ net: true }, function netListenClose(): void {
- const listener = Deno.listen({ hostname: "127.0.0.1", port: 4500 });
- const addr = listener.addr();
- assertEquals(addr.transport, "tcp");
- // TODO(ry) Replace 'address' with 'hostname' and 'port', similar to
- // DialOptions and ListenOptions.
- assertEquals(addr.address, "127.0.0.1:4500");
- listener.close();
-});
-
-testPerm({ net: true }, async function netCloseWhileAccept(): Promise<void> {
- const listener = Deno.listen({ port: 4501 });
- const p = listener.accept();
- listener.close();
- let err;
- try {
- await p;
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.Other);
- assertEquals(err.message, "Listener has been closed");
-});
-
-testPerm({ net: true }, async function netConcurrentAccept(): Promise<void> {
- const listener = Deno.listen({ port: 4502 });
- let acceptErrCount = 0;
- const checkErr = (e): void => {
- assertEquals(e.kind, Deno.ErrorKind.Other);
- if (e.message === "Listener has been closed") {
- assertEquals(acceptErrCount, 1);
- } else if (e.message === "Another accept task is ongoing") {
- acceptErrCount++;
- } else {
- throw new Error("Unexpected error message");
- }
- };
- const p = listener.accept().catch(checkErr);
- const p1 = listener.accept().catch(checkErr);
- await Promise.race([p, p1]);
- listener.close();
- await [p, p1];
- assertEquals(acceptErrCount, 1);
-});
-
-testPerm({ net: true }, async function netDialListen(): Promise<void> {
- const listener = Deno.listen({ port: 4500 });
- listener.accept().then(
- async (conn): Promise<void> => {
- assert(conn.remoteAddr != null);
- assertEquals(conn.localAddr, "127.0.0.1:4500");
- await conn.write(new Uint8Array([1, 2, 3]));
- conn.close();
- }
- );
- const conn = await Deno.dial({ hostname: "127.0.0.1", port: 4500 });
- assertEquals(conn.remoteAddr, "127.0.0.1:4500");
- assert(conn.localAddr != null);
- const buf = new Uint8Array(1024);
- const readResult = await conn.read(buf);
- assertEquals(3, readResult);
- assertEquals(1, buf[0]);
- assertEquals(2, buf[1]);
- assertEquals(3, buf[2]);
- assert(conn.rid > 0);
-
- assert(readResult !== Deno.EOF);
-
- const readResult2 = await conn.read(buf);
- assertEquals(Deno.EOF, readResult2);
-
- listener.close();
- conn.close();
-});
-
-/* TODO(ry) Re-enable this test.
-testPerm({ net: true }, async function netListenAsyncIterator(): Promise<void> {
- const listener = Deno.listen(":4500");
- const runAsyncIterator = async (): Promise<void> => {
- for await (let conn of listener) {
- await conn.write(new Uint8Array([1, 2, 3]));
- conn.close();
- }
- };
- runAsyncIterator();
- const conn = await Deno.dial("127.0.0.1:4500");
- const buf = new Uint8Array(1024);
- const readResult = await conn.read(buf);
- assertEquals(3, readResult);
- assertEquals(1, buf[0]);
- assertEquals(2, buf[1]);
- assertEquals(3, buf[2]);
- assert(conn.rid > 0);
-
- assert(readResult !== Deno.EOF);
-
- const readResult2 = await conn.read(buf);
- assertEquals(Deno.EOF, readResult2);
-
- listener.close();
- conn.close();
-});
- */
-
-/* TODO Fix broken test.
-testPerm({ net: true }, async function netCloseReadSuccess() {
- const addr = "127.0.0.1:4500";
- const listener = Deno.listen(addr);
- const closeDeferred = deferred();
- const closeReadDeferred = deferred();
- listener.accept().then(async conn => {
- await closeReadDeferred.promise;
- await conn.write(new Uint8Array([1, 2, 3]));
- const buf = new Uint8Array(1024);
- const readResult = await conn.read(buf);
- assertEquals(3, readResult);
- assertEquals(4, buf[0]);
- assertEquals(5, buf[1]);
- assertEquals(6, buf[2]);
- conn.close();
- closeDeferred.resolve();
- });
- const conn = await Deno.dial(addr);
- conn.closeRead(); // closing read
- closeReadDeferred.resolve();
- const buf = new Uint8Array(1024);
- const readResult = await conn.read(buf);
- assertEquals(Deno.EOF, readResult); // with immediate EOF
- // Ensure closeRead does not impact write
- await conn.write(new Uint8Array([4, 5, 6]));
- await closeDeferred.promise;
- listener.close();
- conn.close();
-});
-*/
-
-/* TODO Fix broken test.
-testPerm({ net: true }, async function netDoubleCloseRead() {
- const addr = "127.0.0.1:4500";
- const listener = Deno.listen(addr);
- const closeDeferred = deferred();
- listener.accept().then(async conn => {
- await conn.write(new Uint8Array([1, 2, 3]));
- await closeDeferred.promise;
- conn.close();
- });
- const conn = await Deno.dial(addr);
- conn.closeRead(); // closing read
- let err;
- try {
- // Duplicated close should throw error
- conn.closeRead();
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.NotConnected);
- assertEquals(err.name, "NotConnected");
- closeDeferred.resolve();
- listener.close();
- conn.close();
-});
-*/
-
-/* TODO Fix broken test.
-testPerm({ net: true }, async function netCloseWriteSuccess() {
- const addr = "127.0.0.1:4500";
- const listener = Deno.listen(addr);
- const closeDeferred = deferred();
- listener.accept().then(async conn => {
- await conn.write(new Uint8Array([1, 2, 3]));
- await closeDeferred.promise;
- conn.close();
- });
- const conn = await Deno.dial(addr);
- conn.closeWrite(); // closing write
- const buf = new Uint8Array(1024);
- // Check read not impacted
- const readResult = await conn.read(buf);
- assertEquals(3, readResult);
- assertEquals(1, buf[0]);
- assertEquals(2, buf[1]);
- assertEquals(3, buf[2]);
- // Check write should be closed
- let err;
- try {
- await conn.write(new Uint8Array([1, 2, 3]));
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.BrokenPipe);
- assertEquals(err.name, "BrokenPipe");
- closeDeferred.resolve();
- listener.close();
- conn.close();
-});
-*/
-
-/* TODO Fix broken test.
-testPerm({ net: true }, async function netDoubleCloseWrite() {
- const addr = "127.0.0.1:4500";
- const listener = Deno.listen(addr);
- const closeDeferred = deferred();
- listener.accept().then(async conn => {
- await closeDeferred.promise;
- conn.close();
- });
- const conn = await Deno.dial(addr);
- conn.closeWrite(); // closing write
- let err;
- try {
- // Duplicated close should throw error
- conn.closeWrite();
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.NotConnected);
- assertEquals(err.name, "NotConnected");
- closeDeferred.resolve();
- listener.close();
- conn.close();
-});
-*/
diff --git a/js/os.ts b/js/os.ts
deleted file mode 100644
index 2fc06434a..000000000
--- a/js/os.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { core } from "./core.ts";
-import * as dispatch from "./dispatch.ts";
-import { sendSync } from "./dispatch_json.ts";
-import { assert } from "./util.ts";
-import * as util from "./util.ts";
-import { window } from "./window.ts";
-import { OperatingSystem, Arch } from "./build.ts";
-
-// builtin modules
-import { _setGlobals } from "./deno.ts";
-
-/** Check if running in terminal.
- *
- * console.log(Deno.isTTY().stdout);
- */
-export function isTTY(): { stdin: boolean; stdout: boolean; stderr: boolean } {
- return sendSync(dispatch.OP_IS_TTY);
-}
-
-/** Get the hostname.
- * Requires the `--allow-env` flag.
- *
- * console.log(Deno.hostname());
- */
-export function hostname(): string {
- return sendSync(dispatch.OP_HOSTNAME);
-}
-
-/** Exit the Deno process with optional exit code. */
-export function exit(code = 0): never {
- sendSync(dispatch.OP_EXIT, { code });
- return util.unreachable();
-}
-
-function setEnv(key: string, value: string): void {
- sendSync(dispatch.OP_SET_ENV, { key, value });
-}
-
-function getEnv(key: string): string | undefined {
- return sendSync(dispatch.OP_GET_ENV, { key })[0];
-}
-
-/** 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.
- *
- * console.log(Deno.env("SHELL"));
- * 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 };
-export function env(key: string): string | undefined;
-export function env(
- key?: string
-): { [index: string]: string } | string | undefined {
- if (key) {
- return getEnv(key);
- }
- const env = sendSync(dispatch.OP_ENV);
- return new Proxy(env, {
- set(obj, prop: string, value: string): boolean {
- setEnv(prop, value);
- return Reflect.set(obj, prop, value);
- }
- });
-}
-
-interface Start {
- cwd: string;
- pid: number;
- argv: string[];
- mainModule: string; // Absolute URL.
- debugFlag: boolean;
- depsFlag: boolean;
- typesFlag: boolean;
- versionFlag: boolean;
- denoVersion: string;
- v8Version: string;
- tsVersion: string;
- noColor: boolean;
- xevalDelim: string;
- os: OperatingSystem;
- arch: Arch;
-}
-
-// This function bootstraps an environment within Deno, it is shared both by
-// the runtime and the compiler environments.
-// @internal
-export function start(preserveDenoNamespace = true, source?: string): Start {
- core.setAsyncHandler(dispatch.asyncMsgFromRust);
- const ops = core.ops();
- // TODO(bartlomieju): this is a prototype, we should come up with
- // something a bit more sophisticated
- for (const [name, opId] of Object.entries(ops)) {
- const opName = `OP_${name.toUpperCase()}`;
- // Assign op ids to actual variables
- dispatch[opName] = opId;
- }
- // First we send an empty `Start` message to let the privileged side know we
- // are ready. The response should be a `StartRes` message containing the CLI
- // args and other info.
- const s = sendSync(dispatch.OP_START);
-
- util.setLogDebug(s.debugFlag, source);
-
- // pid and noColor need to be set in the Deno module before it's set to be
- // frozen.
- _setGlobals(s.pid, s.noColor);
- delete window.Deno._setGlobals;
- Object.freeze(window.Deno);
-
- if (preserveDenoNamespace) {
- util.immutableDefine(window, "Deno", window.Deno);
- // Deno.core could ONLY be safely frozen here (not in globals.ts)
- // since shared_queue.js will modify core properties.
- Object.freeze(window.Deno.core);
- // core.sharedQueue is an object so we should also freeze it.
- Object.freeze(window.Deno.core.sharedQueue);
- } else {
- // Remove window.Deno
- delete window.Deno;
- assert(window.Deno === undefined);
- }
-
- return s;
-}
-
-/**
- * Returns the current user's home directory.
- * Requires the `--allow-env` flag.
- */
-export function homeDir(): string {
- const path = sendSync(dispatch.OP_HOME_DIR);
- if (!path) {
- throw new Error("Could not get home directory.");
- }
- return path;
-}
-
-/**
- * Returns the path to the current deno executable.
- * Requires the `--allow-env` flag.
- */
-export function execPath(): string {
- return sendSync(dispatch.OP_EXEC_PATH);
-}
diff --git a/js/os_test.ts b/js/os_test.ts
deleted file mode 100644
index 0d07df1b4..000000000
--- a/js/os_test.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import {
- test,
- testPerm,
- assert,
- assertEquals,
- assertNotEquals
-} from "./test_util.ts";
-
-testPerm({ env: true }, function envSuccess(): void {
- const env = Deno.env();
- assert(env !== null);
- // eslint-disable-next-line @typescript-eslint/camelcase
- env.test_var = "Hello World";
- const newEnv = Deno.env();
- assertEquals(env.test_var, newEnv.test_var);
- assertEquals(Deno.env("test_var"), env.test_var);
-});
-
-testPerm({ env: true }, function envNotFound(): void {
- const r = Deno.env("env_var_does_not_exist!");
- assertEquals(r, undefined);
-});
-
-test(function envPermissionDenied1(): void {
- let err;
- try {
- Deno.env();
- } catch (e) {
- err = e;
- }
- assertNotEquals(err, undefined);
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-test(function envPermissionDenied2(): void {
- let err;
- try {
- Deno.env("PATH");
- } catch (e) {
- err = e;
- }
- assertNotEquals(err, undefined);
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-if (Deno.build.os === "win") {
- // This test verifies that on Windows, environment variables are
- // case-insensitive. Case normalization needs be done using the collation
- // that Windows uses, rather than naively using String.toLowerCase().
- testPerm({ env: true, run: true }, async function envCaseInsensitive() {
- // Utility function that runs a Deno subprocess with the environment
- // specified in `inputEnv`. The subprocess reads the environment variables
- // which are in the keys of `expectedEnv` and writes them to stdout as JSON.
- // It is then verified that these match with the values of `expectedEnv`.
- const checkChildEnv = async (inputEnv, expectedEnv): Promise<void> => {
- const src = `
- console.log(
- ${JSON.stringify(Object.keys(expectedEnv))}.map(k => Deno.env(k))
- )`;
- const proc = Deno.run({
- args: [Deno.execPath(), "eval", src],
- env: inputEnv,
- stdout: "piped"
- });
- const status = await proc.status();
- assertEquals(status.success, true);
- const expectedValues = Object.values(expectedEnv);
- const actualValues = JSON.parse(
- new TextDecoder().decode(await proc.output())
- );
- assertEquals(actualValues, expectedValues);
- };
-
- assertEquals(Deno.env("path"), Deno.env("PATH"));
- assertEquals(Deno.env("Path"), Deno.env("PATH"));
-
- // Check 'foo', 'Foo' and 'Foo' are case folded.
- await checkChildEnv({ foo: "X" }, { foo: "X", Foo: "X", FOO: "X" });
-
- // Check that 'µ' and 'Μ' are not case folded.
- const lc1 = "µ";
- const uc1 = lc1.toUpperCase();
- assertNotEquals(lc1, uc1);
- await checkChildEnv(
- { [lc1]: "mu", [uc1]: "MU" },
- { [lc1]: "mu", [uc1]: "MU" }
- );
-
- // Check that 'dž' and 'DŽ' are folded, but 'Dž' is preserved.
- const c2 = "Dž";
- const lc2 = c2.toLowerCase();
- const uc2 = c2.toUpperCase();
- assertNotEquals(c2, lc2);
- assertNotEquals(c2, uc2);
- await checkChildEnv(
- { [c2]: "Dz", [lc2]: "dz" },
- { [c2]: "Dz", [lc2]: "dz", [uc2]: "dz" }
- );
- await checkChildEnv(
- { [c2]: "Dz", [uc2]: "DZ" },
- { [c2]: "Dz", [uc2]: "DZ", [lc2]: "DZ" }
- );
- });
-}
-
-test(function osPid(): void {
- console.log("pid", Deno.pid);
- assert(Deno.pid > 0);
-});
-
-// See complete tests in tools/is_tty_test.py
-test(function osIsTTYSmoke(): void {
- console.log(Deno.isTTY());
-});
-
-testPerm({ env: true }, function homeDir(): void {
- assertNotEquals(Deno.homeDir(), "");
-});
-
-testPerm({ env: false }, function homeDirPerm(): void {
- let caughtError = false;
- try {
- Deno.homeDir();
- } catch (err) {
- caughtError = true;
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ env: true }, function execPath(): void {
- assertNotEquals(Deno.execPath(), "");
-});
-
-testPerm({ env: false }, function execPathPerm(): void {
- let caughtError = false;
- try {
- Deno.execPath();
- } catch (err) {
- caughtError = true;
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ env: true }, function hostnameDir(): void {
- assertNotEquals(Deno.hostname(), "");
-});
-
-testPerm({ env: false }, function hostnamePerm(): void {
- let caughtError = false;
- try {
- Deno.hostname();
- } catch (err) {
- caughtError = true;
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
- }
- assert(caughtError);
-});
diff --git a/js/performance.ts b/js/performance.ts
deleted file mode 100644
index 6ea8e56e1..000000000
--- a/js/performance.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as dispatch from "./dispatch.ts";
-import { sendSync } from "./dispatch_json.ts";
-
-interface NowResponse {
- seconds: number;
- subsecNanos: number;
-}
-
-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 {
- const res = sendSync(dispatch.OP_NOW) as NowResponse;
- return res.seconds * 1e3 + res.subsecNanos / 1e6;
- }
-}
diff --git a/js/performance_test.ts b/js/performance_test.ts
deleted file mode 100644
index ac682364e..000000000
--- a/js/performance_test.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert } from "./test_util.ts";
-
-testPerm({ hrtime: false }, function now(): void {
- const start = performance.now();
- setTimeout((): void => {
- const end = performance.now();
- assert(end - start >= 10);
- }, 10);
-});
diff --git a/js/permissions.ts b/js/permissions.ts
deleted file mode 100644
index 4f393501c..000000000
--- a/js/permissions.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as dispatch from "./dispatch.ts";
-import { sendSync } from "./dispatch_json.ts";
-
-/** Permissions as granted by the caller */
-export interface Permissions {
- read: boolean;
- write: boolean;
- net: boolean;
- env: boolean;
- run: boolean;
- hrtime: boolean;
- // NOTE: Keep in sync with src/permissions.rs
-}
-
-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 {
- return sendSync(dispatch.OP_PERMISSIONS) as 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 {
- sendSync(dispatch.OP_REVOKE_PERMISSION, { permission });
-}
diff --git a/js/permissions_test.ts b/js/permissions_test.ts
deleted file mode 100644
index 6511c2dcb..000000000
--- a/js/permissions_test.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-const knownPermissions: Deno.Permission[] = [
- "run",
- "read",
- "write",
- "net",
- "env",
- "hrtime"
-];
-
-for (const grant of knownPermissions) {
- testPerm({ [grant]: true }, function envGranted(): void {
- const perms = Deno.permissions();
- assert(perms !== null);
- for (const perm in perms) {
- assertEquals(perms[perm], perm === grant);
- }
-
- Deno.revokePermission(grant);
-
- const revoked = Deno.permissions();
- for (const perm in revoked) {
- assertEquals(revoked[perm], false);
- }
- });
-}
diff --git a/js/process.ts b/js/process.ts
deleted file mode 100644
index 0c77929f9..000000000
--- a/js/process.ts
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.ts";
-import { File, close } from "./files.ts";
-import { ReadCloser, WriteCloser } from "./io.ts";
-import { readAll } from "./buffer.ts";
-import { assert, unreachable } from "./util.ts";
-import { build } from "./build.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.
- */
-export type ProcessStdio = "inherit" | "piped" | "null";
-
-// TODO Maybe extend VSCode's 'CommandOptions'?
-// See https://code.visualstudio.com/docs/editor/tasks-appendix#_schema-for-tasksjson
-export interface RunOptions {
- args: string[];
- cwd?: string;
- env?: { [key: string]: string };
- stdout?: ProcessStdio | number;
- stderr?: ProcessStdio | number;
- stdin?: ProcessStdio | number;
-}
-
-interface RunStatusResponse {
- gotSignal: boolean;
- exitCode: number;
- exitSignal: number;
-}
-
-async function runStatus(rid: number): Promise<ProcessStatus> {
- const res = (await sendAsync(dispatch.OP_RUN_STATUS, {
- rid
- })) as RunStatusResponse;
-
- if (res.gotSignal) {
- const signal = res.exitSignal;
- return { signal, success: false };
- } else {
- const code = res.exitCode;
- return { code, success: code === 0 };
- }
-}
-
-/** 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 {
- sendSync(dispatch.OP_KILL, { pid, signo });
-}
-
-export class Process {
- readonly rid: number;
- readonly pid: number;
- readonly stdin?: WriteCloser;
- readonly stdout?: ReadCloser;
- readonly stderr?: ReadCloser;
-
- // @internal
- constructor(res: RunResponse) {
- this.rid = res.rid;
- this.pid = res.pid;
-
- if (res.stdinRid && res.stdinRid > 0) {
- this.stdin = new File(res.stdinRid);
- }
-
- if (res.stdoutRid && res.stdoutRid > 0) {
- this.stdout = new File(res.stdoutRid);
- }
-
- if (res.stderrRid && res.stderrRid > 0) {
- this.stderr = new File(res.stderrRid);
- }
- }
-
- async status(): Promise<ProcessStatus> {
- return await runStatus(this.rid);
- }
-
- /** 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.
- */
- async output(): Promise<Uint8Array> {
- if (!this.stdout) {
- throw new Error("Process.output: stdout is undefined");
- }
- try {
- return await readAll(this.stdout);
- } finally {
- this.stdout.close();
- }
- }
-
- /** 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.
- */
- async stderrOutput(): Promise<Uint8Array> {
- if (!this.stderr) {
- throw new Error("Process.stderrOutput: stderr is undefined");
- }
- try {
- return await readAll(this.stderr);
- } finally {
- this.stderr.close();
- }
- }
-
- close(): void {
- close(this.rid);
- }
-
- kill(signo: number): void {
- kill(this.pid, signo);
- }
-}
-
-export interface ProcessStatus {
- success: boolean;
- code?: number;
- signal?: number; // TODO: Make this a string, e.g. 'SIGTERM'.
-}
-
-// TODO: this method is only used to validate proper option, probably can be renamed
-function stdioMap(s: string): string {
- switch (s) {
- case "inherit":
- case "piped":
- case "null":
- return s;
- default:
- return unreachable();
- }
-}
-
-function isRid(arg: unknown): arg is number {
- return !isNaN(arg as number);
-}
-
-interface RunResponse {
- rid: number;
- pid: number;
- stdinRid: number | null;
- stdoutRid: number | null;
- stderrRid: number | null;
-}
-/**
- * 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 {
- assert(opt.args.length > 0);
- let env: Array<[string, string]> = [];
- if (opt.env) {
- env = Array.from(Object.entries(opt.env));
- }
-
- let stdin = stdioMap("inherit");
- let stdout = stdioMap("inherit");
- let stderr = stdioMap("inherit");
- let stdinRid = 0;
- let stdoutRid = 0;
- let stderrRid = 0;
-
- if (opt.stdin) {
- if (isRid(opt.stdin)) {
- stdinRid = opt.stdin;
- } else {
- stdin = stdioMap(opt.stdin);
- }
- }
-
- if (opt.stdout) {
- if (isRid(opt.stdout)) {
- stdoutRid = opt.stdout;
- } else {
- stdout = stdioMap(opt.stdout);
- }
- }
-
- if (opt.stderr) {
- if (isRid(opt.stderr)) {
- stderrRid = opt.stderr;
- } else {
- stderr = stdioMap(opt.stderr);
- }
- }
-
- const req = {
- args: opt.args.map(String),
- cwd: opt.cwd,
- env,
- stdin,
- stdout,
- stderr,
- stdinRid,
- stdoutRid,
- stderrRid
- };
-
- const res = sendSync(dispatch.OP_RUN, req) as RunResponse;
- return new Process(res);
-}
-
-// From `kill -l`
-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
-}
-
-// From `kill -l`
-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 = {};
-
-export function setSignals(): void {
- if (build.os === "mac") {
- Object.assign(Signal, MacOSSignal);
- } else {
- Object.assign(Signal, LinuxSignal);
- }
-}
diff --git a/js/process_test.ts b/js/process_test.ts
deleted file mode 100644
index 42db06dee..000000000
--- a/js/process_test.ts
+++ /dev/null
@@ -1,377 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import {
- test,
- testPerm,
- assert,
- assertEquals,
- assertStrContains
-} from "./test_util.ts";
-const {
- kill,
- run,
- DenoError,
- ErrorKind,
- readFile,
- open,
- makeTempDir,
- writeFile
-} = Deno;
-
-test(function runPermissions(): void {
- let caughtError = false;
- try {
- Deno.run({ args: ["python", "-c", "print('hello world')"] });
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ run: true }, async function runSuccess(): Promise<void> {
- const p = run({
- args: ["python", "-c", "print('hello world')"]
- });
- const status = await p.status();
- console.log("status", status);
- assertEquals(status.success, true);
- assertEquals(status.code, 0);
- assertEquals(status.signal, undefined);
- p.close();
-});
-
-testPerm({ run: true }, async function runCommandFailedWithCode(): Promise<
- void
-> {
- const p = run({
- args: ["python", "-c", "import sys;sys.exit(41 + 1)"]
- });
- const status = await p.status();
- assertEquals(status.success, false);
- assertEquals(status.code, 42);
- assertEquals(status.signal, undefined);
- p.close();
-});
-
-testPerm({ run: true }, async function runCommandFailedWithSignal(): Promise<
- void
-> {
- if (Deno.build.os === "win") {
- return; // No signals on windows.
- }
- const p = run({
- args: ["python", "-c", "import os;os.kill(os.getpid(), 9)"]
- });
- const status = await p.status();
- assertEquals(status.success, false);
- assertEquals(status.code, undefined);
- assertEquals(status.signal, 9);
- p.close();
-});
-
-testPerm({ run: true }, function runNotFound(): void {
- let error;
- try {
- run({ args: ["this file hopefully doesn't exist"] });
- } catch (e) {
- error = e;
- }
- assert(error !== undefined);
- assert(error instanceof DenoError);
- assertEquals(error.kind, ErrorKind.NotFound);
-});
-
-testPerm(
- { write: true, run: true },
- async function runWithCwdIsAsync(): Promise<void> {
- const enc = new TextEncoder();
- const cwd = await makeTempDir({ prefix: "deno_command_test" });
-
- const exitCodeFile = "deno_was_here";
- const pyProgramFile = "poll_exit.py";
- const pyProgram = `
-from sys import exit
-from time import sleep
-
-while True:
- try:
- with open("${exitCodeFile}", "r") as f:
- line = f.readline()
- code = int(line)
- exit(code)
- except IOError:
- # Retry if we got here before deno wrote the file.
- sleep(0.01)
- pass
-`;
-
- Deno.writeFileSync(`${cwd}/${pyProgramFile}.py`, enc.encode(pyProgram));
- const p = run({
- cwd,
- args: ["python", `${pyProgramFile}.py`]
- });
-
- // Write the expected exit code *after* starting python.
- // This is how we verify that `run()` is actually asynchronous.
- const code = 84;
- Deno.writeFileSync(`${cwd}/${exitCodeFile}`, enc.encode(`${code}`));
-
- const status = await p.status();
- assertEquals(status.success, false);
- assertEquals(status.code, code);
- assertEquals(status.signal, undefined);
- p.close();
- }
-);
-
-testPerm({ run: true }, async function runStdinPiped(): Promise<void> {
- const p = run({
- args: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"],
- stdin: "piped"
- });
- assert(!p.stdout);
- assert(!p.stderr);
-
- const msg = new TextEncoder().encode("hello");
- const n = await p.stdin.write(msg);
- assertEquals(n, msg.byteLength);
-
- p.stdin.close();
-
- const status = await p.status();
- assertEquals(status.success, true);
- assertEquals(status.code, 0);
- assertEquals(status.signal, undefined);
- p.close();
-});
-
-testPerm({ run: true }, async function runStdoutPiped(): Promise<void> {
- const p = run({
- args: ["python", "-c", "import sys; sys.stdout.write('hello')"],
- stdout: "piped"
- });
- assert(!p.stdin);
- assert(!p.stderr);
-
- const data = new Uint8Array(10);
- let r = await p.stdout.read(data);
- if (r === Deno.EOF) {
- throw new Error("p.stdout.read(...) should not be EOF");
- }
- assertEquals(r, 5);
- const s = new TextDecoder().decode(data.subarray(0, r));
- assertEquals(s, "hello");
- r = await p.stdout.read(data);
- assertEquals(r, Deno.EOF);
- p.stdout.close();
-
- const status = await p.status();
- assertEquals(status.success, true);
- assertEquals(status.code, 0);
- assertEquals(status.signal, undefined);
- p.close();
-});
-
-testPerm({ run: true }, async function runStderrPiped(): Promise<void> {
- const p = run({
- args: ["python", "-c", "import sys; sys.stderr.write('hello')"],
- stderr: "piped"
- });
- assert(!p.stdin);
- assert(!p.stdout);
-
- const data = new Uint8Array(10);
- let r = await p.stderr.read(data);
- if (r === Deno.EOF) {
- throw new Error("p.stderr.read should not return EOF here");
- }
- assertEquals(r, 5);
- const s = new TextDecoder().decode(data.subarray(0, r));
- assertEquals(s, "hello");
- r = await p.stderr.read(data);
- assertEquals(r, Deno.EOF);
- p.stderr.close();
-
- const status = await p.status();
- assertEquals(status.success, true);
- assertEquals(status.code, 0);
- assertEquals(status.signal, undefined);
- p.close();
-});
-
-testPerm({ run: true }, async function runOutput(): Promise<void> {
- const p = run({
- args: ["python", "-c", "import sys; sys.stdout.write('hello')"],
- stdout: "piped"
- });
- const output = await p.output();
- const s = new TextDecoder().decode(output);
- assertEquals(s, "hello");
- p.close();
-});
-
-testPerm({ run: true }, async function runStderrOutput(): Promise<void> {
- const p = run({
- args: ["python", "-c", "import sys; sys.stderr.write('error')"],
- stderr: "piped"
- });
- const error = await p.stderrOutput();
- const s = new TextDecoder().decode(error);
- assertEquals(s, "error");
- p.close();
-});
-
-testPerm(
- { run: true, write: true, read: true },
- async function runRedirectStdoutStderr(): Promise<void> {
- const tempDir = await makeTempDir();
- const fileName = tempDir + "/redirected_stdio.txt";
- const file = await open(fileName, "w");
-
- const p = run({
- args: [
- "python",
- "-c",
- "import sys; sys.stderr.write('error\\n'); sys.stdout.write('output\\n');"
- ],
- stdout: file.rid,
- stderr: file.rid
- });
-
- await p.status();
- p.close();
- file.close();
-
- const fileContents = await readFile(fileName);
- const decoder = new TextDecoder();
- const text = decoder.decode(fileContents);
-
- assertStrContains(text, "error");
- assertStrContains(text, "output");
- }
-);
-
-testPerm(
- { run: true, write: true, read: true },
- async function runRedirectStdin(): Promise<void> {
- const tempDir = await makeTempDir();
- const fileName = tempDir + "/redirected_stdio.txt";
- const encoder = new TextEncoder();
- await writeFile(fileName, encoder.encode("hello"));
- const file = await open(fileName, "r");
-
- const p = run({
- args: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"],
- stdin: file.rid
- });
-
- const status = await p.status();
- assertEquals(status.code, 0);
- p.close();
- file.close();
- }
-);
-
-testPerm({ run: true }, async function runEnv(): Promise<void> {
- const p = run({
- args: [
- "python",
- "-c",
- "import os, sys; sys.stdout.write(os.environ.get('FOO', '') + os.environ.get('BAR', ''))"
- ],
- env: {
- FOO: "0123",
- BAR: "4567"
- },
- stdout: "piped"
- });
- const output = await p.output();
- const s = new TextDecoder().decode(output);
- assertEquals(s, "01234567");
- p.close();
-});
-
-testPerm({ run: true }, async function runClose(): Promise<void> {
- const p = run({
- args: [
- "python",
- "-c",
- "from time import sleep; import sys; sleep(10000); sys.stderr.write('error')"
- ],
- stderr: "piped"
- });
- assert(!p.stdin);
- assert(!p.stdout);
-
- p.close();
-
- const data = new Uint8Array(10);
- const r = await p.stderr.read(data);
- assertEquals(r, Deno.EOF);
-});
-
-test(function signalNumbers(): void {
- if (Deno.build.os === "mac") {
- assertEquals(Deno.Signal.SIGSTOP, 17);
- } else if (Deno.build.os === "linux") {
- assertEquals(Deno.Signal.SIGSTOP, 19);
- }
-});
-
-// Ignore signal tests on windows for now...
-if (Deno.build.os !== "win") {
- test(function killPermissions(): void {
- let caughtError = false;
- try {
- // Unlike the other test cases, we don't have permission to spawn a
- // subprocess we can safely kill. Instead we send SIGCONT to the current
- // process - assuming that Deno does not have a special handler set for it
- // and will just continue even if a signal is erroneously sent.
- Deno.kill(Deno.pid, Deno.Signal.SIGCONT);
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
- });
-
- testPerm({ run: true }, async function killSuccess(): Promise<void> {
- const p = run({
- args: ["python", "-c", "from time import sleep; sleep(10000)"]
- });
-
- assertEquals(Deno.Signal.SIGINT, 2);
- kill(p.pid, Deno.Signal.SIGINT);
- const status = await p.status();
-
- assertEquals(status.success, false);
- // TODO(ry) On Linux, status.code is sometimes undefined and sometimes 1.
- // The following assert is causing this test to be flaky. Investigate and
- // re-enable when it can be made deterministic.
- // assertEquals(status.code, 1);
- // assertEquals(status.signal, Deno.Signal.SIGINT);
- });
-
- testPerm({ run: true }, async function killFailed(): Promise<void> {
- const p = run({
- args: ["python", "-c", "from time import sleep; sleep(10000)"]
- });
- assert(!p.stdin);
- assert(!p.stdout);
-
- let err;
- try {
- kill(p.pid, 12345);
- } catch (e) {
- err = e;
- }
-
- assert(!!err);
- assertEquals(err.kind, Deno.ErrorKind.InvalidInput);
- assertEquals(err.name, "InvalidInput");
-
- p.close();
- });
-}
diff --git a/js/read_dir.ts b/js/read_dir.ts
deleted file mode 100644
index 2fa6a566b..000000000
--- a/js/read_dir.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.ts";
-import { FileInfo, FileInfoImpl } from "./file_info.ts";
-import { StatResponse } from "./stat.ts";
-
-interface ReadDirResponse {
- entries: StatResponse[];
-}
-
-function res(response: ReadDirResponse): FileInfo[] {
- return response.entries.map(
- (statRes: StatResponse): FileInfo => {
- return new FileInfoImpl(statRes);
- }
- );
-}
-
-/** Reads the directory given by path and returns a list of file info
- * synchronously.
- *
- * const files = Deno.readDirSync("/");
- */
-export function readDirSync(path: string): FileInfo[] {
- return res(sendSync(dispatch.OP_READ_DIR, { path }));
-}
-
-/** Reads the directory given by path and returns a list of file info.
- *
- * const files = await Deno.readDir("/");
- */
-export async function readDir(path: string): Promise<FileInfo[]> {
- return res(await sendAsync(dispatch.OP_READ_DIR, { path }));
-}
diff --git a/js/read_dir_test.ts b/js/read_dir_test.ts
deleted file mode 100644
index 3e11df9fe..000000000
--- a/js/read_dir_test.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-type FileInfo = Deno.FileInfo;
-
-function assertSameContent(files: FileInfo[]): void {
- let counter = 0;
-
- for (const file of files) {
- if (file.name === "subdir") {
- assert(file.isDirectory());
- counter++;
- }
-
- if (file.name === "002_hello.ts") {
- assertEquals(file.mode!, Deno.statSync(`tests/${file.name}`).mode!);
- counter++;
- }
- }
-
- assertEquals(counter, 2);
-}
-
-testPerm({ read: true }, function readDirSyncSuccess(): void {
- const files = Deno.readDirSync("tests/");
- assertSameContent(files);
-});
-
-testPerm({ read: false }, function readDirSyncPerm(): void {
- let caughtError = false;
- try {
- Deno.readDirSync("tests/");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true }, function readDirSyncNotDir(): void {
- let caughtError = false;
- let src;
-
- try {
- src = Deno.readDirSync("package.json");
- } catch (err) {
- caughtError = true;
- assertEquals(err.kind, Deno.ErrorKind.Other);
- }
- assert(caughtError);
- assertEquals(src, undefined);
-});
-
-testPerm({ read: true }, function readDirSyncNotFound(): void {
- let caughtError = false;
- let src;
-
- try {
- src = Deno.readDirSync("bad_dir_name");
- } catch (err) {
- caughtError = true;
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- }
- assert(caughtError);
- assertEquals(src, undefined);
-});
-
-testPerm({ read: true }, async function readDirSuccess(): Promise<void> {
- const files = await Deno.readDir("tests/");
- assertSameContent(files);
-});
-
-testPerm({ read: false }, async function readDirPerm(): Promise<void> {
- let caughtError = false;
- try {
- await Deno.readDir("tests/");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
diff --git a/js/read_file.ts b/js/read_file.ts
deleted file mode 100644
index de6630cc0..000000000
--- a/js/read_file.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { open, openSync } from "./files.ts";
-import { readAll, readAllSync } from "./buffer.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 {
- const file = openSync(filename);
- const contents = readAllSync(file);
- file.close();
- return contents;
-}
-
-/** 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 async function readFile(filename: string): Promise<Uint8Array> {
- const file = await open(filename);
- const contents = await readAll(file);
- file.close();
- return contents;
-}
diff --git a/js/read_file_test.ts b/js/read_file_test.ts
deleted file mode 100644
index 7d4f4789c..000000000
--- a/js/read_file_test.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-testPerm({ read: true }, function readFileSyncSuccess(): void {
- const data = Deno.readFileSync("package.json");
- assert(data.byteLength > 0);
- const decoder = new TextDecoder("utf-8");
- const json = decoder.decode(data);
- const pkg = JSON.parse(json);
- assertEquals(pkg.name, "deno");
-});
-
-testPerm({ read: false }, function readFileSyncPerm(): void {
- let caughtError = false;
- try {
- Deno.readFileSync("package.json");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true }, function readFileSyncNotFound(): void {
- let caughtError = false;
- let data;
- try {
- data = Deno.readFileSync("bad_filename");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- }
- assert(caughtError);
- assert(data === undefined);
-});
-
-testPerm({ read: true }, async function readFileSuccess(): Promise<void> {
- const data = await Deno.readFile("package.json");
- assert(data.byteLength > 0);
- const decoder = new TextDecoder("utf-8");
- const json = decoder.decode(data);
- const pkg = JSON.parse(json);
- assertEquals(pkg.name, "deno");
-});
-
-testPerm({ read: false }, async function readFilePerm(): Promise<void> {
- let caughtError = false;
- try {
- await Deno.readFile("package.json");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
diff --git a/js/read_link.ts b/js/read_link.ts
deleted file mode 100644
index 861fbff0b..000000000
--- a/js/read_link.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.ts";
-
-/** Returns the destination of the named symbolic link synchronously.
- *
- * const targetPath = Deno.readlinkSync("symlink/path");
- */
-export function readlinkSync(name: string): string {
- return sendSync(dispatch.OP_READ_LINK, { name });
-}
-
-/** Returns the destination of the named symbolic link.
- *
- * const targetPath = await Deno.readlink("symlink/path");
- */
-export async function readlink(name: string): Promise<string> {
- return await sendAsync(dispatch.OP_READ_LINK, { name });
-}
diff --git a/js/read_link_test.ts b/js/read_link_test.ts
deleted file mode 100644
index 83a693e3b..000000000
--- a/js/read_link_test.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-testPerm({ write: true, read: true }, function readlinkSyncSuccess(): void {
- const testDir = Deno.makeTempDirSync();
- const target = testDir + "/target";
- const symlink = testDir + "/symln";
- Deno.mkdirSync(target);
- // TODO Add test for Windows once symlink is implemented for Windows.
- // See https://github.com/denoland/deno/issues/815.
- if (Deno.build.os !== "win") {
- Deno.symlinkSync(target, symlink);
- const targetPath = Deno.readlinkSync(symlink);
- assertEquals(targetPath, target);
- }
-});
-
-testPerm({ read: false }, async function readlinkSyncPerm(): Promise<void> {
- let caughtError = false;
- try {
- Deno.readlinkSync("/symlink");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true }, function readlinkSyncNotFound(): void {
- let caughtError = false;
- let data;
- try {
- data = Deno.readlinkSync("bad_filename");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- }
- assert(caughtError);
- assertEquals(data, undefined);
-});
-
-testPerm({ write: true, read: true }, async function readlinkSuccess(): Promise<
- void
-> {
- const testDir = Deno.makeTempDirSync();
- const target = testDir + "/target";
- const symlink = testDir + "/symln";
- Deno.mkdirSync(target);
- // TODO Add test for Windows once symlink is implemented for Windows.
- // See https://github.com/denoland/deno/issues/815.
- if (Deno.build.os !== "win") {
- Deno.symlinkSync(target, symlink);
- const targetPath = await Deno.readlink(symlink);
- assertEquals(targetPath, target);
- }
-});
-
-testPerm({ read: false }, async function readlinkPerm(): Promise<void> {
- let caughtError = false;
- try {
- await Deno.readlink("/symlink");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
diff --git a/js/remove.ts b/js/remove.ts
deleted file mode 100644
index 36413a7c4..000000000
--- a/js/remove.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.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 {
- sendSync(dispatch.OP_REMOVE, { path, recursive: !!options.recursive });
-}
-
-/** 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 async function remove(
- path: string,
- options: RemoveOption = {}
-): Promise<void> {
- await sendAsync(dispatch.OP_REMOVE, { path, recursive: !!options.recursive });
-}
diff --git a/js/remove_test.ts b/js/remove_test.ts
deleted file mode 100644
index f14386f7f..000000000
--- a/js/remove_test.ts
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-// SYNC
-
-testPerm({ write: true }, function removeSyncDirSuccess(): void {
- // REMOVE EMPTY DIRECTORY
- const path = Deno.makeTempDirSync() + "/dir/subdir";
- Deno.mkdirSync(path);
- const pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory()); // check exist first
- Deno.removeSync(path); // remove
- // We then check again after remove
- let err;
- try {
- Deno.statSync(path);
- } catch (e) {
- err = e;
- }
- // Directory is gone
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: true }, function removeSyncFileSuccess(): void {
- // REMOVE FILE
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- Deno.writeFileSync(filename, data, { perm: 0o666 });
- const fileInfo = Deno.statSync(filename);
- assert(fileInfo.isFile()); // check exist first
- Deno.removeSync(filename); // remove
- // We then check again after remove
- let err;
- try {
- Deno.statSync(filename);
- } catch (e) {
- err = e;
- }
- // File is gone
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: true }, function removeSyncFail(): void {
- // NON-EMPTY DIRECTORY
- const path = Deno.makeTempDirSync() + "/dir/subdir";
- const subPath = path + "/subsubdir";
- Deno.mkdirSync(path);
- Deno.mkdirSync(subPath);
- const pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory()); // check exist first
- const subPathInfo = Deno.statSync(subPath);
- assert(subPathInfo.isDirectory()); // check exist first
- let err;
- try {
- // Should not be able to recursively remove
- Deno.removeSync(path);
- } catch (e) {
- err = e;
- }
- // TODO(ry) Is Other really the error we should get here? What would Go do?
- assertEquals(err.kind, Deno.ErrorKind.Other);
- assertEquals(err.name, "Other");
- // NON-EXISTENT DIRECTORY/FILE
- try {
- // Non-existent
- Deno.removeSync("/baddir");
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: false }, function removeSyncPerm(): void {
- let err;
- try {
- Deno.removeSync("/baddir");
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ write: true }, function removeAllSyncDirSuccess(): void {
- // REMOVE EMPTY DIRECTORY
- let path = Deno.makeTempDirSync() + "/dir/subdir";
- Deno.mkdirSync(path);
- let pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory()); // check exist first
- Deno.removeSync(path, { recursive: true }); // remove
- // We then check again after remove
- let err;
- try {
- Deno.statSync(path);
- } catch (e) {
- err = e;
- }
- // Directory is gone
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
- // REMOVE NON-EMPTY DIRECTORY
- path = Deno.makeTempDirSync() + "/dir/subdir";
- const subPath = path + "/subsubdir";
- Deno.mkdirSync(path);
- Deno.mkdirSync(subPath);
- pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory()); // check exist first
- const subPathInfo = Deno.statSync(subPath);
- assert(subPathInfo.isDirectory()); // check exist first
- Deno.removeSync(path, { recursive: true }); // remove
- // We then check parent directory again after remove
- try {
- Deno.statSync(path);
- } catch (e) {
- err = e;
- }
- // Directory is gone
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: true }, function removeAllSyncFileSuccess(): void {
- // REMOVE FILE
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- Deno.writeFileSync(filename, data, { perm: 0o666 });
- const fileInfo = Deno.statSync(filename);
- assert(fileInfo.isFile()); // check exist first
- Deno.removeSync(filename, { recursive: true }); // remove
- // We then check again after remove
- let err;
- try {
- Deno.statSync(filename);
- } catch (e) {
- err = e;
- }
- // File is gone
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: true }, function removeAllSyncFail(): void {
- // NON-EXISTENT DIRECTORY/FILE
- let err;
- try {
- // Non-existent
- Deno.removeSync("/baddir", { recursive: true });
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: false }, function removeAllSyncPerm(): void {
- let err;
- try {
- Deno.removeSync("/baddir", { recursive: true });
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-// ASYNC
-
-testPerm({ write: true }, async function removeDirSuccess(): Promise<void> {
- // REMOVE EMPTY DIRECTORY
- const path = Deno.makeTempDirSync() + "/dir/subdir";
- Deno.mkdirSync(path);
- const pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory()); // check exist first
- await Deno.remove(path); // remove
- // We then check again after remove
- let err;
- try {
- Deno.statSync(path);
- } catch (e) {
- err = e;
- }
- // Directory is gone
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: true }, async function removeFileSuccess(): Promise<void> {
- // REMOVE FILE
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- Deno.writeFileSync(filename, data, { perm: 0o666 });
- const fileInfo = Deno.statSync(filename);
- assert(fileInfo.isFile()); // check exist first
- await Deno.remove(filename); // remove
- // We then check again after remove
- let err;
- try {
- Deno.statSync(filename);
- } catch (e) {
- err = e;
- }
- // File is gone
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: true }, async function removeFail(): Promise<void> {
- // NON-EMPTY DIRECTORY
- const path = Deno.makeTempDirSync() + "/dir/subdir";
- const subPath = path + "/subsubdir";
- Deno.mkdirSync(path);
- Deno.mkdirSync(subPath);
- const pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory()); // check exist first
- const subPathInfo = Deno.statSync(subPath);
- assert(subPathInfo.isDirectory()); // check exist first
- let err;
- try {
- // Should not be able to recursively remove
- await Deno.remove(path);
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.Other);
- assertEquals(err.name, "Other");
- // NON-EXISTENT DIRECTORY/FILE
- try {
- // Non-existent
- await Deno.remove("/baddir");
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: false }, async function removePerm(): Promise<void> {
- let err;
- try {
- await Deno.remove("/baddir");
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ write: true }, async function removeAllDirSuccess(): Promise<void> {
- // REMOVE EMPTY DIRECTORY
- let path = Deno.makeTempDirSync() + "/dir/subdir";
- Deno.mkdirSync(path);
- let pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory()); // check exist first
- await Deno.remove(path, { recursive: true }); // remove
- // We then check again after remove
- let err;
- try {
- Deno.statSync(path);
- } catch (e) {
- err = e;
- }
- // Directory is gone
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
- // REMOVE NON-EMPTY DIRECTORY
- path = Deno.makeTempDirSync() + "/dir/subdir";
- const subPath = path + "/subsubdir";
- Deno.mkdirSync(path);
- Deno.mkdirSync(subPath);
- pathInfo = Deno.statSync(path);
- assert(pathInfo.isDirectory()); // check exist first
- const subPathInfo = Deno.statSync(subPath);
- assert(subPathInfo.isDirectory()); // check exist first
- await Deno.remove(path, { recursive: true }); // remove
- // We then check parent directory again after remove
- try {
- Deno.statSync(path);
- } catch (e) {
- err = e;
- }
- // Directory is gone
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: true }, async function removeAllFileSuccess(): Promise<void> {
- // REMOVE FILE
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- Deno.writeFileSync(filename, data, { perm: 0o666 });
- const fileInfo = Deno.statSync(filename);
- assert(fileInfo.isFile()); // check exist first
- await Deno.remove(filename, { recursive: true }); // remove
- // We then check again after remove
- let err;
- try {
- Deno.statSync(filename);
- } catch (e) {
- err = e;
- }
- // File is gone
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: true }, async function removeAllFail(): Promise<void> {
- // NON-EXISTENT DIRECTORY/FILE
- let err;
- try {
- // Non-existent
- await Deno.remove("/baddir", { recursive: true });
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
-});
-
-testPerm({ write: false }, async function removeAllPerm(): Promise<void> {
- let err;
- try {
- await Deno.remove("/baddir", { recursive: true });
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
diff --git a/js/rename.ts b/js/rename.ts
deleted file mode 100644
index c906ce37b..000000000
--- a/js/rename.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.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 {
- sendSync(dispatch.OP_RENAME, { oldpath, newpath });
-}
-
-/** 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 async function rename(oldpath: string, newpath: string): Promise<void> {
- await sendAsync(dispatch.OP_RENAME, { oldpath, newpath });
-}
diff --git a/js/rename_test.ts b/js/rename_test.ts
deleted file mode 100644
index 43d02d419..000000000
--- a/js/rename_test.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-testPerm({ read: true, write: true }, function renameSyncSuccess(): void {
- const testDir = Deno.makeTempDirSync();
- const oldpath = testDir + "/oldpath";
- const newpath = testDir + "/newpath";
- Deno.mkdirSync(oldpath);
- Deno.renameSync(oldpath, newpath);
- const newPathInfo = Deno.statSync(newpath);
- assert(newPathInfo.isDirectory());
-
- let caughtErr = false;
- let oldPathInfo;
-
- try {
- oldPathInfo = Deno.statSync(oldpath);
- } catch (e) {
- caughtErr = true;
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- }
- assert(caughtErr);
- assertEquals(oldPathInfo, undefined);
-});
-
-testPerm({ read: false, write: true }, function renameSyncReadPerm(): void {
- let err;
- try {
- const oldpath = "/oldbaddir";
- const newpath = "/newbaddir";
- Deno.renameSync(oldpath, newpath);
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ read: true, write: false }, function renameSyncWritePerm(): void {
- let err;
- try {
- const oldpath = "/oldbaddir";
- const newpath = "/newbaddir";
- Deno.renameSync(oldpath, newpath);
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ read: true, write: true }, async function renameSuccess(): Promise<
- void
-> {
- const testDir = Deno.makeTempDirSync();
- const oldpath = testDir + "/oldpath";
- const newpath = testDir + "/newpath";
- Deno.mkdirSync(oldpath);
- await Deno.rename(oldpath, newpath);
- const newPathInfo = Deno.statSync(newpath);
- assert(newPathInfo.isDirectory());
-
- let caughtErr = false;
- let oldPathInfo;
-
- try {
- oldPathInfo = Deno.statSync(oldpath);
- } catch (e) {
- caughtErr = true;
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- }
- assert(caughtErr);
- assertEquals(oldPathInfo, undefined);
-});
diff --git a/js/repl.ts b/js/repl.ts
deleted file mode 100644
index 966e809e8..000000000
--- a/js/repl.ts
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { close } from "./files.ts";
-import { exit } from "./os.ts";
-import { window } from "./window.ts";
-import { core } from "./core.ts";
-import { formatError } from "./format_error.ts";
-import { stringifyArgs } from "./console.ts";
-import * as dispatch from "./dispatch.ts";
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-
-const { console } = window;
-
-/**
- * REPL logging.
- * In favor of console.log to avoid unwanted indentation
- */
-function replLog(...args: unknown[]): void {
- core.print(stringifyArgs(args) + "\n");
-}
-
-/**
- * REPL logging for errors.
- * In favor of console.error to avoid unwanted indentation
- */
-function replError(...args: unknown[]): void {
- core.print(stringifyArgs(args) + "\n", true);
-}
-
-const helpMsg = [
- "_ Get last evaluation result",
- "_error Get last thrown error",
- "exit Exit the REPL",
- "help Print this help message"
-].join("\n");
-
-const replCommands = {
- exit: {
- get(): void {
- exit(0);
- }
- },
- help: {
- get(): string {
- return helpMsg;
- }
- }
-};
-
-function startRepl(historyFile: string): number {
- return sendSync(dispatch.OP_REPL_START, { historyFile });
-}
-
-// @internal
-export async function readline(rid: number, prompt: string): Promise<string> {
- return sendAsync(dispatch.OP_REPL_READLINE, { rid, prompt });
-}
-
-// Error messages that allow users to continue input
-// instead of throwing an error to REPL
-// ref: https://github.com/v8/v8/blob/master/src/message-template.h
-// TODO(kevinkassimo): this list might not be comprehensive
-const recoverableErrorMessages = [
- "Unexpected end of input", // { or [ or (
- "Missing initializer in const declaration", // const a
- "Missing catch or finally after try", // try {}
- "missing ) after argument list", // console.log(1
- "Unterminated template literal" // `template
- // TODO(kevinkassimo): need a parser to handling errors such as:
- // "Missing } in template expression" // `${ or `${ a 123 }`
-];
-
-function isRecoverableError(e: Error): boolean {
- return recoverableErrorMessages.includes(e.message);
-}
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-type Value = any;
-
-let lastEvalResult: Value = undefined;
-let lastThrownError: Value = undefined;
-
-// Evaluate code.
-// Returns true if code is consumed (no error/irrecoverable error).
-// Returns false if error is recoverable
-function evaluate(code: string): boolean {
- const [result, errInfo] = core.evalContext(code);
- if (!errInfo) {
- lastEvalResult = result;
- replLog(result);
- } else if (errInfo.isCompileError && isRecoverableError(errInfo.thrown)) {
- // Recoverable compiler error
- return false; // don't consume code.
- } else {
- lastThrownError = errInfo.thrown;
- if (errInfo.isNativeError) {
- const formattedError = formatError(
- core.errorToJSON(errInfo.thrown as Error)
- );
- replError(formattedError);
- } else {
- replError("Thrown:", errInfo.thrown);
- }
- }
- return true;
-}
-
-// @internal
-export async function replLoop(): Promise<void> {
- Object.defineProperties(window, replCommands);
-
- const historyFile = "deno_history.txt";
- const rid = startRepl(historyFile);
-
- const quitRepl = (exitCode: number): void => {
- // Special handling in case user calls deno.close(3).
- try {
- close(rid); // close signals Drop on REPL and saves history.
- } catch {}
- exit(exitCode);
- };
-
- // Configure window._ to give the last evaluation result.
- Object.defineProperty(window, "_", {
- configurable: true,
- get: (): Value => lastEvalResult,
- set: (value: Value): Value => {
- Object.defineProperty(window, "_", {
- value: value,
- writable: true,
- enumerable: true,
- configurable: true
- });
- console.log("Last evaluation result is no longer saved to _.");
- }
- });
-
- // Configure window._error to give the last thrown error.
- Object.defineProperty(window, "_error", {
- configurable: true,
- get: (): Value => lastThrownError,
- set: (value: Value): Value => {
- Object.defineProperty(window, "_error", {
- value: value,
- writable: true,
- enumerable: true,
- configurable: true
- });
- console.log("Last thrown error is no longer saved to _error.");
- }
- });
-
- while (true) {
- let code = "";
- // Top level read
- try {
- code = await readline(rid, "> ");
- if (code.trim() === "") {
- continue;
- }
- } catch (err) {
- if (err.message === "EOF") {
- quitRepl(0);
- } else {
- // If interrupted, don't print error.
- if (err.message !== "Interrupted") {
- // e.g. this happens when we have deno.close(3).
- // We want to display the problem.
- const formattedError = formatError(core.errorToJSON(err));
- replError(formattedError);
- }
- // Quit REPL anyways.
- quitRepl(1);
- }
- }
- // Start continued read
- while (!evaluate(code)) {
- code += "\n";
- try {
- code += await readline(rid, " ");
- } catch (err) {
- // If interrupted on continued read,
- // abort this read instead of quitting.
- if (err.message === "Interrupted") {
- break;
- } else if (err.message === "EOF") {
- quitRepl(0);
- } else {
- // e.g. this happens when we have deno.close(3).
- // We want to display the problem.
- const formattedError = formatError(core.errorToJSON(err));
- replError(formattedError);
- quitRepl(1);
- }
- }
- }
- }
-}
diff --git a/js/request.ts b/js/request.ts
deleted file mode 100644
index 0c77b8854..000000000
--- a/js/request.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as headers from "./headers.ts";
-import * as body from "./body.ts";
-import * as domTypes from "./dom_types.ts";
-
-const { Headers } = headers;
-
-function byteUpperCase(s: string): string {
- return String(s).replace(/[a-z]/g, function byteUpperCaseReplace(c): string {
- return c.toUpperCase();
- });
-}
-
-function normalizeMethod(m: string): string {
- const u = byteUpperCase(m);
- if (
- u === "DELETE" ||
- u === "GET" ||
- u === "HEAD" ||
- u === "OPTIONS" ||
- u === "POST" ||
- u === "PUT"
- ) {
- return u;
- }
- return m;
-}
-
-/**
- * An HTTP request
- * @param {Blob|String} [body]
- * @param {Object} [init]
- */
-export class Request extends body.Body implements domTypes.Request {
- public method: string;
- public url: string;
- public credentials?: "omit" | "same-origin" | "include";
- public headers: domTypes.Headers;
-
- constructor(input: domTypes.RequestInfo, init?: domTypes.RequestInit) {
- if (arguments.length < 1) {
- throw TypeError("Not enough arguments");
- }
-
- if (!init) {
- init = {};
- }
-
- let b: body.BodySource;
-
- // prefer body from init
- if (init.body) {
- b = init.body;
- } else if (input instanceof Request && input._bodySource) {
- if (input.bodyUsed) {
- throw TypeError(body.BodyUsedError);
- }
- b = input._bodySource;
- } else if (typeof input === "object" && "body" in input && input.body) {
- if (input.bodyUsed) {
- throw TypeError(body.BodyUsedError);
- }
- b = input.body;
- } else {
- b = "";
- }
-
- let headers: domTypes.Headers;
-
- // prefer headers from init
- if (init.headers) {
- headers = new Headers(init.headers);
- } else if (input instanceof Request) {
- headers = input.headers;
- } else {
- headers = new Headers();
- }
-
- const contentType = headers.get("content-type") || "";
- super(b, contentType);
- this.headers = headers;
-
- // readonly attribute ByteString method;
- /**
- * The HTTP request method
- * @readonly
- * @default GET
- * @type {string}
- */
- this.method = "GET";
-
- // readonly attribute USVString url;
- /**
- * The request URL
- * @readonly
- * @type {string}
- */
- this.url = "";
-
- // readonly attribute RequestCredentials credentials;
- this.credentials = "omit";
-
- if (input instanceof Request) {
- if (input.bodyUsed) {
- throw TypeError(body.BodyUsedError);
- }
- this.method = input.method;
- this.url = input.url;
- this.headers = new Headers(input.headers);
- this.credentials = input.credentials;
- this._stream = input._stream;
- } else if (typeof input === "string") {
- this.url = input;
- }
-
- if (init && "method" in init) {
- this.method = normalizeMethod(init.method as string);
- }
-
- if (
- init &&
- "credentials" in init &&
- init.credentials &&
- ["omit", "same-origin", "include"].indexOf(init.credentials) !== -1
- ) {
- this.credentials = init.credentials;
- }
- }
-
- public clone(): domTypes.Request {
- if (this.bodyUsed) {
- throw TypeError(body.BodyUsedError);
- }
-
- const iterators = this.headers.entries();
- const headersList: Array<[string, string]> = [];
- for (const header of iterators) {
- headersList.push(header);
- }
-
- const body2 = this._bodySource;
-
- const cloned = new Request(this.url, {
- body: body2,
- method: this.method,
- headers: new Headers(headersList),
- credentials: this.credentials
- });
- return cloned;
- }
-}
diff --git a/js/request_test.ts b/js/request_test.ts
deleted file mode 100644
index e9e1f5164..000000000
--- a/js/request_test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assertEquals } from "./test_util.ts";
-
-test(function fromInit(): void {
- const req = new Request("https://example.com", {
- body: "ahoyhoy",
- method: "POST",
- headers: {
- "test-header": "value"
- }
- });
-
- // @ts-ignore
- assertEquals("ahoyhoy", req._bodySource);
- assertEquals(req.url, "https://example.com");
- assertEquals(req.headers.get("test-header"), "value");
-});
diff --git a/js/resources.ts b/js/resources.ts
deleted file mode 100644
index 27598ce09..000000000
--- a/js/resources.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as dispatch from "./dispatch.ts";
-import { sendSync } from "./dispatch_json.ts";
-
-export interface ResourceMap {
- [rid: number]: string;
-}
-
-/** Returns a map of open _file like_ resource ids along with their string
- * representation.
- */
-export function resources(): ResourceMap {
- const res = sendSync(dispatch.OP_RESOURCES) as Array<[number, string]>;
- const resources: ResourceMap = {};
- for (const resourceTuple of res) {
- resources[resourceTuple[0]] = resourceTuple[1];
- }
- return resources;
-}
diff --git a/js/resources_test.ts b/js/resources_test.ts
deleted file mode 100644
index 753ef3e17..000000000
--- a/js/resources_test.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, testPerm, assertEquals } from "./test_util.ts";
-
-test(function resourcesStdio(): void {
- const res = Deno.resources();
-
- assertEquals(res[0], "stdin");
- assertEquals(res[1], "stdout");
- assertEquals(res[2], "stderr");
-});
-
-testPerm({ net: true }, async function resourcesNet(): Promise<void> {
- const listener = Deno.listen({ port: 4501 });
- const dialerConn = await Deno.dial({ port: 4501 });
- const listenerConn = await listener.accept();
-
- const res = Deno.resources();
- assertEquals(
- Object.values(res).filter((r): boolean => r === "tcpListener").length,
- 1
- );
- assertEquals(
- Object.values(res).filter((r): boolean => r === "tcpStream").length,
- 2
- );
-
- listenerConn.close();
- dialerConn.close();
- listener.close();
-});
-
-testPerm({ read: true }, async function resourcesFile(): Promise<void> {
- const resourcesBefore = Deno.resources();
- await Deno.open("tests/hello.txt");
- const resourcesAfter = Deno.resources();
-
- // check that exactly one new resource (file) was added
- assertEquals(
- Object.keys(resourcesAfter).length,
- Object.keys(resourcesBefore).length + 1
- );
- const newRid = Object.keys(resourcesAfter).find(
- (rid): boolean => {
- return !resourcesBefore.hasOwnProperty(rid);
- }
- );
- assertEquals(resourcesAfter[newRid], "fsFile");
-});
diff --git a/js/stat.ts b/js/stat.ts
deleted file mode 100644
index 1f53e6f7b..000000000
--- a/js/stat.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.ts";
-import { FileInfo, FileInfoImpl } from "./file_info.ts";
-
-export interface StatResponse {
- isFile: boolean;
- isSymlink: boolean;
- len: number;
- modified: number;
- accessed: number;
- created: number;
- mode: number;
- hasMode: boolean; // false on windows
- 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 async function lstat(filename: string): Promise<FileInfo> {
- const res = (await sendAsync(dispatch.OP_STAT, {
- filename,
- lstat: true
- })) as StatResponse;
- return new FileInfoImpl(res);
-}
-
-/** 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 {
- const res = sendSync(dispatch.OP_STAT, {
- filename,
- lstat: true
- }) as StatResponse;
- return new FileInfoImpl(res);
-}
-
-/** 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 async function stat(filename: string): Promise<FileInfo> {
- const res = (await sendAsync(dispatch.OP_STAT, {
- filename,
- lstat: false
- })) as StatResponse;
- return new FileInfoImpl(res);
-}
-
-/** 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 {
- const res = sendSync(dispatch.OP_STAT, {
- filename,
- lstat: false
- }) as StatResponse;
- return new FileInfoImpl(res);
-}
diff --git a/js/stat_test.ts b/js/stat_test.ts
deleted file mode 100644
index 1542f1080..000000000
--- a/js/stat_test.ts
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-// TODO Add tests for modified, accessed, and created fields once there is a way
-// to create temp files.
-testPerm({ read: true }, async function statSyncSuccess(): Promise<void> {
- const packageInfo = Deno.statSync("package.json");
- assert(packageInfo.isFile());
- assert(!packageInfo.isSymlink());
-
- const modulesInfo = Deno.statSync("node_modules");
- assert(modulesInfo.isDirectory());
- assert(!modulesInfo.isSymlink());
-
- const testsInfo = Deno.statSync("tests");
- assert(testsInfo.isDirectory());
- assert(!testsInfo.isSymlink());
-});
-
-testPerm({ read: false }, async function statSyncPerm(): Promise<void> {
- let caughtError = false;
- try {
- Deno.statSync("package.json");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true }, async function statSyncNotFound(): Promise<void> {
- let caughtError = false;
- let badInfo;
-
- try {
- badInfo = Deno.statSync("bad_file_name");
- } catch (err) {
- caughtError = true;
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
- }
-
- assert(caughtError);
- assertEquals(badInfo, undefined);
-});
-
-testPerm({ read: true }, async function lstatSyncSuccess(): Promise<void> {
- const packageInfo = Deno.lstatSync("package.json");
- assert(packageInfo.isFile());
- assert(!packageInfo.isSymlink());
-
- const modulesInfo = Deno.lstatSync("node_modules");
- assert(!modulesInfo.isDirectory());
- assert(modulesInfo.isSymlink());
-
- const i = Deno.lstatSync("website");
- assert(i.isDirectory());
- assert(!i.isSymlink());
-});
-
-testPerm({ read: false }, async function lstatSyncPerm(): Promise<void> {
- let caughtError = false;
- try {
- Deno.lstatSync("package.json");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true }, async function lstatSyncNotFound(): Promise<void> {
- let caughtError = false;
- let badInfo;
-
- try {
- badInfo = Deno.lstatSync("bad_file_name");
- } catch (err) {
- caughtError = true;
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
- }
-
- assert(caughtError);
- assertEquals(badInfo, undefined);
-});
-
-testPerm({ read: true }, async function statSuccess(): Promise<void> {
- const packageInfo = await Deno.stat("package.json");
- assert(packageInfo.isFile());
- assert(!packageInfo.isSymlink());
-
- const modulesInfo = await Deno.stat("node_modules");
- assert(modulesInfo.isDirectory());
- assert(!modulesInfo.isSymlink());
-
- const i = await Deno.stat("tests");
- assert(i.isDirectory());
- assert(!i.isSymlink());
-});
-
-testPerm({ read: false }, async function statPerm(): Promise<void> {
- let caughtError = false;
- try {
- await Deno.stat("package.json");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true }, async function statNotFound(): Promise<void> {
- let caughtError = false;
- let badInfo;
-
- try {
- badInfo = await Deno.stat("bad_file_name");
- } catch (err) {
- caughtError = true;
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
- }
-
- assert(caughtError);
- assertEquals(badInfo, undefined);
-});
-
-testPerm({ read: true }, async function lstatSuccess(): Promise<void> {
- const packageInfo = await Deno.lstat("package.json");
- assert(packageInfo.isFile());
- assert(!packageInfo.isSymlink());
-
- const modulesInfo = await Deno.lstat("node_modules");
- assert(!modulesInfo.isDirectory());
- assert(modulesInfo.isSymlink());
-
- const i = await Deno.lstat("website");
- assert(i.isDirectory());
- assert(!i.isSymlink());
-});
-
-testPerm({ read: false }, async function lstatPerm(): Promise<void> {
- let caughtError = false;
- try {
- await Deno.lstat("package.json");
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true }, async function lstatNotFound(): Promise<void> {
- let caughtError = false;
- let badInfo;
-
- try {
- badInfo = await Deno.lstat("bad_file_name");
- } catch (err) {
- caughtError = true;
- assertEquals(err.kind, Deno.ErrorKind.NotFound);
- assertEquals(err.name, "NotFound");
- }
-
- assert(caughtError);
- assertEquals(badInfo, undefined);
-});
diff --git a/js/symlink.ts b/js/symlink.ts
deleted file mode 100644
index 21ebb2f59..000000000
--- a/js/symlink.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.ts";
-import * as util from "./util.ts";
-import { build } from "./build.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 {
- if (build.os === "win" && type) {
- return util.notImplemented();
- }
- sendSync(dispatch.OP_SYMLINK, { oldname, newname });
-}
-
-/** 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 async function symlink(
- oldname: string,
- newname: string,
- type?: string
-): Promise<void> {
- if (build.os === "win" && type) {
- return util.notImplemented();
- }
- await sendAsync(dispatch.OP_SYMLINK, { oldname, newname });
-}
diff --git a/js/symlink_test.ts b/js/symlink_test.ts
deleted file mode 100644
index bce1f6ae5..000000000
--- a/js/symlink_test.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, testPerm, assert, assertEquals } from "./test_util.ts";
-
-testPerm({ read: true, write: true }, function symlinkSyncSuccess(): void {
- const testDir = Deno.makeTempDirSync();
- const oldname = testDir + "/oldname";
- const newname = testDir + "/newname";
- Deno.mkdirSync(oldname);
- let errOnWindows;
- // Just for now, until we implement symlink for Windows.
- try {
- Deno.symlinkSync(oldname, newname);
- } catch (e) {
- errOnWindows = e;
- }
- if (errOnWindows) {
- assertEquals(Deno.build.os, "win");
- assertEquals(errOnWindows.kind, Deno.ErrorKind.Other);
- assertEquals(errOnWindows.message, "Not implemented");
- } else {
- const newNameInfoLStat = Deno.lstatSync(newname);
- const newNameInfoStat = Deno.statSync(newname);
- assert(newNameInfoLStat.isSymlink());
- assert(newNameInfoStat.isDirectory());
- }
-});
-
-test(function symlinkSyncPerm(): void {
- let err;
- try {
- Deno.symlinkSync("oldbaddir", "newbaddir");
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-// Just for now, until we implement symlink for Windows.
-// Symlink with type should succeed on other platforms with type ignored
-testPerm({ write: true }, function symlinkSyncNotImplemented(): void {
- const testDir = Deno.makeTempDirSync();
- const oldname = testDir + "/oldname";
- const newname = testDir + "/newname";
- let err;
- try {
- Deno.symlinkSync(oldname, newname, "dir");
- } catch (e) {
- err = e;
- }
- if (err) {
- assertEquals(Deno.build.os, "win");
- assertEquals(err.message, "Not implemented");
- }
-});
-
-testPerm({ read: true, write: true }, async function symlinkSuccess(): Promise<
- void
-> {
- const testDir = Deno.makeTempDirSync();
- const oldname = testDir + "/oldname";
- const newname = testDir + "/newname";
- Deno.mkdirSync(oldname);
- let errOnWindows;
- // Just for now, until we implement symlink for Windows.
- try {
- await Deno.symlink(oldname, newname);
- } catch (e) {
- errOnWindows = e;
- }
- if (errOnWindows) {
- assertEquals(errOnWindows.kind, Deno.ErrorKind.Other);
- assertEquals(errOnWindows.message, "Not implemented");
- } else {
- const newNameInfoLStat = Deno.lstatSync(newname);
- const newNameInfoStat = Deno.statSync(newname);
- assert(newNameInfoLStat.isSymlink());
- assert(newNameInfoStat.isDirectory());
- }
-});
diff --git a/js/test_util.ts b/js/test_util.ts
deleted file mode 100644
index bb75082e6..000000000
--- a/js/test_util.ts
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-//
-// We want to test many ops in deno which have different behavior depending on
-// the permissions set. These tests can specify which permissions they expect,
-// which appends a special string like "permW1N0" to the end of the test name.
-// Here we run several copies of deno with different permissions, filtering the
-// tests by the special string. permW1N0 means allow-write but not allow-net.
-// See tools/unit_tests.py for more details.
-
-import * as testing from "../std/testing/mod.ts";
-import { assert, assertEquals } from "../std/testing/asserts.ts";
-export {
- assert,
- assertThrows,
- assertEquals,
- assertMatch,
- assertNotEquals,
- assertStrictEq,
- assertStrContains,
- unreachable
-} from "../std/testing/asserts.ts";
-
-interface TestPermissions {
- read?: boolean;
- write?: boolean;
- net?: boolean;
- env?: boolean;
- run?: boolean;
- hrtime?: boolean;
-}
-
-const processPerms = Deno.permissions();
-
-function permissionsMatch(
- processPerms: Deno.Permissions,
- requiredPerms: Deno.Permissions
-): boolean {
- for (const permName in processPerms) {
- if (processPerms[permName] !== requiredPerms[permName]) {
- return false;
- }
- }
-
- return true;
-}
-
-export const permissionCombinations: Map<string, Deno.Permissions> = new Map();
-
-function permToString(perms: Deno.Permissions): string {
- const r = perms.read ? 1 : 0;
- const w = perms.write ? 1 : 0;
- const n = perms.net ? 1 : 0;
- const e = perms.env ? 1 : 0;
- const u = perms.run ? 1 : 0;
- const h = perms.hrtime ? 1 : 0;
- return `permR${r}W${w}N${n}E${e}U${u}H${h}`;
-}
-
-function registerPermCombination(perms: Deno.Permissions): void {
- const key = permToString(perms);
- if (!permissionCombinations.has(key)) {
- permissionCombinations.set(key, perms);
- }
-}
-
-function normalizeTestPermissions(perms: TestPermissions): Deno.Permissions {
- return {
- read: !!perms.read,
- write: !!perms.write,
- net: !!perms.net,
- run: !!perms.run,
- env: !!perms.env,
- hrtime: !!perms.hrtime
- };
-}
-
-export function testPerm(
- perms: TestPermissions,
- fn: testing.TestFunction
-): void {
- const normalizedPerms = normalizeTestPermissions(perms);
-
- registerPermCombination(normalizedPerms);
-
- if (!permissionsMatch(processPerms, normalizedPerms)) {
- return;
- }
-
- testing.test(fn);
-}
-
-export function test(fn: testing.TestFunction): void {
- testPerm(
- {
- read: false,
- write: false,
- net: false,
- env: false,
- run: false,
- hrtime: false
- },
- fn
- );
-}
-
-function extractNumber(re: RegExp, str: string): number | undefined {
- const match = str.match(re);
-
- if (match) {
- return Number.parseInt(match[1]);
- }
-}
-
-export function parseUnitTestOutput(
- rawOutput: Uint8Array,
- print: boolean
-): { actual?: number; expected?: number; resultOutput?: string } {
- const decoder = new TextDecoder();
- const output = decoder.decode(rawOutput);
-
- let expected, actual, result;
-
- for (const line of output.split("\n")) {
- if (!expected) {
- // expect "running 30 tests"
- expected = extractNumber(/running (\d+) tests/, line);
- } else if (line.indexOf("test result:") !== -1) {
- result = line;
- }
-
- if (print) {
- console.log(line);
- }
- }
-
- // Check that the number of expected tests equals what was reported at the
- // bottom.
- if (result) {
- // result should be a string like this:
- // "test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; ..."
- actual = extractNumber(/(\d+) passed/, result);
- }
-
- return { actual, expected, resultOutput: result };
-}
-
-test(function permissionsMatches(): void {
- assert(
- permissionsMatch(
- {
- read: true,
- write: false,
- net: false,
- env: false,
- run: false,
- hrtime: false
- },
- normalizeTestPermissions({ read: true })
- )
- );
-
- assert(
- permissionsMatch(
- {
- read: false,
- write: false,
- net: false,
- env: false,
- run: false,
- hrtime: false
- },
- normalizeTestPermissions({})
- )
- );
-
- assertEquals(
- permissionsMatch(
- {
- read: false,
- write: true,
- net: true,
- env: true,
- run: true,
- hrtime: true
- },
- normalizeTestPermissions({ read: true })
- ),
- false
- );
-
- assertEquals(
- permissionsMatch(
- {
- read: true,
- write: false,
- net: true,
- env: false,
- run: false,
- hrtime: false
- },
- normalizeTestPermissions({ read: true })
- ),
- false
- );
-
- assert(
- permissionsMatch(
- {
- read: true,
- write: true,
- net: true,
- env: true,
- run: true,
- hrtime: true
- },
- {
- read: true,
- write: true,
- net: true,
- env: true,
- run: true,
- hrtime: true
- }
- )
- );
-});
-
-testPerm({ read: true }, async function parsingUnitTestOutput(): Promise<void> {
- const cwd = Deno.cwd();
- const testDataPath = `${cwd}/tools/testdata/`;
-
- let result;
-
- // This is an example of a successful unit test output.
- result = parseUnitTestOutput(
- await Deno.readFile(`${testDataPath}/unit_test_output1.txt`),
- false
- );
- assertEquals(result.actual, 96);
- assertEquals(result.expected, 96);
-
- // This is an example of a silently dying unit test.
- result = parseUnitTestOutput(
- await Deno.readFile(`${testDataPath}/unit_test_output2.txt`),
- false
- );
- assertEquals(result.actual, undefined);
- assertEquals(result.expected, 96);
-
- // This is an example of compiling before successful unit tests.
- result = parseUnitTestOutput(
- await Deno.readFile(`${testDataPath}/unit_test_output3.txt`),
- false
- );
- assertEquals(result.actual, 96);
- assertEquals(result.expected, 96);
-
- // Check what happens on empty output.
- result = parseUnitTestOutput(new TextEncoder().encode("\n\n\n"), false);
- assertEquals(result.actual, undefined);
- assertEquals(result.expected, undefined);
-});
diff --git a/js/text_encoding.ts b/js/text_encoding.ts
deleted file mode 100644
index 8386ff8b0..000000000
--- a/js/text_encoding.ts
+++ /dev/null
@@ -1,554 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-// The following code is based off of text-encoding at:
-// https://github.com/inexorabletash/text-encoding
-//
-// Anyone is free to copy, modify, publish, use, compile, sell, or
-// distribute this software, either in source code form or as a compiled
-// binary, for any purpose, commercial or non-commercial, and by any
-// means.
-//
-// In jurisdictions that recognize copyright laws, the author or authors
-// of this software dedicate any and all copyright interest in the
-// software to the public domain. We make this dedication for the benefit
-// of the public at large and to the detriment of our heirs and
-// successors. We intend this dedication to be an overt act of
-// relinquishment in perpetuity of all present and future rights to this
-// software under copyright law.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-// OTHER DEALINGS IN THE SOFTWARE.
-
-import * as base64 from "./base64.ts";
-import * as domTypes from "./dom_types.ts";
-import { DenoError, ErrorKind } from "./errors.ts";
-
-const CONTINUE = null;
-const END_OF_STREAM = -1;
-const FINISHED = -1;
-
-function decoderError(fatal: boolean): number | never {
- if (fatal) {
- throw new TypeError("Decoder error.");
- }
- return 0xfffd; // default code point
-}
-
-function inRange(a: number, min: number, max: number): boolean {
- return min <= a && a <= max;
-}
-
-function isASCIIByte(a: number): boolean {
- return inRange(a, 0x00, 0x7f);
-}
-
-function stringToCodePoints(input: string): number[] {
- const u: number[] = [];
- for (const c of input) {
- u.push(c.codePointAt(0)!);
- }
- return u;
-}
-
-class UTF8Decoder implements Decoder {
- private _codePoint = 0;
- private _bytesSeen = 0;
- private _bytesNeeded = 0;
- private _fatal: boolean;
- private _ignoreBOM: boolean;
- private _lowerBoundary = 0x80;
- private _upperBoundary = 0xbf;
-
- constructor(options: DecoderOptions) {
- this._fatal = options.fatal || false;
- this._ignoreBOM = options.ignoreBOM || false;
- }
-
- handler(stream: Stream, byte: number): number | null {
- if (byte === END_OF_STREAM && this._bytesNeeded !== 0) {
- this._bytesNeeded = 0;
- return decoderError(this._fatal);
- }
-
- if (byte === END_OF_STREAM) {
- return FINISHED;
- }
-
- if (this._ignoreBOM) {
- if (
- (this._bytesSeen === 0 && byte !== 0xef) ||
- (this._bytesSeen === 1 && byte !== 0xbb)
- ) {
- this._ignoreBOM = false;
- }
-
- if (this._bytesSeen === 2) {
- this._ignoreBOM = false;
- if (byte === 0xbf) {
- //Ignore BOM
- this._codePoint = 0;
- this._bytesNeeded = 0;
- this._bytesSeen = 0;
- return CONTINUE;
- }
- }
- }
-
- if (this._bytesNeeded === 0) {
- if (isASCIIByte(byte)) {
- // Single byte code point
- return byte;
- } else if (inRange(byte, 0xc2, 0xdf)) {
- // Two byte code point
- this._bytesNeeded = 1;
- this._codePoint = byte & 0x1f;
- } else if (inRange(byte, 0xe0, 0xef)) {
- // Three byte code point
- if (byte === 0xe0) {
- this._lowerBoundary = 0xa0;
- } else if (byte === 0xed) {
- this._upperBoundary = 0x9f;
- }
- this._bytesNeeded = 2;
- this._codePoint = byte & 0xf;
- } else if (inRange(byte, 0xf0, 0xf4)) {
- if (byte === 0xf0) {
- this._lowerBoundary = 0x90;
- } else if (byte === 0xf4) {
- this._upperBoundary = 0x8f;
- }
- this._bytesNeeded = 3;
- this._codePoint = byte & 0x7;
- } else {
- return decoderError(this._fatal);
- }
- return CONTINUE;
- }
-
- if (!inRange(byte, this._lowerBoundary, this._upperBoundary)) {
- // Byte out of range, so encoding error
- this._codePoint = 0;
- this._bytesNeeded = 0;
- this._bytesSeen = 0;
- stream.prepend(byte);
- return decoderError(this._fatal);
- }
-
- this._lowerBoundary = 0x80;
- this._upperBoundary = 0xbf;
-
- this._codePoint = (this._codePoint << 6) | (byte & 0x3f);
-
- this._bytesSeen++;
-
- if (this._bytesSeen !== this._bytesNeeded) {
- return CONTINUE;
- }
-
- const codePoint = this._codePoint;
-
- this._codePoint = 0;
- this._bytesNeeded = 0;
- this._bytesSeen = 0;
-
- return codePoint;
- }
-}
-
-class UTF8Encoder implements Encoder {
- handler(codePoint: number): number | number[] {
- if (codePoint === END_OF_STREAM) {
- return FINISHED;
- }
-
- if (inRange(codePoint, 0x00, 0x7f)) {
- return codePoint;
- }
-
- let count: number;
- let offset: number;
- if (inRange(codePoint, 0x0080, 0x07ff)) {
- count = 1;
- offset = 0xc0;
- } else if (inRange(codePoint, 0x0800, 0xffff)) {
- count = 2;
- offset = 0xe0;
- } else if (inRange(codePoint, 0x10000, 0x10ffff)) {
- count = 3;
- offset = 0xf0;
- } else {
- throw TypeError(`Code point out of range: \\x${codePoint.toString(16)}`);
- }
-
- const bytes = [(codePoint >> (6 * count)) + offset];
-
- while (count > 0) {
- const temp = codePoint >> (6 * (count - 1));
- bytes.push(0x80 | (temp & 0x3f));
- count--;
- }
-
- return bytes;
- }
-}
-
-/** Decodes a string of data which has been encoded using base-64. */
-export function atob(s: string): string {
- s = String(s);
- s = s.replace(/[\t\n\f\r ]/g, "");
-
- if (s.length % 4 === 0) {
- s = s.replace(/==?$/, "");
- }
-
- const rem = s.length % 4;
- if (rem === 1 || /[^+/0-9A-Za-z]/.test(s)) {
- // TODO: throw `DOMException`
- throw new DenoError(
- ErrorKind.InvalidInput,
- "The string to be decoded is not correctly encoded"
- );
- }
-
- // base64-js requires length exactly times of 4
- if (rem > 0) {
- s = s.padEnd(s.length + (4 - rem), "=");
- }
-
- const byteArray: Uint8Array = base64.toByteArray(s);
- let result = "";
- for (let i = 0; i < byteArray.length; i++) {
- result += String.fromCharCode(byteArray[i]);
- }
- return result;
-}
-
-/** Creates a base-64 ASCII string from the input string. */
-export function btoa(s: string): string {
- const byteArray = [];
- for (let i = 0; i < s.length; i++) {
- const charCode = s[i].charCodeAt(0);
- if (charCode > 0xff) {
- throw new DenoError(
- ErrorKind.InvalidInput,
- "The string to be encoded contains characters " +
- "outside of the Latin1 range."
- );
- }
- byteArray.push(charCode);
- }
- const result = base64.fromByteArray(Uint8Array.from(byteArray));
- return result;
-}
-
-interface DecoderOptions {
- fatal?: boolean;
- ignoreBOM?: boolean;
-}
-
-interface Decoder {
- handler(stream: Stream, byte: number): number | null;
-}
-
-interface Encoder {
- handler(codePoint: number): number | number[];
-}
-
-class SingleByteDecoder implements Decoder {
- private _index: number[];
- private _fatal: boolean;
-
- constructor(index: number[], options: DecoderOptions) {
- if (options.ignoreBOM) {
- throw new TypeError("Ignoring the BOM is available only with utf-8.");
- }
- this._fatal = options.fatal || false;
- this._index = index;
- }
- handler(stream: Stream, byte: number): number {
- if (byte === END_OF_STREAM) {
- return FINISHED;
- }
- if (isASCIIByte(byte)) {
- return byte;
- }
- const codePoint = this._index[byte - 0x80];
-
- if (codePoint == null) {
- return decoderError(this._fatal);
- }
-
- return codePoint;
- }
-}
-
-// The encodingMap is a hash of labels that are indexed by the conical
-// encoding.
-const encodingMap: { [key: string]: string[] } = {
- "windows-1252": [
- "ansi_x3.4-1968",
- "ascii",
- "cp1252",
- "cp819",
- "csisolatin1",
- "ibm819",
- "iso-8859-1",
- "iso-ir-100",
- "iso8859-1",
- "iso88591",
- "iso_8859-1",
- "iso_8859-1:1987",
- "l1",
- "latin1",
- "us-ascii",
- "windows-1252",
- "x-cp1252"
- ],
- "utf-8": ["unicode-1-1-utf-8", "utf-8", "utf8"]
-};
-// We convert these into a Map where every label resolves to its canonical
-// encoding type.
-const encodings = new Map<string, string>();
-for (const key of Object.keys(encodingMap)) {
- const labels = encodingMap[key];
- for (const label of labels) {
- encodings.set(label, key);
- }
-}
-
-// A map of functions that return new instances of a decoder indexed by the
-// encoding type.
-const decoders = new Map<string, (options: DecoderOptions) => Decoder>();
-decoders.set(
- "utf-8",
- (options: DecoderOptions): UTF8Decoder => {
- return new UTF8Decoder(options);
- }
-);
-
-// Single byte decoders are an array of code point lookups
-const encodingIndexes = new Map<string, number[]>();
-// prettier-ignore
-encodingIndexes.set("windows-1252", [8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255]);
-for (const [key, index] of encodingIndexes) {
- decoders.set(
- key,
- (options: DecoderOptions): SingleByteDecoder => {
- return new SingleByteDecoder(index, options);
- }
- );
-}
-
-function codePointsToString(codePoints: number[]): string {
- let s = "";
- for (const cp of codePoints) {
- s += String.fromCodePoint(cp);
- }
- return s;
-}
-
-class Stream {
- private _tokens: number[];
- constructor(tokens: number[] | Uint8Array) {
- this._tokens = [].slice.call(tokens);
- this._tokens.reverse();
- }
-
- endOfStream(): boolean {
- return !this._tokens.length;
- }
-
- read(): number {
- return !this._tokens.length ? END_OF_STREAM : this._tokens.pop()!;
- }
-
- prepend(token: number | number[]): void {
- if (Array.isArray(token)) {
- while (token.length) {
- this._tokens.push(token.pop()!);
- }
- } else {
- this._tokens.push(token);
- }
- }
-
- push(token: number | number[]): void {
- if (Array.isArray(token)) {
- while (token.length) {
- this._tokens.unshift(token.shift()!);
- }
- } else {
- this._tokens.unshift(token);
- }
- }
-}
-
-export interface TextDecodeOptions {
- stream?: false;
-}
-
-export interface TextDecoderOptions {
- fatal?: boolean;
- ignoreBOM?: boolean;
-}
-
-type EitherArrayBuffer = SharedArrayBuffer | ArrayBuffer;
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-function isEitherArrayBuffer(x: any): x is EitherArrayBuffer {
- return x instanceof SharedArrayBuffer || x instanceof ArrayBuffer;
-}
-
-export class TextDecoder {
- private _encoding: string;
-
- /** Returns encoding's name, lowercased. */
- get encoding(): string {
- return this._encoding;
- }
- /** Returns `true` if error mode is "fatal", and `false` otherwise. */
- readonly fatal: boolean = false;
- /** Returns `true` if ignore BOM flag is set, and `false` otherwise. */
- readonly ignoreBOM: boolean = false;
-
- constructor(label = "utf-8", options: TextDecoderOptions = { fatal: false }) {
- if (options.ignoreBOM) {
- this.ignoreBOM = true;
- }
- if (options.fatal) {
- this.fatal = true;
- }
- label = String(label)
- .trim()
- .toLowerCase();
- const encoding = encodings.get(label);
- if (!encoding) {
- throw new RangeError(
- `The encoding label provided ('${label}') is invalid.`
- );
- }
- if (!decoders.has(encoding)) {
- throw new TypeError(`Internal decoder ('${encoding}') not found.`);
- }
- this._encoding = encoding;
- }
-
- /** Returns the result of running encoding's decoder. */
- decode(
- input?: domTypes.BufferSource,
- options: TextDecodeOptions = { stream: false }
- ): string {
- if (options.stream) {
- throw new TypeError("Stream not supported.");
- }
-
- let bytes: Uint8Array;
- if (input instanceof Uint8Array) {
- bytes = input;
- } else if (isEitherArrayBuffer(input)) {
- bytes = new Uint8Array(input);
- } else if (
- typeof input === "object" &&
- "buffer" in input &&
- isEitherArrayBuffer(input.buffer)
- ) {
- bytes = new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
- } else {
- bytes = new Uint8Array(0);
- }
-
- const decoder = decoders.get(this._encoding)!({
- fatal: this.fatal,
- ignoreBOM: this.ignoreBOM
- });
- const inputStream = new Stream(bytes);
- const output: number[] = [];
-
- while (true) {
- const result = decoder.handler(inputStream, inputStream.read());
- if (result === FINISHED) {
- break;
- }
-
- if (result !== CONTINUE) {
- output.push(result);
- }
- }
-
- if (output.length > 0 && output[0] === 0xfeff) {
- output.shift();
- }
-
- return codePointsToString(output);
- }
- get [Symbol.toStringTag](): string {
- return "TextDecoder";
- }
-}
-
-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 = ""): Uint8Array {
- const encoder = new UTF8Encoder();
- const inputStream = new Stream(stringToCodePoints(input));
- const output: number[] = [];
-
- while (true) {
- const result = encoder.handler(inputStream.read());
- if (result === FINISHED) {
- break;
- }
- if (Array.isArray(result)) {
- output.push(...result);
- } else {
- output.push(result);
- }
- }
-
- return new Uint8Array(output);
- }
- encodeInto(input: string, dest: Uint8Array): TextEncoderEncodeIntoResult {
- const encoder = new UTF8Encoder();
- const inputStream = new Stream(stringToCodePoints(input));
-
- let written = 0;
- let read = 0;
- while (true) {
- const result = encoder.handler(inputStream.read());
- if (result === FINISHED) {
- break;
- }
- read++;
- if (Array.isArray(result)) {
- dest.set(result, written);
- written += result.length;
- if (result.length > 3) {
- // increment read a second time if greater than U+FFFF
- read++;
- }
- } else {
- dest[written] = result;
- written++;
- }
- }
-
- return {
- read,
- written
- };
- }
- get [Symbol.toStringTag](): string {
- return "TextEncoder";
- }
-}
diff --git a/js/text_encoding_test.ts b/js/text_encoding_test.ts
deleted file mode 100644
index aaa9e6b9d..000000000
--- a/js/text_encoding_test.ts
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert, assertEquals } from "./test_util.ts";
-
-test(function btoaSuccess(): void {
- const text = "hello world";
- const encoded = btoa(text);
- assertEquals(encoded, "aGVsbG8gd29ybGQ=");
-});
-
-test(function atobSuccess(): void {
- const encoded = "aGVsbG8gd29ybGQ=";
- const decoded = atob(encoded);
- assertEquals(decoded, "hello world");
-});
-
-test(function atobWithAsciiWhitespace(): void {
- const encodedList = [
- " aGVsbG8gd29ybGQ=",
- " aGVsbG8gd29ybGQ=",
- "aGVsbG8gd29ybGQ= ",
- "aGVsbG8gd29ybGQ=\n",
- "aGVsbG\t8gd29ybGQ=",
- `aGVsbG\t8g
- d29ybGQ=`
- ];
-
- for (const encoded of encodedList) {
- const decoded = atob(encoded);
- assertEquals(decoded, "hello world");
- }
-});
-
-test(function atobThrows(): void {
- let threw = false;
- try {
- atob("aGVsbG8gd29ybGQ==");
- } catch (e) {
- threw = true;
- }
- assert(threw);
-});
-
-test(function atobThrows2(): void {
- let threw = false;
- try {
- atob("aGVsbG8gd29ybGQ===");
- } catch (e) {
- threw = true;
- }
- assert(threw);
-});
-
-test(function btoaFailed(): void {
- const text = "你好";
- let err;
- try {
- btoa(text);
- } catch (e) {
- err = e;
- }
- assert(!!err);
- assertEquals(err.name, "InvalidInput");
-});
-
-test(function textDecoder2(): void {
- // prettier-ignore
- const fixture = new Uint8Array([
- 0xf0, 0x9d, 0x93, 0xbd,
- 0xf0, 0x9d, 0x93, 0xae,
- 0xf0, 0x9d, 0x94, 0x81,
- 0xf0, 0x9d, 0x93, 0xbd
- ]);
- const decoder = new TextDecoder();
- assertEquals(decoder.decode(fixture), "𝓽𝓮𝔁𝓽");
-});
-
-test(function textDecoderIgnoreBOM(): void {
- // prettier-ignore
- const fixture = new Uint8Array([
- 0xef, 0xbb, 0xbf,
- 0xf0, 0x9d, 0x93, 0xbd,
- 0xf0, 0x9d, 0x93, 0xae,
- 0xf0, 0x9d, 0x94, 0x81,
- 0xf0, 0x9d, 0x93, 0xbd
- ]);
- const decoder = new TextDecoder("utf-8", { ignoreBOM: true });
- assertEquals(decoder.decode(fixture), "𝓽𝓮𝔁𝓽");
-});
-
-test(function textDecoderNotBOM(): void {
- // prettier-ignore
- const fixture = new Uint8Array([
- 0xef, 0xbb, 0x89,
- 0xf0, 0x9d, 0x93, 0xbd,
- 0xf0, 0x9d, 0x93, 0xae,
- 0xf0, 0x9d, 0x94, 0x81,
- 0xf0, 0x9d, 0x93, 0xbd
- ]);
- const decoder = new TextDecoder("utf-8", { ignoreBOM: true });
- assertEquals(decoder.decode(fixture), "ﻉ𝓽𝓮𝔁𝓽");
-});
-
-test(function textDecoderASCII(): void {
- const fixture = new Uint8Array([0x89, 0x95, 0x9f, 0xbf]);
- const decoder = new TextDecoder("ascii");
- assertEquals(decoder.decode(fixture), "‰•Ÿ¿");
-});
-
-test(function textDecoderErrorEncoding(): void {
- let didThrow = false;
- try {
- new TextDecoder("foo");
- } catch (e) {
- didThrow = true;
- assertEquals(e.message, "The encoding label provided ('foo') is invalid.");
- }
- assert(didThrow);
-});
-
-test(function textEncoder(): void {
- const fixture = "𝓽𝓮𝔁𝓽";
- const encoder = new TextEncoder();
- // prettier-ignore
- assertEquals(Array.from(encoder.encode(fixture)), [
- 0xf0, 0x9d, 0x93, 0xbd,
- 0xf0, 0x9d, 0x93, 0xae,
- 0xf0, 0x9d, 0x94, 0x81,
- 0xf0, 0x9d, 0x93, 0xbd
- ]);
-});
-
-test(function textEncodeInto(): void {
- const fixture = "text";
- const encoder = new TextEncoder();
- const bytes = new Uint8Array(5);
- const result = encoder.encodeInto(fixture, bytes);
- assertEquals(result.read, 4);
- assertEquals(result.written, 4);
- // prettier-ignore
- assertEquals(Array.from(bytes), [
- 0x74, 0x65, 0x78, 0x74, 0x00,
- ]);
-});
-
-test(function textEncodeInto2(): void {
- const fixture = "𝓽𝓮𝔁𝓽";
- const encoder = new TextEncoder();
- const bytes = new Uint8Array(17);
- const result = encoder.encodeInto(fixture, bytes);
- assertEquals(result.read, 8);
- assertEquals(result.written, 16);
- // prettier-ignore
- assertEquals(Array.from(bytes), [
- 0xf0, 0x9d, 0x93, 0xbd,
- 0xf0, 0x9d, 0x93, 0xae,
- 0xf0, 0x9d, 0x94, 0x81,
- 0xf0, 0x9d, 0x93, 0xbd, 0x00,
- ]);
-});
-
-test(function textDecoderSharedUint8Array(): void {
- const ab = new SharedArrayBuffer(6);
- const dataView = new DataView(ab);
- const charCodeA = "A".charCodeAt(0);
- for (let i = 0; i < ab.byteLength; i++) {
- dataView.setUint8(i, charCodeA + i);
- }
- const ui8 = new Uint8Array(ab);
- const decoder = new TextDecoder();
- const actual = decoder.decode(ui8);
- assertEquals(actual, "ABCDEF");
-});
-
-test(function textDecoderSharedInt32Array(): void {
- const ab = new SharedArrayBuffer(8);
- const dataView = new DataView(ab);
- const charCodeA = "A".charCodeAt(0);
- for (let i = 0; i < ab.byteLength; i++) {
- dataView.setUint8(i, charCodeA + i);
- }
- const i32 = new Int32Array(ab);
- const decoder = new TextDecoder();
- const actual = decoder.decode(i32);
- assertEquals(actual, "ABCDEFGH");
-});
-
-test(function toStringShouldBeWebCompatibility(): void {
- const encoder = new TextEncoder();
- assertEquals(encoder.toString(), "[object TextEncoder]");
-
- const decoder = new TextDecoder();
- assertEquals(decoder.toString(), "[object TextDecoder]");
-});
diff --git a/js/timers.ts b/js/timers.ts
deleted file mode 100644
index 5bc4922e3..000000000
--- a/js/timers.ts
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { assert } from "./util.ts";
-import { window } from "./window.ts";
-import * as dispatch from "./dispatch.ts";
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-
-const { console } = window;
-
-interface Timer {
- id: number;
- callback: () => void;
- delay: number;
- due: number;
- repeat: boolean;
- scheduled: boolean;
-}
-
-// We'll subtract EPOCH every time we retrieve the time with Date.now(). This
-// ensures that absolute time values stay below UINT32_MAX - 2, which is the
-// maximum object key that EcmaScript considers "numerical". After running for
-// about a month, this is no longer true, and Deno explodes.
-// TODO(piscisaureus): fix that ^.
-const EPOCH = Date.now();
-const APOCALYPSE = 2 ** 32 - 2;
-
-// Timeout values > TIMEOUT_MAX are set to 1.
-const TIMEOUT_MAX = 2 ** 31 - 1;
-
-let globalTimeoutDue: number | null = null;
-
-let nextTimerId = 1;
-const idMap = new Map<number, Timer>();
-const dueMap: { [due: number]: Timer[] } = Object.create(null);
-
-function getTime(): number {
- // TODO: use a monotonic clock.
- const now = Date.now() - EPOCH;
- assert(now >= 0 && now < APOCALYPSE);
- return now;
-}
-
-function clearGlobalTimeout(): void {
- globalTimeoutDue = null;
- sendSync(dispatch.OP_GLOBAL_TIMER_STOP);
-}
-
-async function setGlobalTimeout(due: number, now: number): Promise<void> {
- // Since JS and Rust don't use the same clock, pass the time to rust as a
- // relative time value. On the Rust side we'll turn that into an absolute
- // value again.
- const timeout = due - now;
- assert(timeout >= 0);
-
- // Send message to the backend.
- globalTimeoutDue = due;
- await sendAsync(dispatch.OP_GLOBAL_TIMER, { timeout });
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
- fireTimers();
-}
-
-function setOrClearGlobalTimeout(due: number | null, now: number): void {
- if (due == null) {
- clearGlobalTimeout();
- } else {
- setGlobalTimeout(due, now);
- }
-}
-
-function schedule(timer: Timer, now: number): void {
- assert(!timer.scheduled);
- assert(now <= timer.due);
- // Find or create the list of timers that will fire at point-in-time `due`.
- let list = dueMap[timer.due];
- if (list === undefined) {
- list = dueMap[timer.due] = [];
- }
- // Append the newly scheduled timer to the list and mark it as scheduled.
- list.push(timer);
- timer.scheduled = true;
- // If the new timer is scheduled to fire before any timer that existed before,
- // update the global timeout to reflect this.
- if (globalTimeoutDue === null || globalTimeoutDue > timer.due) {
- setOrClearGlobalTimeout(timer.due, now);
- }
-}
-
-function unschedule(timer: Timer): void {
- if (!timer.scheduled) {
- return;
- }
- // Find the list of timers that will fire at point-in-time `due`.
- const list = dueMap[timer.due];
- if (list.length === 1) {
- // Time timer is the only one in the list. Remove the entire list.
- assert(list[0] === timer);
- delete dueMap[timer.due];
- // If the unscheduled timer was 'next up', find when the next timer that
- // still exists is due, and update the global alarm accordingly.
- if (timer.due === globalTimeoutDue) {
- let nextTimerDue: number | null = null;
- for (const key in dueMap) {
- nextTimerDue = Number(key);
- break;
- }
- setOrClearGlobalTimeout(nextTimerDue, getTime());
- }
- } else {
- // Multiple timers that are due at the same point in time.
- // Remove this timer from the list.
- const index = list.indexOf(timer);
- assert(index > -1);
- list.splice(index, 1);
- }
-}
-
-function fire(timer: Timer): void {
- // If the timer isn't found in the ID map, that means it has been cancelled
- // between the timer firing and the promise callback (this function).
- if (!idMap.has(timer.id)) {
- return;
- }
- // Reschedule the timer if it is a repeating one, otherwise drop it.
- if (!timer.repeat) {
- // One-shot timer: remove the timer from this id-to-timer map.
- idMap.delete(timer.id);
- } else {
- // Interval timer: compute when timer was supposed to fire next.
- // However make sure to never schedule the next interval in the past.
- const now = getTime();
- timer.due = Math.max(now, timer.due + timer.delay);
- schedule(timer, now);
- }
- // Call the user callback. Intermediate assignment is to avoid leaking `this`
- // to it, while also keeping the stack trace neat when it shows up in there.
- const callback = timer.callback;
- callback();
-}
-
-function fireTimers(): void {
- const now = getTime();
- // Bail out if we're not expecting the global timer to fire.
- if (globalTimeoutDue === null) {
- return;
- }
- // After firing the timers that are due now, this will hold the due time of
- // the first timer that hasn't fired yet.
- let nextTimerDue: number | null = null;
- // Walk over the keys of the 'due' map. Since dueMap is actually a regular
- // object and its keys are numerical and smaller than UINT32_MAX - 2,
- // keys are iterated in ascending order.
- for (const key in dueMap) {
- // Convert the object key (a string) to a number.
- const due = Number(key);
- // Break out of the loop if the next timer isn't due to fire yet.
- if (Number(due) > now) {
- nextTimerDue = due;
- break;
- }
- // Get the list of timers that have this due time, then drop it.
- const list = dueMap[key];
- delete dueMap[key];
- // Fire all the timers in the list.
- for (const timer of list) {
- // With the list dropped, the timer is no longer scheduled.
- timer.scheduled = false;
- // Place the callback on the microtask queue.
- Promise.resolve(timer).then(fire);
- }
- }
-
- // Update the global alarm to go off when the first-up timer that hasn't fired
- // yet is due.
- setOrClearGlobalTimeout(nextTimerDue, now);
-}
-
-export type Args = unknown[];
-
-function checkThis(thisArg: unknown): void {
- if (thisArg !== null && thisArg !== undefined && thisArg !== window) {
- throw new TypeError("Illegal invocation");
- }
-}
-
-function checkBigInt(n: unknown): void {
- if (typeof n === "bigint") {
- throw new TypeError("Cannot convert a BigInt value to a number");
- }
-}
-
-function setTimer(
- cb: (...args: Args) => void,
- delay: number,
- args: Args,
- repeat: boolean
-): number {
- // Bind `args` to the callback and bind `this` to window(global).
- const callback: () => void = cb.bind(window, ...args);
- // In the browser, the delay value must be coercible to an integer between 0
- // and INT32_MAX. Any other value will cause the timer to fire immediately.
- // We emulate this behavior.
- const now = getTime();
- if (delay > TIMEOUT_MAX) {
- console.warn(
- `${delay} does not fit into` +
- " a 32-bit signed integer." +
- "\nTimeout duration was set to 1."
- );
- delay = 1;
- }
- delay = Math.max(0, delay | 0);
-
- // Create a new, unscheduled timer object.
- const timer = {
- id: nextTimerId++,
- callback,
- args,
- delay,
- due: now + delay,
- repeat,
- scheduled: false
- };
- // Register the timer's existence in the id-to-timer map.
- idMap.set(timer.id, timer);
- // Schedule the timer in the due table.
- schedule(timer, now);
- return timer.id;
-}
-
-/** Sets a timer which executes a function once after the timer expires. */
-export function setTimeout(
- cb: (...args: Args) => void,
- delay = 0,
- ...args: Args
-): number {
- checkBigInt(delay);
- // @ts-ignore
- checkThis(this);
- return setTimer(cb, delay, args, false);
-}
-
-/** Repeatedly calls a function , with a fixed time delay between each call. */
-export function setInterval(
- cb: (...args: Args) => void,
- delay = 0,
- ...args: Args
-): number {
- checkBigInt(delay);
- // @ts-ignore
- checkThis(this);
- return setTimer(cb, delay, args, true);
-}
-
-/** Clears a previously set timer by id. AKA clearTimeout and clearInterval. */
-function clearTimer(id: number): void {
- id = Number(id);
- const timer = idMap.get(id);
- if (timer === undefined) {
- // Timer doesn't exist any more or never existed. This is not an error.
- return;
- }
- // Unschedule the timer if it is currently scheduled, and forget about it.
- unschedule(timer);
- idMap.delete(timer.id);
-}
-
-export function clearTimeout(id = 0): void {
- checkBigInt(id);
- if (id === 0) {
- return;
- }
- clearTimer(id);
-}
-
-export function clearInterval(id = 0): void {
- checkBigInt(id);
- if (id === 0) {
- return;
- }
- clearTimer(id);
-}
diff --git a/js/timers_test.ts b/js/timers_test.ts
deleted file mode 100644
index bc4fcffcf..000000000
--- a/js/timers_test.ts
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert, assertEquals, assertNotEquals } from "./test_util.ts";
-
-function deferred(): {
- promise: Promise<{}>;
- resolve: (value?: {} | PromiseLike<{}>) => void;
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- reject: (reason?: any) => void;
-} {
- let resolve;
- let reject;
- const promise = new Promise(
- (res, rej): void => {
- resolve = res;
- reject = rej;
- }
- );
- return {
- promise,
- resolve,
- reject
- };
-}
-
-async function waitForMs(ms): Promise<number> {
- return new Promise((resolve): number => setTimeout(resolve, ms));
-}
-
-test(async function timeoutSuccess(): Promise<void> {
- const { promise, resolve } = deferred();
- let count = 0;
- setTimeout((): void => {
- count++;
- resolve();
- }, 500);
- await promise;
- // count should increment
- assertEquals(count, 1);
-});
-
-test(async function timeoutArgs(): Promise<void> {
- const { promise, resolve } = deferred();
- const arg = 1;
- setTimeout(
- (a, b, c): void => {
- assertEquals(a, arg);
- assertEquals(b, arg.toString());
- assertEquals(c, [arg]);
- resolve();
- },
- 10,
- arg,
- arg.toString(),
- [arg]
- );
- await promise;
-});
-
-test(async function timeoutCancelSuccess(): Promise<void> {
- let count = 0;
- const id = setTimeout((): void => {
- count++;
- }, 1);
- // Cancelled, count should not increment
- clearTimeout(id);
- await waitForMs(600);
- assertEquals(count, 0);
-});
-
-test(async function timeoutCancelMultiple(): Promise<void> {
- function uncalled(): never {
- throw new Error("This function should not be called.");
- }
-
- // Set timers and cancel them in the same order.
- const t1 = setTimeout(uncalled, 10);
- const t2 = setTimeout(uncalled, 10);
- const t3 = setTimeout(uncalled, 10);
- clearTimeout(t1);
- clearTimeout(t2);
- clearTimeout(t3);
-
- // Set timers and cancel them in reverse order.
- const t4 = setTimeout(uncalled, 20);
- const t5 = setTimeout(uncalled, 20);
- const t6 = setTimeout(uncalled, 20);
- clearTimeout(t6);
- clearTimeout(t5);
- clearTimeout(t4);
-
- // Sleep until we're certain that the cancelled timers aren't gonna fire.
- await waitForMs(50);
-});
-
-test(async function timeoutCancelInvalidSilentFail(): Promise<void> {
- // Expect no panic
- const { promise, resolve } = deferred();
- let count = 0;
- const id = setTimeout((): void => {
- count++;
- // Should have no effect
- clearTimeout(id);
- resolve();
- }, 500);
- await promise;
- assertEquals(count, 1);
-
- // Should silently fail (no panic)
- clearTimeout(2147483647);
-});
-
-test(async function intervalSuccess(): Promise<void> {
- const { promise, resolve } = deferred();
- let count = 0;
- const id = setInterval((): void => {
- count++;
- clearInterval(id);
- resolve();
- }, 100);
- await promise;
- // Clear interval
- clearInterval(id);
- // count should increment twice
- assertEquals(count, 1);
-});
-
-test(async function intervalCancelSuccess(): Promise<void> {
- let count = 0;
- const id = setInterval((): void => {
- count++;
- }, 1);
- clearInterval(id);
- await waitForMs(500);
- assertEquals(count, 0);
-});
-
-test(async function intervalOrdering(): Promise<void> {
- const timers = [];
- let timeouts = 0;
- function onTimeout(): void {
- ++timeouts;
- for (let i = 1; i < timers.length; i++) {
- clearTimeout(timers[i]);
- }
- }
- for (let i = 0; i < 10; i++) {
- timers[i] = setTimeout(onTimeout, 1);
- }
- await waitForMs(500);
- assertEquals(timeouts, 1);
-});
-
-test(async function intervalCancelInvalidSilentFail(): Promise<void> {
- // Should silently fail (no panic)
- clearInterval(2147483647);
-});
-
-test(async function fireCallbackImmediatelyWhenDelayOverMaxValue(): Promise<
- void
-> {
- let count = 0;
- setTimeout((): void => {
- count++;
- }, 2 ** 31);
- await waitForMs(1);
- assertEquals(count, 1);
-});
-
-test(async function timeoutCallbackThis(): Promise<void> {
- const { promise, resolve } = deferred();
- const obj = {
- foo(): void {
- assertEquals(this, window);
- resolve();
- }
- };
- setTimeout(obj.foo, 1);
- await promise;
-});
-
-test(async function timeoutBindThis(): Promise<void> {
- function noop(): void {}
-
- const thisCheckPassed = [null, undefined, window, globalThis];
-
- const thisCheckFailed = [
- 0,
- "",
- true,
- false,
- {},
- [],
- "foo",
- (): void => {},
- Object.prototype
- ];
-
- thisCheckPassed.forEach(
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- (thisArg: any): void => {
- let hasThrown = 0;
- try {
- setTimeout.call(thisArg, noop, 1);
- hasThrown = 1;
- } catch (err) {
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 1);
- }
- );
-
- thisCheckFailed.forEach(
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- (thisArg: any): void => {
- let hasThrown = 0;
- try {
- setTimeout.call(thisArg, noop, 1);
- hasThrown = 1;
- } catch (err) {
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 2);
- }
- );
-});
-
-test(async function clearTimeoutShouldConvertToNumber(): Promise<void> {
- let called = false;
- const obj = {
- valueOf(): number {
- called = true;
- return 1;
- }
- };
- clearTimeout((obj as unknown) as number);
- assert(called);
-});
-
-test(function setTimeoutShouldThrowWithBigint(): void {
- let hasThrown = 0;
- try {
- setTimeout((): void => {}, (1n as unknown) as number);
- hasThrown = 1;
- } catch (err) {
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 2);
-});
-
-test(function clearTimeoutShouldThrowWithBigint(): void {
- let hasThrown = 0;
- try {
- clearTimeout((1n as unknown) as number);
- hasThrown = 1;
- } catch (err) {
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 2);
-});
-
-test(function testFunctionName(): void {
- assertEquals(clearTimeout.name, "clearTimeout");
- assertEquals(clearInterval.name, "clearInterval");
-});
-
-test(function testFunctionParamsLength(): void {
- assertEquals(setTimeout.length, 1);
- assertEquals(setInterval.length, 1);
- assertEquals(clearTimeout.length, 0);
- assertEquals(clearInterval.length, 0);
-});
-
-test(function clearTimeoutAndClearIntervalNotBeEquals(): void {
- assertNotEquals(clearTimeout, clearInterval);
-});
diff --git a/js/tls.ts b/js/tls.ts
deleted file mode 100644
index ec24b458b..000000000
--- a/js/tls.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.ts";
-import { Conn, ConnImpl } from "./net.ts";
-
-// TODO(ry) There are many configuration options to add...
-// https://docs.rs/rustls/0.16.0/rustls/struct.ClientConfig.html
-interface DialTLSOptions {
- port: number;
- hostname?: string;
-}
-const dialTLSDefaults = { hostname: "127.0.0.1", transport: "tcp" };
-
-/**
- * dialTLS establishes a secure connection over TLS (transport layer security).
- */
-export async function dialTLS(options: DialTLSOptions): Promise<Conn> {
- options = Object.assign(dialTLSDefaults, options);
- const res = await sendAsync(dispatch.OP_DIAL_TLS, options);
- return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!);
-}
diff --git a/js/tls_test.ts b/js/tls_test.ts
deleted file mode 100644
index 25900f876..000000000
--- a/js/tls_test.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, testPerm, assert, assertEquals } from "./test_util.ts";
-
-// TODO(ry) The tests in this file use github.com:443, but it would be better to
-// not rely on an internet connection and rather use a localhost TLS server.
-
-test(async function dialTLSNoPerm(): Promise<void> {
- let err;
- try {
- await Deno.dialTLS({ hostname: "github.com", port: 443 });
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ net: true }, async function dialTLSBasic(): Promise<void> {
- const conn = await Deno.dialTLS({ hostname: "github.com", port: 443 });
- assert(conn.rid > 0);
- const body = new TextEncoder().encode("GET / HTTP/1.0\r\n\r\n");
- const writeResult = await conn.write(body);
- assertEquals(body.length, writeResult);
- conn.close();
-});
diff --git a/js/truncate.ts b/js/truncate.ts
deleted file mode 100644
index 5ce7b5158..000000000
--- a/js/truncate.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.ts";
-
-function coerceLen(len?: number): number {
- if (!len) {
- return 0;
- }
-
- if (len < 0) {
- return 0;
- }
-
- return len;
-}
-
-/** 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 {
- sendSync(dispatch.OP_TRUNCATE, { name, len: coerceLen(len) });
-}
-
-/**
- * Truncates or extends the specified file, updating the size of this file to
- * become size.
- *
- * await Deno.truncate("hello.txt", 10);
- */
-export async function truncate(name: string, len?: number): Promise<void> {
- await sendAsync(dispatch.OP_TRUNCATE, { name, len: coerceLen(len) });
-}
diff --git a/js/truncate_test.ts b/js/truncate_test.ts
deleted file mode 100644
index 055db8652..000000000
--- a/js/truncate_test.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assertEquals } from "./test_util.ts";
-
-function readDataSync(name: string): string {
- const data = Deno.readFileSync(name);
- const decoder = new TextDecoder("utf-8");
- const text = decoder.decode(data);
- return text;
-}
-
-async function readData(name: string): Promise<string> {
- const data = await Deno.readFile(name);
- const decoder = new TextDecoder("utf-8");
- const text = decoder.decode(data);
- return text;
-}
-
-testPerm({ read: true, write: true }, function truncateSyncSuccess(): void {
- const enc = new TextEncoder();
- const d = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test_truncateSync.txt";
- Deno.writeFileSync(filename, d);
- Deno.truncateSync(filename, 20);
- let data = readDataSync(filename);
- assertEquals(data.length, 20);
- Deno.truncateSync(filename, 5);
- data = readDataSync(filename);
- assertEquals(data.length, 5);
- Deno.truncateSync(filename, -5);
- data = readDataSync(filename);
- assertEquals(data.length, 0);
- Deno.removeSync(filename);
-});
-
-testPerm({ read: true, write: true }, async function truncateSuccess(): Promise<
- void
-> {
- const enc = new TextEncoder();
- const d = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test_truncate.txt";
- await Deno.writeFile(filename, d);
- await Deno.truncate(filename, 20);
- let data = await readData(filename);
- assertEquals(data.length, 20);
- await Deno.truncate(filename, 5);
- data = await readData(filename);
- assertEquals(data.length, 5);
- await Deno.truncate(filename, -5);
- data = await readData(filename);
- assertEquals(data.length, 0);
- await Deno.remove(filename);
-});
-
-testPerm({ write: false }, function truncateSyncPerm(): void {
- let err;
- try {
- Deno.mkdirSync("/test_truncateSyncPermission.txt");
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
-
-testPerm({ write: false }, async function truncatePerm(): Promise<void> {
- let err;
- try {
- await Deno.mkdir("/test_truncatePermission.txt");
- } catch (e) {
- err = e;
- }
- assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(err.name, "PermissionDenied");
-});
diff --git a/js/ts_global.d.ts b/js/ts_global.d.ts
deleted file mode 100644
index 71a01e30e..000000000
--- a/js/ts_global.d.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-// This scopes the `ts` namespace globally, which is where it exists at runtime
-// when building Deno, but the `typescript/lib/typescript.d.ts` is defined as a
-// module.
-
-// Warning! This is a magical import. We don't want to have multiple copies of
-// typescript.d.ts around the repo, there's already one in
-// deno_typescript/typescript/lib/typescript.d.ts. Ideally we could simply point
-// to that in this import specifier, but "cargo package" is very strict and
-// requires all files to be present in a crate's subtree.
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import * as ts_ from "$asset$/typescript.d.ts";
-
-declare global {
- namespace ts {
- export = ts_;
- }
-}
diff --git a/js/type_directives.ts b/js/type_directives.ts
deleted file mode 100644
index 9b27887b5..000000000
--- a/js/type_directives.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-interface FileReference {
- fileName: string;
- pos: number;
- end: number;
-}
-
-/** Remap the module name based on any supplied type directives passed. */
-export function getMappedModuleName(
- source: FileReference,
- typeDirectives: Map<FileReference, string>
-): string {
- const { fileName: sourceFileName, pos: sourcePos } = source;
- for (const [{ fileName, pos }, value] of typeDirectives.entries()) {
- if (sourceFileName === fileName && sourcePos === pos) {
- return value;
- }
- }
- return source.fileName;
-}
-
-/** Matches directives that look something like this and parses out the value
- * of the directive:
- *
- * // @deno-types="./foo.d.ts"
- *
- * [See Diagram](http://bit.ly/31nZPCF)
- */
-const typeDirectiveRegEx = /@deno-types\s*=\s*(["'])((?:(?=(\\?))\3.)*?)\1/gi;
-
-/** Matches `import`, `import from` or `export from` statements and parses out the value of the
- * module specifier in the second capture group:
- *
- * import "./foo.js"
- * import * as foo from "./foo.js"
- * export { a, b, c } from "./bar.js"
- *
- * [See Diagram](http://bit.ly/2lOsp0K)
- */
-const importExportRegEx = /(?:import|export)(?:\s+|\s+[\s\S]*?from\s+)?(["'])((?:(?=(\\?))\3.)*?)\1/;
-
-/** Parses out any Deno type directives that are part of the source code, or
- * returns `undefined` if there are not any.
- */
-export function parseTypeDirectives(
- sourceCode: string | undefined
-): Map<FileReference, string> | undefined {
- if (!sourceCode) {
- return;
- }
-
- // collect all the directives in the file and their start and end positions
- const directives: FileReference[] = [];
- let maybeMatch: RegExpExecArray | null = null;
- while ((maybeMatch = typeDirectiveRegEx.exec(sourceCode))) {
- const [matchString, , fileName] = maybeMatch;
- const { index: pos } = maybeMatch;
- directives.push({
- fileName,
- pos,
- end: pos + matchString.length
- });
- }
- if (!directives.length) {
- return;
- }
-
- // work from the last directive backwards for the next `import`/`export`
- // statement
- directives.reverse();
- const results = new Map<FileReference, string>();
- for (const { end, fileName, pos } of directives) {
- const searchString = sourceCode.substring(end);
- const maybeMatch = importExportRegEx.exec(searchString);
- if (maybeMatch) {
- const [matchString, , targetFileName] = maybeMatch;
- const targetPos =
- end + maybeMatch.index + matchString.indexOf(targetFileName) - 1;
- const target: FileReference = {
- fileName: targetFileName,
- pos: targetPos,
- end: targetPos + targetFileName.length
- };
- results.set(target, fileName);
- }
- sourceCode = sourceCode.substring(0, pos);
- }
-
- return results;
-}
diff --git a/js/types.ts b/js/types.ts
deleted file mode 100644
index 88462d758..000000000
--- a/js/types.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-export type TypedArray = Uint8Array | Float32Array | Int32Array;
diff --git a/js/unit_test_runner.ts b/js/unit_test_runner.ts
deleted file mode 100755
index 24dae7706..000000000
--- a/js/unit_test_runner.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/env -S deno run --reload --allow-run
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import "./unit_tests.ts";
-import { permissionCombinations, parseUnitTestOutput } from "./test_util.ts";
-
-interface TestResult {
- perms: string;
- output: string;
- result: number;
-}
-
-function permsToCliFlags(perms: Deno.Permissions): string[] {
- return Object.keys(perms)
- .map(
- (key): string => {
- if (!perms[key]) return "";
-
- const cliFlag = key.replace(
- /\.?([A-Z])/g,
- (x, y): string => `-${y.toLowerCase()}`
- );
- return `--allow-${cliFlag}`;
- }
- )
- .filter((e): boolean => e.length > 0);
-}
-
-function fmtPerms(perms: Deno.Permissions): string {
- let fmt = permsToCliFlags(perms).join(" ");
-
- if (!fmt) {
- fmt = "<no permissions>";
- }
-
- return fmt;
-}
-
-async function main(): Promise<void> {
- console.log(
- "Discovered permission combinations for tests:",
- permissionCombinations.size
- );
-
- for (const perms of permissionCombinations.values()) {
- console.log("\t" + fmtPerms(perms));
- }
-
- const testResults = new Set<TestResult>();
-
- for (const perms of permissionCombinations.values()) {
- const permsFmt = fmtPerms(perms);
- console.log(`Running tests for: ${permsFmt}`);
- const cliPerms = permsToCliFlags(perms);
- // run subsequent tests using same deno executable
- const args = [
- Deno.execPath(),
- "run",
- "--no-prompt",
- ...cliPerms,
- "js/unit_tests.ts"
- ];
-
- const p = Deno.run({
- args,
- stdout: "piped"
- });
-
- const { actual, expected, resultOutput } = parseUnitTestOutput(
- await p.output(),
- true
- );
-
- let result = 0;
-
- if (!actual && !expected) {
- console.error("Bad js/unit_test.ts output");
- result = 1;
- } else if (expected !== actual) {
- result = 1;
- }
-
- testResults.add({
- perms: permsFmt,
- output: resultOutput,
- result
- });
- }
-
- // if any run tests returned non-zero status then whole test
- // run should fail
- let testsFailed = false;
-
- for (const testResult of testResults) {
- console.log(`Summary for ${testResult.perms}`);
- console.log(testResult.output + "\n");
- testsFailed = testsFailed || Boolean(testResult.result);
- }
-
- if (testsFailed) {
- console.error("Unit tests failed");
- Deno.exit(1);
- }
-
- console.log("Unit tests passed");
-}
-
-main();
diff --git a/js/unit_tests.ts b/js/unit_tests.ts
deleted file mode 100644
index a83b57c15..000000000
--- a/js/unit_tests.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-// This test is executed as part of tools/test.py
-// But it can also be run manually: ./target/debug/deno js/unit_tests.ts
-
-import "./blob_test.ts";
-import "./body_test.ts";
-import "./buffer_test.ts";
-import "./build_test.ts";
-import "./chmod_test.ts";
-import "./chown_test.ts";
-import "./console_test.ts";
-import "./copy_file_test.ts";
-import "./custom_event_test.ts";
-import "./dir_test.ts";
-import "./dispatch_json_test.ts";
-import "./error_stack_test.ts";
-import "./event_test.ts";
-import "./event_target_test.ts";
-import "./fetch_test.ts";
-import "./file_test.ts";
-import "./files_test.ts";
-import "./form_data_test.ts";
-import "./get_random_values_test.ts";
-import "./globals_test.ts";
-import "./headers_test.ts";
-import "./link_test.ts";
-import "./location_test.ts";
-import "./make_temp_dir_test.ts";
-import "./metrics_test.ts";
-import "./mixins/dom_iterable_test.ts";
-import "./mkdir_test.ts";
-import "./net_test.ts";
-import "./os_test.ts";
-import "./process_test.ts";
-import "./read_dir_test.ts";
-import "./read_file_test.ts";
-import "./read_link_test.ts";
-import "./rename_test.ts";
-import "./request_test.ts";
-import "./resources_test.ts";
-import "./stat_test.ts";
-import "./symlink_test.ts";
-import "./text_encoding_test.ts";
-import "./timers_test.ts";
-import "./tls_test.ts";
-import "./truncate_test.ts";
-import "./url_test.ts";
-import "./url_search_params_test.ts";
-import "./utime_test.ts";
-import "./write_file_test.ts";
-import "./performance_test.ts";
-import "./permissions_test.ts";
-import "./version_test.ts";
-
-import "../website/app_test.ts";
-
-import { runIfMain } from "../std/testing/mod.ts";
-
-async function main(): Promise<void> {
- // Testing entire test suite serially
- runIfMain(import.meta);
-}
-
-main();
diff --git a/js/url.ts b/js/url.ts
deleted file mode 100644
index f22198da4..000000000
--- a/js/url.ts
+++ /dev/null
@@ -1,376 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as urlSearchParams from "./url_search_params.ts";
-import * as domTypes from "./dom_types.ts";
-import { getRandomValues } from "./get_random_values.ts";
-import { window } from "./window.ts";
-
-interface URLParts {
- protocol: string;
- username: string;
- password: string;
- hostname: string;
- port: string;
- path: string;
- query: string | null;
- hash: string;
-}
-
-const patterns = {
- protocol: "(?:([^:/?#]+):)",
- authority: "(?://([^/?#]*))",
- path: "([^?#]*)",
- query: "(\\?[^#]*)",
- hash: "(#.*)",
-
- authentication: "(?:([^:]*)(?::([^@]*))?@)",
- hostname: "([^:]+)",
- port: "(?::(\\d+))"
-};
-
-const urlRegExp = new RegExp(
- `^${patterns.protocol}?${patterns.authority}?${patterns.path}${
- patterns.query
- }?${patterns.hash}?`
-);
-
-const authorityRegExp = new RegExp(
- `^${patterns.authentication}?${patterns.hostname}${patterns.port}?$`
-);
-
-const searchParamsMethods: Array<keyof urlSearchParams.URLSearchParams> = [
- "append",
- "delete",
- "set"
-];
-
-function parse(url: string): URLParts | undefined {
- const urlMatch = urlRegExp.exec(url);
- if (urlMatch) {
- const [, , authority] = urlMatch;
- const authorityMatch = authority
- ? authorityRegExp.exec(authority)
- : [null, null, null, null, null];
- if (authorityMatch) {
- return {
- protocol: urlMatch[1] || "",
- username: authorityMatch[1] || "",
- password: authorityMatch[2] || "",
- hostname: authorityMatch[3] || "",
- port: authorityMatch[4] || "",
- path: urlMatch[3] || "",
- query: urlMatch[4] || "",
- hash: urlMatch[5] || ""
- };
- }
- }
- return undefined;
-}
-
-// Based on https://github.com/kelektiv/node-uuid
-// TODO(kevinkassimo): Use deno_std version once possible.
-function generateUUID(): string {
- return "00000000-0000-4000-8000-000000000000".replace(
- /[0]/g,
- (): string =>
- // random integer from 0 to 15 as a hex digit.
- (getRandomValues(new Uint8Array(1))[0] % 16).toString(16)
- );
-}
-
-// Keep it outside of URL to avoid any attempts of access.
-export const blobURLMap = new Map<string, domTypes.Blob>();
-
-function isAbsolutePath(path: string): boolean {
- return path.startsWith("/");
-}
-
-// Resolves `.`s and `..`s where possible.
-// Preserves repeating and trailing `/`s by design.
-function normalizePath(path: string): string {
- const isAbsolute = isAbsolutePath(path);
- path = path.replace(/^\//, "");
- const pathSegments = path.split("/");
-
- const newPathSegments: string[] = [];
- for (let i = 0; i < pathSegments.length; i++) {
- const previous = newPathSegments[newPathSegments.length - 1];
- if (
- pathSegments[i] == ".." &&
- previous != ".." &&
- (previous != undefined || isAbsolute)
- ) {
- newPathSegments.pop();
- } else if (pathSegments[i] != ".") {
- newPathSegments.push(pathSegments[i]);
- }
- }
-
- let newPath = newPathSegments.join("/");
- if (!isAbsolute) {
- if (newPathSegments.length == 0) {
- newPath = ".";
- }
- } else {
- newPath = `/${newPath}`;
- }
- return newPath;
-}
-
-// Standard URL basing logic, applied to paths.
-function resolvePathFromBase(path: string, basePath: string): string {
- const normalizedPath = normalizePath(path);
- if (isAbsolutePath(normalizedPath)) {
- return normalizedPath;
- }
- const normalizedBasePath = normalizePath(basePath);
- if (!isAbsolutePath(normalizedBasePath)) {
- throw new TypeError("Base path must be absolute.");
- }
-
- // Special case.
- if (path == "") {
- return normalizedBasePath;
- }
-
- // Remove everything after the last `/` in `normalizedBasePath`.
- const prefix = normalizedBasePath.replace(/[^\/]*$/, "");
- // If `normalizedPath` ends with `.` or `..`, add a trailing space.
- const suffix = normalizedPath.replace(/(?<=(^|\/)(\.|\.\.))$/, "/");
-
- return normalizePath(prefix + suffix);
-}
-
-export class URL {
- private _parts: URLParts;
- private _searchParams!: urlSearchParams.URLSearchParams;
-
- private _updateSearchParams(): void {
- const searchParams = new urlSearchParams.URLSearchParams(this.search);
-
- for (const methodName of searchParamsMethods) {
- /* eslint-disable @typescript-eslint/no-explicit-any */
- const method: (...args: any[]) => any = searchParams[methodName];
- searchParams[methodName] = (...args: unknown[]): any => {
- method.apply(searchParams, args);
- this.search = searchParams.toString();
- };
- /* eslint-enable */
- }
- this._searchParams = searchParams;
-
- // convert to `any` that has avoided the private limit
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- (this._searchParams as any).url = this;
- }
-
- get hash(): string {
- return this._parts.hash;
- }
-
- set hash(value: string) {
- value = unescape(String(value));
- if (!value) {
- this._parts.hash = "";
- } else {
- if (value.charAt(0) !== "#") {
- value = `#${value}`;
- }
- // hashes can contain % and # unescaped
- this._parts.hash = escape(value)
- .replace(/%25/g, "%")
- .replace(/%23/g, "#");
- }
- }
-
- get host(): string {
- return `${this.hostname}${this.port ? `:${this.port}` : ""}`;
- }
-
- set host(value: string) {
- value = String(value);
- const url = new URL(`http://${value}`);
- this._parts.hostname = url.hostname;
- this._parts.port = url.port;
- }
-
- get hostname(): string {
- return this._parts.hostname;
- }
-
- set hostname(value: string) {
- value = String(value);
- this._parts.hostname = encodeURIComponent(value);
- }
-
- get href(): string {
- const authentication =
- this.username || this.password
- ? `${this.username}${this.password ? ":" + this.password : ""}@`
- : "";
-
- return `${this.protocol}//${authentication}${this.host}${this.pathname}${
- this.search
- }${this.hash}`;
- }
-
- set href(value: string) {
- value = String(value);
- if (value !== this.href) {
- const url = new URL(value);
- this._parts = { ...url._parts };
- this._updateSearchParams();
- }
- }
-
- get origin(): string {
- return `${this.protocol}//${this.host}`;
- }
-
- get password(): string {
- return this._parts.password;
- }
-
- set password(value: string) {
- value = String(value);
- this._parts.password = encodeURIComponent(value);
- }
-
- get pathname(): string {
- return this._parts.path ? this._parts.path : "/";
- }
-
- set pathname(value: string) {
- value = unescape(String(value));
- if (!value || value.charAt(0) !== "/") {
- value = `/${value}`;
- }
- // paths can contain % unescaped
- this._parts.path = escape(value).replace(/%25/g, "%");
- }
-
- get port(): string {
- return this._parts.port;
- }
-
- set port(value: string) {
- const port = parseInt(String(value), 10);
- this._parts.port = isNaN(port)
- ? ""
- : Math.max(0, port % 2 ** 16).toString();
- }
-
- get protocol(): string {
- return `${this._parts.protocol}:`;
- }
-
- set protocol(value: string) {
- value = String(value);
- if (value) {
- if (value.charAt(value.length - 1) === ":") {
- value = value.slice(0, -1);
- }
- this._parts.protocol = encodeURIComponent(value);
- }
- }
-
- get search(): string {
- if (this._parts.query === null || this._parts.query === "") {
- return "";
- }
-
- return this._parts.query;
- }
-
- set search(value: string) {
- value = String(value);
- let query: string | null;
-
- if (value === "") {
- query = null;
- } else if (value.charAt(0) !== "?") {
- query = `?${value}`;
- } else {
- query = value;
- }
-
- this._parts.query = query;
- this._updateSearchParams();
- }
-
- get username(): string {
- return this._parts.username;
- }
-
- set username(value: string) {
- value = String(value);
- this._parts.username = encodeURIComponent(value);
- }
-
- get searchParams(): urlSearchParams.URLSearchParams {
- return this._searchParams;
- }
-
- constructor(url: string, base?: string | URL) {
- let baseParts: URLParts | undefined;
- if (base) {
- baseParts = typeof base === "string" ? parse(base) : base._parts;
- if (!baseParts || baseParts.protocol == "") {
- throw new TypeError("Invalid base URL.");
- }
- }
-
- const urlParts = parse(url);
- if (!urlParts) {
- throw new TypeError("Invalid URL.");
- }
-
- if (urlParts.protocol) {
- this._parts = urlParts;
- } else if (baseParts) {
- this._parts = {
- protocol: baseParts.protocol,
- username: baseParts.username,
- password: baseParts.password,
- hostname: baseParts.hostname,
- port: baseParts.port,
- path: resolvePathFromBase(urlParts.path, baseParts.path || "/"),
- query: urlParts.query,
- hash: urlParts.hash
- };
- } else {
- throw new TypeError("URL requires a base URL.");
- }
- this._updateSearchParams();
- }
-
- toString(): string {
- return this.href;
- }
-
- toJSON(): string {
- return this.href;
- }
-
- // TODO(kevinkassimo): implement MediaSource version in the future.
- static createObjectURL(b: domTypes.Blob): string {
- const origin = window.location.origin || "http://deno-opaque-origin";
- const key = `blob:${origin}/${generateUUID()}`;
- blobURLMap.set(key, b);
- return key;
- }
-
- static revokeObjectURL(url: string): void {
- let urlObject;
- try {
- urlObject = new URL(url);
- } catch {
- throw new TypeError("Provided URL string is not valid");
- }
- if (urlObject.protocol !== "blob:") {
- return;
- }
- // Origin match check seems irrelevant for now, unless we implement
- // persisten storage for per window.location.origin at some point.
- blobURLMap.delete(url);
- }
-}
diff --git a/js/url_search_params.ts b/js/url_search_params.ts
deleted file mode 100644
index 0835133d5..000000000
--- a/js/url_search_params.ts
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { URL } from "./url.ts";
-import { requiredArguments, isIterable } from "./util.ts";
-
-export class URLSearchParams {
- private params: Array<[string, string]> = [];
- private url: URL | null = null;
-
- constructor(init: string | string[][] | Record<string, string> = "") {
- if (typeof init === "string") {
- this._handleStringInitialization(init);
- return;
- }
-
- if (Array.isArray(init) || isIterable(init)) {
- this._handleArrayInitialization(init);
- return;
- }
-
- if (Object(init) !== init) {
- return;
- }
-
- if (init instanceof URLSearchParams) {
- this.params = init.params;
- return;
- }
-
- // Overload: record<USVString, USVString>
- for (const key of Object.keys(init)) {
- this.append(key, init[key]);
- }
- }
-
- private updateSteps(): void {
- if (this.url === null) {
- return;
- }
-
- let query: string | null = this.toString();
- if (query === "") {
- query = null;
- }
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- (this.url as any)._parts.query = query;
- }
-
- /** 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 {
- requiredArguments("URLSearchParams.append", arguments.length, 2);
- this.params.push([String(name), String(value)]);
- this.updateSteps();
- }
-
- /** Deletes the given search parameter and its associated value,
- * from the list of all search parameters.
- *
- * searchParams.delete('name');
- */
- delete(name: string): void {
- requiredArguments("URLSearchParams.delete", arguments.length, 1);
- name = String(name);
- let i = 0;
- while (i < this.params.length) {
- if (this.params[i][0] === name) {
- this.params.splice(i, 1);
- } else {
- i++;
- }
- }
- this.updateSteps();
- }
-
- /** Returns all the values associated with a given search parameter
- * as an array.
- *
- * searchParams.getAll('name');
- */
- getAll(name: string): string[] {
- requiredArguments("URLSearchParams.getAll", arguments.length, 1);
- name = String(name);
- const values = [];
- for (const entry of this.params) {
- if (entry[0] === name) {
- values.push(entry[1]);
- }
- }
-
- return values;
- }
-
- /** Returns the first value associated to the given search parameter.
- *
- * searchParams.get('name');
- */
- get(name: string): string | null {
- requiredArguments("URLSearchParams.get", arguments.length, 1);
- name = String(name);
- for (const entry of this.params) {
- if (entry[0] === name) {
- return entry[1];
- }
- }
-
- return null;
- }
-
- /** Returns a Boolean that indicates whether a parameter with the
- * specified name exists.
- *
- * searchParams.has('name');
- */
- has(name: string): boolean {
- requiredArguments("URLSearchParams.has", arguments.length, 1);
- name = String(name);
- return this.params.some((entry): boolean => entry[0] === name);
- }
-
- /** 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 {
- requiredArguments("URLSearchParams.set", arguments.length, 2);
-
- // If there are any name-value pairs whose name is name, in list,
- // set the value of the first such name-value pair to value
- // and remove the others.
- name = String(name);
- value = String(value);
- let found = false;
- let i = 0;
- while (i < this.params.length) {
- if (this.params[i][0] === name) {
- if (!found) {
- this.params[i][1] = value;
- found = true;
- i++;
- } else {
- this.params.splice(i, 1);
- }
- } else {
- i++;
- }
- }
-
- // Otherwise, append a new name-value pair whose name is name
- // and value is value, to list.
- if (!found) {
- this.append(name, value);
- }
-
- this.updateSteps();
- }
-
- /** 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 {
- this.params = this.params.sort(
- (a, b): number => (a[0] === b[0] ? 0 : a[0] > b[0] ? 1 : -1)
- );
- this.updateSteps();
- }
-
- /** 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: this) => void,
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- thisArg?: any
- ): void {
- requiredArguments("URLSearchParams.forEach", arguments.length, 1);
-
- if (typeof thisArg !== "undefined") {
- callbackfn = callbackfn.bind(thisArg);
- }
-
- for (const [key, value] of this.entries()) {
- callbackfn(value, key, this);
- }
- }
-
- /** Returns an iterator allowing to go through all keys contained
- * in this object.
- *
- * for (const key of searchParams.keys()) {
- * console.log(key);
- * }
- */
- *keys(): IterableIterator<string> {
- for (const entry of this.params) {
- yield entry[0];
- }
- }
-
- /** Returns an iterator allowing to go through all values contained
- * in this object.
- *
- * for (const value of searchParams.values()) {
- * console.log(value);
- * }
- */
- *values(): IterableIterator<string> {
- for (const entry of this.params) {
- yield entry[1];
- }
- }
-
- /** 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(): IterableIterator<[string, string]> {
- yield* this.params;
- }
-
- /** 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](): IterableIterator<[string, string]> {
- yield* this.params;
- }
-
- /** Returns a query string suitable for use in a URL.
- *
- * searchParams.toString();
- */
- toString(): string {
- return this.params
- .map(
- (tuple): string =>
- `${encodeURIComponent(tuple[0])}=${encodeURIComponent(tuple[1])}`
- )
- .join("&");
- }
-
- private _handleStringInitialization(init: string): void {
- // Overload: USVString
- // If init is a string and starts with U+003F (?),
- // remove the first code point from init.
- if (init.charCodeAt(0) === 0x003f) {
- init = init.slice(1);
- }
-
- for (const pair of init.split("&")) {
- // Empty params are ignored
- if (pair.length === 0) {
- continue;
- }
- const position = pair.indexOf("=");
- const name = pair.slice(0, position === -1 ? pair.length : position);
- const value = pair.slice(name.length + 1);
- this.append(decodeURIComponent(name), decodeURIComponent(value));
- }
- }
-
- private _handleArrayInitialization(
- init: string[][] | Iterable<[string, string]>
- ): void {
- // Overload: sequence<sequence<USVString>>
- for (const tuple of init) {
- // If pair does not contain exactly two items, then throw a TypeError.
- if (tuple.length !== 2) {
- throw new TypeError(
- "URLSearchParams.constructor tuple array argument must only contain pair elements"
- );
- }
- this.append(tuple[0], tuple[1]);
- }
- }
-}
diff --git a/js/url_search_params_test.ts b/js/url_search_params_test.ts
deleted file mode 100644
index 08b0c5a1f..000000000
--- a/js/url_search_params_test.ts
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert, assertEquals } from "./test_util.ts";
-
-test(function urlSearchParamsInitString(): void {
- const init = "c=4&a=2&b=3&%C3%A1=1";
- const searchParams = new URLSearchParams(init);
- assert(
- init === searchParams.toString(),
- "The init query string does not match"
- );
-});
-
-test(function urlSearchParamsInitIterable(): void {
- const init = [["a", "54"], ["b", "true"]];
- const searchParams = new URLSearchParams(init);
- assertEquals(searchParams.toString(), "a=54&b=true");
-});
-
-test(function urlSearchParamsInitRecord(): void {
- const init = { a: "54", b: "true" };
- const searchParams = new URLSearchParams(init);
- assertEquals(searchParams.toString(), "a=54&b=true");
-});
-
-test(function urlSearchParamsInit(): void {
- const params1 = new URLSearchParams("a=b");
- assertEquals(params1.toString(), "a=b");
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const params2 = new URLSearchParams(params1 as any);
- assertEquals(params2.toString(), "a=b");
-});
-
-test(function urlSearchParamsAppendSuccess(): void {
- const searchParams = new URLSearchParams();
- searchParams.append("a", "true");
- assertEquals(searchParams.toString(), "a=true");
-});
-
-test(function urlSearchParamsDeleteSuccess(): void {
- const init = "a=54&b=true";
- const searchParams = new URLSearchParams(init);
- searchParams.delete("b");
- assertEquals(searchParams.toString(), "a=54");
-});
-
-test(function urlSearchParamsGetAllSuccess(): void {
- const init = "a=54&b=true&a=true";
- const searchParams = new URLSearchParams(init);
- assertEquals(searchParams.getAll("a"), ["54", "true"]);
- assertEquals(searchParams.getAll("b"), ["true"]);
- assertEquals(searchParams.getAll("c"), []);
-});
-
-test(function urlSearchParamsGetSuccess(): void {
- const init = "a=54&b=true&a=true";
- const searchParams = new URLSearchParams(init);
- assertEquals(searchParams.get("a"), "54");
- assertEquals(searchParams.get("b"), "true");
- assertEquals(searchParams.get("c"), null);
-});
-
-test(function urlSearchParamsHasSuccess(): void {
- const init = "a=54&b=true&a=true";
- const searchParams = new URLSearchParams(init);
- assert(searchParams.has("a"));
- assert(searchParams.has("b"));
- assert(!searchParams.has("c"));
-});
-
-test(function urlSearchParamsSetReplaceFirstAndRemoveOthers(): void {
- const init = "a=54&b=true&a=true";
- const searchParams = new URLSearchParams(init);
- searchParams.set("a", "false");
- assertEquals(searchParams.toString(), "a=false&b=true");
-});
-
-test(function urlSearchParamsSetAppendNew(): void {
- const init = "a=54&b=true&a=true";
- const searchParams = new URLSearchParams(init);
- searchParams.set("c", "foo");
- assertEquals(searchParams.toString(), "a=54&b=true&a=true&c=foo");
-});
-
-test(function urlSearchParamsSortSuccess(): void {
- const init = "c=4&a=2&b=3&a=1";
- const searchParams = new URLSearchParams(init);
- searchParams.sort();
- assertEquals(searchParams.toString(), "a=2&a=1&b=3&c=4");
-});
-
-test(function urlSearchParamsForEachSuccess(): void {
- const init = [["a", "54"], ["b", "true"]];
- const searchParams = new URLSearchParams(init);
- let callNum = 0;
- searchParams.forEach(
- (value, key, parent): void => {
- assertEquals(searchParams, parent);
- assertEquals(value, init[callNum][1]);
- assertEquals(key, init[callNum][0]);
- callNum++;
- }
- );
- assertEquals(callNum, init.length);
-});
-
-test(function urlSearchParamsMissingName(): void {
- const init = "=4";
- const searchParams = new URLSearchParams(init);
- assertEquals(searchParams.get(""), "4");
- assertEquals(searchParams.toString(), "=4");
-});
-
-test(function urlSearchParamsMissingValue(): void {
- const init = "4=";
- const searchParams = new URLSearchParams(init);
- assertEquals(searchParams.get("4"), "");
- assertEquals(searchParams.toString(), "4=");
-});
-
-test(function urlSearchParamsMissingEqualSign(): void {
- const init = "4";
- const searchParams = new URLSearchParams(init);
- assertEquals(searchParams.get("4"), "");
- assertEquals(searchParams.toString(), "4=");
-});
-
-test(function urlSearchParamsMissingPair(): void {
- const init = "c=4&&a=54&";
- const searchParams = new URLSearchParams(init);
- assertEquals(searchParams.toString(), "c=4&a=54");
-});
-
-// If pair does not contain exactly two items, then throw a TypeError.
-// ref https://url.spec.whatwg.org/#interface-urlsearchparams
-test(function urlSearchParamsShouldThrowTypeError(): void {
- let hasThrown = 0;
-
- try {
- new URLSearchParams([["1"]]);
- hasThrown = 1;
- } catch (err) {
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
-
- assertEquals(hasThrown, 2);
-
- try {
- new URLSearchParams([["1", "2", "3"]]);
- hasThrown = 1;
- } catch (err) {
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
-
- assertEquals(hasThrown, 2);
-});
-
-test(function urlSearchParamsAppendArgumentsCheck(): void {
- const methodRequireOneParam = ["delete", "getAll", "get", "has", "forEach"];
-
- const methodRequireTwoParams = ["append", "set"];
-
- methodRequireOneParam.concat(methodRequireTwoParams).forEach(
- (method: string): void => {
- const searchParams = new URLSearchParams();
- let hasThrown = 0;
- try {
- searchParams[method]();
- hasThrown = 1;
- } catch (err) {
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 2);
- }
- );
-
- methodRequireTwoParams.forEach(
- (method: string): void => {
- const searchParams = new URLSearchParams();
- let hasThrown = 0;
- try {
- searchParams[method]("foo");
- hasThrown = 1;
- } catch (err) {
- if (err instanceof TypeError) {
- hasThrown = 2;
- } else {
- hasThrown = 3;
- }
- }
- assertEquals(hasThrown, 2);
- }
- );
-});
-
-// ref: https://github.com/web-platform-tests/wpt/blob/master/url/urlsearchparams-delete.any.js
-test(function urlSearchParamsDeletingAppendedMultiple(): void {
- const params = new URLSearchParams();
- params.append("first", (1 as unknown) as string);
- assert(params.has("first"));
- assertEquals(params.get("first"), "1");
- params.delete("first");
- assertEquals(params.has("first"), false);
- params.append("first", (1 as unknown) as string);
- params.append("first", (10 as unknown) as string);
- params.delete("first");
- assertEquals(params.has("first"), false);
-});
-
-// ref: https://github.com/web-platform-tests/wpt/blob/master/url/urlsearchparams-constructor.any.js#L176-L182
-test(function urlSearchParamsCustomSymbolIterator(): void {
- const params = new URLSearchParams();
- params[Symbol.iterator] = function*(): IterableIterator<[string, string]> {
- yield ["a", "b"];
- };
- const params1 = new URLSearchParams((params as unknown) as string[][]);
- assertEquals(params1.get("a"), "b");
-});
-
-test(function urlSearchParamsCustomSymbolIteratorWithNonStringParams(): void {
- const params = {};
- params[Symbol.iterator] = function*(): IterableIterator<[number, number]> {
- yield [1, 2];
- };
- const params1 = new URLSearchParams((params as unknown) as string[][]);
- assertEquals(params1.get("1"), "2");
-});
diff --git a/js/url_test.ts b/js/url_test.ts
deleted file mode 100644
index 07a8028ce..000000000
--- a/js/url_test.ts
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { test, assert, assertEquals } from "./test_util.ts";
-
-test(function urlParsing(): void {
- const url = new URL(
- "https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
- );
- assertEquals(url.hash, "#qat");
- assertEquals(url.host, "baz.qat:8000");
- assertEquals(url.hostname, "baz.qat");
- assertEquals(
- url.href,
- "https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
- );
- assertEquals(url.origin, "https://baz.qat:8000");
- assertEquals(url.password, "bar");
- assertEquals(url.pathname, "/qux/quux");
- assertEquals(url.port, "8000");
- assertEquals(url.protocol, "https:");
- assertEquals(url.search, "?foo=bar&baz=12");
- assertEquals(url.searchParams.getAll("foo"), ["bar"]);
- assertEquals(url.searchParams.getAll("baz"), ["12"]);
- assertEquals(url.username, "foo");
- assertEquals(
- String(url),
- "https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
- );
- assertEquals(
- JSON.stringify({ key: url }),
- `{"key":"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"}`
- );
-});
-
-test(function urlModifications(): void {
- const url = new URL(
- "https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
- );
- url.hash = "";
- assertEquals(
- url.href,
- "https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12"
- );
- url.host = "qat.baz:8080";
- assertEquals(
- url.href,
- "https://foo:bar@qat.baz:8080/qux/quux?foo=bar&baz=12"
- );
- url.hostname = "foo.bar";
- assertEquals(
- url.href,
- "https://foo:bar@foo.bar:8080/qux/quux?foo=bar&baz=12"
- );
- url.password = "qux";
- assertEquals(
- url.href,
- "https://foo:qux@foo.bar:8080/qux/quux?foo=bar&baz=12"
- );
- url.pathname = "/foo/bar%qat";
- assertEquals(
- url.href,
- "https://foo:qux@foo.bar:8080/foo/bar%qat?foo=bar&baz=12"
- );
- url.port = "";
- assertEquals(url.href, "https://foo:qux@foo.bar/foo/bar%qat?foo=bar&baz=12");
- url.protocol = "http:";
- assertEquals(url.href, "http://foo:qux@foo.bar/foo/bar%qat?foo=bar&baz=12");
- url.search = "?foo=bar&foo=baz";
- assertEquals(url.href, "http://foo:qux@foo.bar/foo/bar%qat?foo=bar&foo=baz");
- assertEquals(url.searchParams.getAll("foo"), ["bar", "baz"]);
- url.username = "foo@bar";
- assertEquals(
- url.href,
- "http://foo%40bar:qux@foo.bar/foo/bar%qat?foo=bar&foo=baz"
- );
- url.searchParams.set("bar", "qat");
- assertEquals(
- url.href,
- "http://foo%40bar:qux@foo.bar/foo/bar%qat?foo=bar&foo=baz&bar=qat"
- );
- url.searchParams.delete("foo");
- assertEquals(url.href, "http://foo%40bar:qux@foo.bar/foo/bar%qat?bar=qat");
- url.searchParams.append("foo", "bar");
- assertEquals(
- url.href,
- "http://foo%40bar:qux@foo.bar/foo/bar%qat?bar=qat&foo=bar"
- );
-});
-
-test(function urlModifyHref(): void {
- const url = new URL("http://example.com/");
- url.href = "https://foo:bar@example.com:8080/baz/qat#qux";
- assertEquals(url.protocol, "https:");
- assertEquals(url.username, "foo");
- assertEquals(url.password, "bar");
- assertEquals(url.host, "example.com:8080");
- assertEquals(url.hostname, "example.com");
- assertEquals(url.pathname, "/baz/qat");
- assertEquals(url.hash, "#qux");
-});
-
-test(function urlModifyPathname(): void {
- const url = new URL("http://foo.bar/baz%qat/qux%quux");
- assertEquals(url.pathname, "/baz%qat/qux%quux");
- url.pathname = url.pathname;
- assertEquals(url.pathname, "/baz%qat/qux%quux");
- url.pathname = "baz#qat qux";
- assertEquals(url.pathname, "/baz%23qat%20qux");
- url.pathname = url.pathname;
- assertEquals(url.pathname, "/baz%23qat%20qux");
-});
-
-test(function urlModifyHash(): void {
- const url = new URL("http://foo.bar");
- url.hash = "%foo bar/qat%qux#bar";
- assertEquals(url.hash, "#%foo%20bar/qat%qux#bar");
- url.hash = url.hash;
- assertEquals(url.hash, "#%foo%20bar/qat%qux#bar");
-});
-
-test(function urlSearchParamsReuse(): void {
- const url = new URL(
- "https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
- );
- const sp = url.searchParams;
- url.host = "baz.qat";
- assert(sp === url.searchParams, "Search params should be reused.");
-});
-
-test(function urlBaseURL(): void {
- const base = new URL(
- "https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
- );
- const url = new URL("/foo/bar?baz=foo#qux", base);
- assertEquals(url.href, "https://foo:bar@baz.qat:8000/foo/bar?baz=foo#qux");
-});
-
-test(function urlBaseString(): void {
- const url = new URL(
- "/foo/bar?baz=foo#qux",
- "https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
- );
- assertEquals(url.href, "https://foo:bar@baz.qat:8000/foo/bar?baz=foo#qux");
-});
-
-test(function urlRelativeWithBase(): void {
- assertEquals(new URL("", "file:///a/a/a").href, "file:///a/a/a");
- assertEquals(new URL(".", "file:///a/a/a").href, "file:///a/a/");
- assertEquals(new URL("..", "file:///a/a/a").href, "file:///a/");
- assertEquals(new URL("b", "file:///a/a/a").href, "file:///a/a/b");
- assertEquals(new URL("b", "file:///a/a/a/").href, "file:///a/a/a/b");
- assertEquals(new URL("b/", "file:///a/a/a").href, "file:///a/a/b/");
- assertEquals(new URL("../b", "file:///a/a/a").href, "file:///a/b");
-});
-
-test(function emptyBasePath(): void {
- assertEquals(new URL("", "http://example.com").href, "http://example.com/");
-});
-
-test(function deletingAllParamsRemovesQuestionMarkFromURL(): void {
- const url = new URL("http://example.com/?param1&param2");
- url.searchParams.delete("param1");
- url.searchParams.delete("param2");
- assertEquals(url.href, "http://example.com/");
- assertEquals(url.search, "");
-});
-
-test(function removingNonExistentParamRemovesQuestionMarkFromURL(): void {
- const url = new URL("http://example.com/?");
- assertEquals(url.href, "http://example.com/?");
- url.searchParams.delete("param1");
- assertEquals(url.href, "http://example.com/");
- assertEquals(url.search, "");
-});
-
-test(function sortingNonExistentParamRemovesQuestionMarkFromURL(): void {
- const url = new URL("http://example.com/?");
- assertEquals(url.href, "http://example.com/?");
- url.searchParams.sort();
- assertEquals(url.href, "http://example.com/");
- assertEquals(url.search, "");
-});
diff --git a/js/util.ts b/js/util.ts
deleted file mode 100644
index 013dc7ee1..000000000
--- a/js/util.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { TypedArray } from "./types.ts";
-import { window } from "./window.ts";
-
-let logDebug = false;
-let logSource = "JS";
-
-// @internal
-export function setLogDebug(debug: boolean, source?: string): void {
- logDebug = debug;
- if (source) {
- logSource = source;
- }
-}
-
-/** Debug logging for deno.
- * Enable with the `--log-debug` or `-D` command line flag.
- * @internal
- */
-export function log(...args: unknown[]): void {
- if (logDebug) {
- // if we destructure `console` off `window` too early, we don't bind to
- // the right console, therefore we don't log anything out.
- window.console.log(`DEBUG ${logSource} -`, ...args);
- }
-}
-
-// @internal
-export function assert(cond: boolean, msg = "assert"): void {
- if (!cond) {
- throw Error(msg);
- }
-}
-
-// @internal
-export function typedArrayToArrayBuffer(ta: TypedArray): ArrayBuffer {
- const ab = ta.buffer.slice(ta.byteOffset, ta.byteOffset + ta.byteLength);
- return ab as ArrayBuffer;
-}
-
-// @internal
-export function arrayToStr(ui8: Uint8Array): string {
- return String.fromCharCode(...ui8);
-}
-
-/** A `Resolvable` is a Promise with the `reject` and `resolve` functions
- * placed as methods on the promise object itself. It allows you to do:
- *
- * const p = createResolvable<number>();
- * // ...
- * p.resolve(42);
- *
- * It'd be prettier to make `Resolvable` a class that inherits from `Promise`,
- * rather than an interface. This is possible in ES2016, however typescript
- * produces broken code when targeting ES5 code.
- *
- * At the time of writing, the GitHub issue is closed in favour of a proposed
- * solution that is awaiting feedback.
- *
- * @see https://github.com/Microsoft/TypeScript/issues/15202
- * @see https://github.com/Microsoft/TypeScript/issues/15397
- * @internal
- */
-
-export interface ResolvableMethods<T> {
- resolve: (value?: T | PromiseLike<T>) => void;
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- reject: (reason?: any) => void;
-}
-
-// @internal
-export type Resolvable<T> = Promise<T> & ResolvableMethods<T>;
-
-// @internal
-export function createResolvable<T>(): Resolvable<T> {
- let methods: ResolvableMethods<T>;
- const promise = new Promise<T>(
- (resolve, reject): void => {
- methods = { resolve, reject };
- }
- );
- // TypeScript doesn't know that the Promise callback occurs synchronously
- // therefore use of not null assertion (`!`)
- return Object.assign(promise, methods!) as Resolvable<T>;
-}
-
-// @internal
-export function notImplemented(): never {
- throw new Error("Not implemented");
-}
-
-// @internal
-export function unreachable(): never {
- throw new Error("Code not reachable");
-}
-
-// @internal
-export function hexdump(u8: Uint8Array): string {
- return Array.prototype.map
- .call(
- u8,
- (x: number): string => {
- return ("00" + x.toString(16)).slice(-2);
- }
- )
- .join(" ");
-}
-
-// @internal
-export function containsOnlyASCII(str: string): boolean {
- if (typeof str !== "string") {
- return false;
- }
- return /^[\x00-\x7F]*$/.test(str);
-}
-
-const TypedArrayConstructor = Object.getPrototypeOf(Uint8Array);
-export function isTypedArray(x: unknown): x is TypedArray {
- return x instanceof TypedArrayConstructor;
-}
-
-// Returns whether o is an object, not null, and not a function.
-// @internal
-export function isObject(o: unknown): o is object {
- return o != null && typeof o === "object";
-}
-
-// Returns whether o is iterable.
-export function isIterable<T, P extends keyof T, K extends T[P]>(
- o: T
-): o is T & Iterable<[P, K]> {
- // checks for null and undefined
- if (o == null) {
- return false;
- }
- return (
- typeof ((o as unknown) as Iterable<[P, K]>)[Symbol.iterator] === "function"
- );
-}
-
-// @internal
-export function requiredArguments(
- name: string,
- length: number,
- required: number
-): void {
- if (length < required) {
- const errMsg = `${name} requires at least ${required} argument${
- required === 1 ? "" : "s"
- }, but only ${length} present`;
- throw new TypeError(errMsg);
- }
-}
-
-// @internal
-export function immutableDefine(
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- o: any,
- p: string | number | symbol,
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- value: any
-): void {
- Object.defineProperty(o, p, {
- value,
- configurable: false,
- writable: false
- });
-}
-
-// Returns values from a WeakMap to emulate private properties in JavaScript
-export function getPrivateValue<
- K extends object,
- V extends object,
- W extends keyof V
->(instance: K, weakMap: WeakMap<K, V>, key: W): V[W] {
- if (weakMap.has(instance)) {
- return weakMap.get(instance)![key];
- }
- throw new TypeError("Illegal invocation");
-}
-
-/**
- * Determines whether an object has a property with the specified name.
- * Avoid calling prototype builtin `hasOwnProperty` for two reasons:
- *
- * 1. `hasOwnProperty` is defined on the object as something else:
- *
- * const options = {
- * ending: 'utf8',
- * hasOwnProperty: 'foo'
- * };
- * options.hasOwnProperty('ending') // throws a TypeError
- *
- * 2. The object doesn't inherit from `Object.prototype`:
- *
- * const options = Object.create(null);
- * options.ending = 'utf8';
- * options.hasOwnProperty('ending'); // throws a TypeError
- *
- * @param obj A Object.
- * @param v A property name.
- * @see https://eslint.org/docs/rules/no-prototype-builtins
- * @internal
- */
-export function hasOwnProperty<T>(obj: T, v: PropertyKey): boolean {
- if (obj == null) {
- return false;
- }
- return Object.prototype.hasOwnProperty.call(obj, v);
-}
-
-/**
- * Split a number into two parts: lower 32 bit and higher 32 bit
- * (as if the number is represented as uint64.)
- *
- * @param n Number to split.
- * @internal
- */
-export function splitNumberToParts(n: number): number[] {
- // JS bitwise operators (OR, SHIFT) operate as if number is uint32.
- const lower = n | 0;
- // This is also faster than Math.floor(n / 0x100000000) in V8.
- const higher = (n - lower) / 0x100000000;
- return [lower, higher];
-}
diff --git a/js/utime.ts b/js/utime.ts
deleted file mode 100644
index 7495378b1..000000000
--- a/js/utime.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import { OP_UTIME } from "./dispatch.ts";
-
-function toSecondsFromEpoch(v: number | Date): number {
- return v instanceof Date ? v.valueOf() / 1000 : v;
-}
-
-/** 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 {
- sendSync(OP_UTIME, {
- filename,
- // TODO(ry) split atime, mtime into [seconds, nanoseconds] tuple
- atime: toSecondsFromEpoch(atime),
- mtime: toSecondsFromEpoch(mtime)
- });
-}
-
-/** 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 async function utime(
- filename: string,
- atime: number | Date,
- mtime: number | Date
-): Promise<void> {
- await sendAsync(OP_UTIME, {
- filename,
- // TODO(ry) split atime, mtime into [seconds, nanoseconds] tuple
- atime: toSecondsFromEpoch(atime),
- mtime: toSecondsFromEpoch(mtime)
- });
-}
diff --git a/js/utime_test.ts b/js/utime_test.ts
deleted file mode 100644
index 535ee1f40..000000000
--- a/js/utime_test.ts
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-// Allow 10 second difference.
-// Note this might not be enough for FAT (but we are not testing on such fs).
-function assertFuzzyTimestampEquals(t1: number, t2: number): void {
- assert(Math.abs(t1 - t2) < 10);
-}
-
-testPerm({ read: true, write: true }, function utimeSyncFileSuccess(): void {
- const testDir = Deno.makeTempDirSync();
- const filename = testDir + "/file.txt";
- Deno.writeFileSync(filename, new TextEncoder().encode("hello"), {
- perm: 0o666
- });
-
- const atime = 1000;
- const mtime = 50000;
- Deno.utimeSync(filename, atime, mtime);
-
- const fileInfo = Deno.statSync(filename);
- assertFuzzyTimestampEquals(fileInfo.accessed, atime);
- assertFuzzyTimestampEquals(fileInfo.modified, mtime);
-});
-
-testPerm(
- { read: true, write: true },
- function utimeSyncDirectorySuccess(): void {
- const testDir = Deno.makeTempDirSync();
-
- const atime = 1000;
- const mtime = 50000;
- Deno.utimeSync(testDir, atime, mtime);
-
- const dirInfo = Deno.statSync(testDir);
- assertFuzzyTimestampEquals(dirInfo.accessed, atime);
- assertFuzzyTimestampEquals(dirInfo.modified, mtime);
- }
-);
-
-testPerm({ read: true, write: true }, function utimeSyncDateSuccess(): void {
- const testDir = Deno.makeTempDirSync();
-
- const atime = 1000;
- const mtime = 50000;
- Deno.utimeSync(testDir, new Date(atime * 1000), new Date(mtime * 1000));
-
- const dirInfo = Deno.statSync(testDir);
- assertFuzzyTimestampEquals(dirInfo.accessed, atime);
- assertFuzzyTimestampEquals(dirInfo.modified, mtime);
-});
-
-testPerm(
- { read: true, write: true },
- function utimeSyncLargeNumberSuccess(): void {
- const testDir = Deno.makeTempDirSync();
-
- // There are Rust side caps (might be fs relate),
- // so JUST make them slightly larger than UINT32_MAX.
- const atime = 0x100000001;
- const mtime = 0x100000002;
- Deno.utimeSync(testDir, atime, mtime);
-
- const dirInfo = Deno.statSync(testDir);
- assertFuzzyTimestampEquals(dirInfo.accessed, atime);
- assertFuzzyTimestampEquals(dirInfo.modified, mtime);
- }
-);
-
-testPerm({ read: true, write: true }, function utimeSyncNotFound(): void {
- const atime = 1000;
- const mtime = 50000;
-
- let caughtError = false;
- try {
- Deno.utimeSync("/baddir", atime, mtime);
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- assertEquals(e.name, "NotFound");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true, write: false }, function utimeSyncPerm(): void {
- const atime = 1000;
- const mtime = 50000;
-
- let caughtError = false;
- try {
- Deno.utimeSync("/some_dir", atime, mtime);
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm(
- { read: true, write: true },
- async function utimeFileSuccess(): Promise<void> {
- const testDir = Deno.makeTempDirSync();
- const filename = testDir + "/file.txt";
- Deno.writeFileSync(filename, new TextEncoder().encode("hello"), {
- perm: 0o666
- });
-
- const atime = 1000;
- const mtime = 50000;
- await Deno.utime(filename, atime, mtime);
-
- const fileInfo = Deno.statSync(filename);
- assertFuzzyTimestampEquals(fileInfo.accessed, atime);
- assertFuzzyTimestampEquals(fileInfo.modified, mtime);
- }
-);
-
-testPerm(
- { read: true, write: true },
- async function utimeDirectorySuccess(): Promise<void> {
- const testDir = Deno.makeTempDirSync();
-
- const atime = 1000;
- const mtime = 50000;
- await Deno.utime(testDir, atime, mtime);
-
- const dirInfo = Deno.statSync(testDir);
- assertFuzzyTimestampEquals(dirInfo.accessed, atime);
- assertFuzzyTimestampEquals(dirInfo.modified, mtime);
- }
-);
-
-testPerm(
- { read: true, write: true },
- async function utimeDateSuccess(): Promise<void> {
- const testDir = Deno.makeTempDirSync();
-
- const atime = 1000;
- const mtime = 50000;
- await Deno.utime(testDir, new Date(atime * 1000), new Date(mtime * 1000));
-
- const dirInfo = Deno.statSync(testDir);
- assertFuzzyTimestampEquals(dirInfo.accessed, atime);
- assertFuzzyTimestampEquals(dirInfo.modified, mtime);
- }
-);
-
-testPerm({ read: true, write: true }, async function utimeNotFound(): Promise<
- void
-> {
- const atime = 1000;
- const mtime = 50000;
-
- let caughtError = false;
- try {
- await Deno.utime("/baddir", atime, mtime);
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- assertEquals(e.name, "NotFound");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true, write: false }, async function utimeSyncPerm(): Promise<
- void
-> {
- const atime = 1000;
- const mtime = 50000;
-
- let caughtError = false;
- try {
- await Deno.utime("/some_dir", atime, mtime);
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
diff --git a/js/version.ts b/js/version.ts
deleted file mode 100644
index 08ac58122..000000000
--- a/js/version.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-interface Version {
- deno: string;
- v8: string;
- typescript: string;
-}
-
-export const version: Version = {
- deno: "",
- v8: "",
- typescript: ""
-};
-
-/**
- * Sets the deno, v8, and typescript versions and freezes the version object.
- * @internal
- */
-export function setVersions(
- denoVersion: string,
- v8Version: string,
- tsVersion: string
-): void {
- version.deno = denoVersion;
- version.v8 = v8Version;
- version.typescript = tsVersion;
-
- Object.freeze(version);
-}
diff --git a/js/version_test.ts b/js/version_test.ts
deleted file mode 100644
index b32230812..000000000
--- a/js/version_test.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { test, assert } from "./test_util.ts";
-
-test(function version(): void {
- const pattern = /^\d+\.\d+\.\d+/;
- assert(pattern.test(Deno.version.deno));
- assert(pattern.test(Deno.version.v8));
- assert(pattern.test(Deno.version.typescript));
-});
diff --git a/js/window.ts b/js/window.ts
deleted file mode 100644
index 3d3d6601f..000000000
--- a/js/window.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-// (0, eval) is indirect eval.
-// See the links below for details:
-// - https://stackoverflow.com/a/14120023
-// - https://tc39.github.io/ecma262/#sec-performeval (spec)
-export const window = (0, eval)("this");
-// TODO: The above should be replaced with globalThis
-// when the globalThis proposal goes to stage 4
-// See https://github.com/tc39/proposal-global
diff --git a/js/workers.ts b/js/workers.ts
deleted file mode 100644
index 281fe619f..000000000
--- a/js/workers.ts
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import * as dispatch from "./dispatch.ts";
-import { sendAsync, sendSync } from "./dispatch_json.ts";
-import { log } from "./util.ts";
-import { TextDecoder, TextEncoder } from "./text_encoding.ts";
-import { window } from "./window.ts";
-import { blobURLMap } from "./url.ts";
-import { blobBytesWeakMap } from "./blob.ts";
-
-const encoder = new TextEncoder();
-const decoder = new TextDecoder();
-
-export function encodeMessage(data: any): Uint8Array {
- const dataJson = JSON.stringify(data);
- return encoder.encode(dataJson);
-}
-
-export function decodeMessage(dataIntArray: Uint8Array): any {
- const dataJson = decoder.decode(dataIntArray);
- return JSON.parse(dataJson);
-}
-
-function createWorker(
- specifier: string,
- includeDenoNamespace: boolean,
- hasSourceCode: boolean,
- sourceCode: Uint8Array
-): number {
- return sendSync(dispatch.OP_CREATE_WORKER, {
- specifier,
- includeDenoNamespace,
- hasSourceCode,
- sourceCode: new TextDecoder().decode(sourceCode)
- });
-}
-
-async function hostGetWorkerClosed(rid: number): Promise<void> {
- await sendAsync(dispatch.OP_HOST_GET_WORKER_CLOSED, { rid });
-}
-
-function hostPostMessage(rid: number, data: any): void {
- const dataIntArray = encodeMessage(data);
- sendSync(dispatch.OP_HOST_POST_MESSAGE, { rid }, dataIntArray);
-}
-
-async function hostGetMessage(rid: number): Promise<any> {
- const res = await sendAsync(dispatch.OP_HOST_GET_MESSAGE, { rid });
-
- if (res.data != null) {
- return decodeMessage(new Uint8Array(res.data));
- } else {
- return null;
- }
-}
-
-// Stuff for workers
-export const onmessage: (e: { data: any }) => void = (): void => {};
-
-export function postMessage(data: any): void {
- const dataIntArray = encodeMessage(data);
- sendSync(dispatch.OP_WORKER_POST_MESSAGE, {}, dataIntArray);
-}
-
-export async function getMessage(): Promise<any> {
- log("getMessage");
- const res = await sendAsync(dispatch.OP_WORKER_GET_MESSAGE);
-
- if (res.data != null) {
- return decodeMessage(new Uint8Array(res.data));
- } else {
- return null;
- }
-}
-
-export let isClosing = false;
-
-export function workerClose(): void {
- isClosing = true;
-}
-
-export async function workerMain(): Promise<void> {
- log("workerMain");
-
- while (!isClosing) {
- const data = await getMessage();
- if (data == null) {
- log("workerMain got null message. quitting.");
- break;
- }
-
- if (window["onmessage"]) {
- const event = { data };
- const result: void | Promise<void> = window.onmessage(event);
- if (result && "then" in result) {
- await result;
- }
- }
-
- if (!window["onmessage"]) {
- break;
- }
- }
-}
-
-export interface Worker {
- onerror?: () => void;
- onmessage?: (e: { data: any }) => void;
- onmessageerror?: () => void;
- postMessage(data: any): void;
- closed: Promise<void>;
-}
-
-// TODO(kevinkassimo): Maybe implement reasonable web worker options?
-// eslint-disable-next-line @typescript-eslint/no-empty-interface
-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: number;
- private isClosing = false;
- private readonly isClosedPromise: Promise<void>;
- public onerror?: () => void;
- public onmessage?: (data: any) => void;
- public onmessageerror?: () => void;
-
- constructor(specifier: string, options?: DenoWorkerOptions) {
- let hasSourceCode = false;
- let sourceCode = new Uint8Array();
-
- let includeDenoNamespace = true;
- if (options && options.noDenoNamespace) {
- includeDenoNamespace = false;
- }
- // Handle blob URL.
- if (specifier.startsWith("blob:")) {
- hasSourceCode = true;
- const b = blobURLMap.get(specifier);
- if (!b) {
- throw new Error("No Blob associated with the given URL is found");
- }
- const blobBytes = blobBytesWeakMap.get(b!);
- if (!blobBytes) {
- throw new Error("Invalid Blob");
- }
- sourceCode = blobBytes!;
- }
-
- this.rid = createWorker(
- specifier,
- includeDenoNamespace,
- hasSourceCode,
- sourceCode
- );
- this.run();
- this.isClosedPromise = hostGetWorkerClosed(this.rid);
- this.isClosedPromise.then(
- (): void => {
- this.isClosing = true;
- }
- );
- }
-
- get closed(): Promise<void> {
- return this.isClosedPromise;
- }
-
- postMessage(data: any): void {
- hostPostMessage(this.rid, data);
- }
-
- private async run(): Promise<void> {
- while (!this.isClosing) {
- const data = await hostGetMessage(this.rid);
- if (data == null) {
- log("worker got null message. quitting.");
- break;
- }
- // TODO(afinch7) stop this from eating messages before onmessage has been assigned
- if (this.onmessage) {
- const event = { data };
- this.onmessage(event);
- }
- }
- }
-}
diff --git a/js/write_file.ts b/js/write_file.ts
deleted file mode 100644
index d6307e002..000000000
--- a/js/write_file.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { stat, statSync } from "./stat.ts";
-import { open, openSync } from "./files.ts";
-import { chmod, chmodSync } from "./chmod.ts";
-import { writeAll, writeAllSync } from "./buffer.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 {
- if (options.create !== undefined) {
- const create = !!options.create;
- if (!create) {
- // verify that file exists
- statSync(filename);
- }
- }
-
- const openMode = !!options.append ? "a" : "w";
- const file = openSync(filename, openMode);
-
- if (options.perm !== undefined && options.perm !== null) {
- chmodSync(filename, options.perm);
- }
-
- writeAllSync(file, data);
- file.close();
-}
-
-/** 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 async function writeFile(
- filename: string,
- data: Uint8Array,
- options: WriteFileOptions = {}
-): Promise<void> {
- if (options.create !== undefined) {
- const create = !!options.create;
- if (!create) {
- // verify that file exists
- await stat(filename);
- }
- }
-
- const openMode = !!options.append ? "a" : "w";
- const file = await open(filename, openMode);
-
- if (options.perm !== undefined && options.perm !== null) {
- await chmod(filename, options.perm);
- }
-
- await writeAll(file, data);
- file.close();
-}
diff --git a/js/write_file_test.ts b/js/write_file_test.ts
deleted file mode 100644
index e1bbb67b3..000000000
--- a/js/write_file_test.ts
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { testPerm, assert, assertEquals } from "./test_util.ts";
-
-testPerm({ read: true, write: true }, function writeFileSyncSuccess(): void {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- Deno.writeFileSync(filename, data);
- const dataRead = Deno.readFileSync(filename);
- const dec = new TextDecoder("utf-8");
- const actual = dec.decode(dataRead);
- assertEquals("Hello", actual);
-});
-
-testPerm({ write: true }, function writeFileSyncFail(): void {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = "/baddir/test.txt";
- // The following should fail because /baddir doesn't exist (hopefully).
- let caughtError = false;
- try {
- Deno.writeFileSync(filename, data);
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- assertEquals(e.name, "NotFound");
- }
- assert(caughtError);
-});
-
-testPerm({ write: false }, function writeFileSyncPerm(): void {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = "/baddir/test.txt";
- // The following should fail due to no write permission
- let caughtError = false;
- try {
- Deno.writeFileSync(filename, data);
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm({ read: true, write: true }, function writeFileSyncUpdatePerm(): void {
- if (Deno.build.os !== "win") {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- Deno.writeFileSync(filename, data, { perm: 0o755 });
- assertEquals(Deno.statSync(filename).mode & 0o777, 0o755);
- Deno.writeFileSync(filename, data, { perm: 0o666 });
- assertEquals(Deno.statSync(filename).mode & 0o777, 0o666);
- }
-});
-
-testPerm({ read: true, write: true }, function writeFileSyncCreate(): void {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- let caughtError = false;
- // if create turned off, the file won't be created
- try {
- Deno.writeFileSync(filename, data, { create: false });
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- assertEquals(e.name, "NotFound");
- }
- assert(caughtError);
-
- // Turn on create, should have no error
- Deno.writeFileSync(filename, data, { create: true });
- Deno.writeFileSync(filename, data, { create: false });
- const dataRead = Deno.readFileSync(filename);
- const dec = new TextDecoder("utf-8");
- const actual = dec.decode(dataRead);
- assertEquals("Hello", actual);
-});
-
-testPerm({ read: true, write: true }, function writeFileSyncAppend(): void {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- Deno.writeFileSync(filename, data);
- Deno.writeFileSync(filename, data, { append: true });
- let dataRead = Deno.readFileSync(filename);
- const dec = new TextDecoder("utf-8");
- let actual = dec.decode(dataRead);
- assertEquals("HelloHello", actual);
- // Now attempt overwrite
- Deno.writeFileSync(filename, data, { append: false });
- dataRead = Deno.readFileSync(filename);
- actual = dec.decode(dataRead);
- assertEquals("Hello", actual);
- // append not set should also overwrite
- Deno.writeFileSync(filename, data);
- dataRead = Deno.readFileSync(filename);
- actual = dec.decode(dataRead);
- assertEquals("Hello", actual);
-});
-
-testPerm(
- { read: true, write: true },
- async function writeFileSuccess(): Promise<void> {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- await Deno.writeFile(filename, data);
- const dataRead = Deno.readFileSync(filename);
- const dec = new TextDecoder("utf-8");
- const actual = dec.decode(dataRead);
- assertEquals("Hello", actual);
- }
-);
-
-testPerm(
- { read: true, write: true },
- async function writeFileNotFound(): Promise<void> {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = "/baddir/test.txt";
- // The following should fail because /baddir doesn't exist (hopefully).
- let caughtError = false;
- try {
- await Deno.writeFile(filename, data);
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- assertEquals(e.name, "NotFound");
- }
- assert(caughtError);
- }
-);
-
-testPerm({ read: true, write: false }, async function writeFilePerm(): Promise<
- void
-> {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = "/baddir/test.txt";
- // The following should fail due to no write permission
- let caughtError = false;
- try {
- await Deno.writeFile(filename, data);
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
- assertEquals(e.name, "PermissionDenied");
- }
- assert(caughtError);
-});
-
-testPerm(
- { read: true, write: true },
- async function writeFileUpdatePerm(): Promise<void> {
- if (Deno.build.os !== "win") {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- await Deno.writeFile(filename, data, { perm: 0o755 });
- assertEquals(Deno.statSync(filename).mode & 0o777, 0o755);
- await Deno.writeFile(filename, data, { perm: 0o666 });
- assertEquals(Deno.statSync(filename).mode & 0o777, 0o666);
- }
- }
-);
-
-testPerm({ read: true, write: true }, async function writeFileCreate(): Promise<
- void
-> {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- let caughtError = false;
- // if create turned off, the file won't be created
- try {
- await Deno.writeFile(filename, data, { create: false });
- } catch (e) {
- caughtError = true;
- assertEquals(e.kind, Deno.ErrorKind.NotFound);
- assertEquals(e.name, "NotFound");
- }
- assert(caughtError);
-
- // Turn on create, should have no error
- await Deno.writeFile(filename, data, { create: true });
- await Deno.writeFile(filename, data, { create: false });
- const dataRead = Deno.readFileSync(filename);
- const dec = new TextDecoder("utf-8");
- const actual = dec.decode(dataRead);
- assertEquals("Hello", actual);
-});
-
-testPerm({ read: true, write: true }, async function writeFileAppend(): Promise<
- void
-> {
- const enc = new TextEncoder();
- const data = enc.encode("Hello");
- const filename = Deno.makeTempDirSync() + "/test.txt";
- await Deno.writeFile(filename, data);
- await Deno.writeFile(filename, data, { append: true });
- let dataRead = Deno.readFileSync(filename);
- const dec = new TextDecoder("utf-8");
- let actual = dec.decode(dataRead);
- assertEquals("HelloHello", actual);
- // Now attempt overwrite
- await Deno.writeFile(filename, data, { append: false });
- dataRead = Deno.readFileSync(filename);
- actual = dec.decode(dataRead);
- assertEquals("Hello", actual);
- // append not set should also overwrite
- await Deno.writeFile(filename, data);
- dataRead = Deno.readFileSync(filename);
- actual = dec.decode(dataRead);
- assertEquals("Hello", actual);
-});