Skip to content

Commit

Permalink
feat: Add --location and globalThis.location
Browse files Browse the repository at this point in the history
  • Loading branch information
nayeemrmn committed Oct 17, 2020
1 parent c1c7601 commit 9bab164
Show file tree
Hide file tree
Showing 30 changed files with 763 additions and 214 deletions.
356 changes: 187 additions & 169 deletions cli/flags.rs

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions cli/installer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ pub fn install(

let mut executable_args = vec!["run".to_string()];
executable_args.extend_from_slice(&flags.to_permission_args());
if let Some(url) = flags.location.as_ref() {
executable_args.push("--location".to_string());
executable_args.push(url.to_string());
}
if let Some(ca_file) = flags.ca_file {
executable_args.push("--cert".to_string());
executable_args.push(ca_file)
Expand Down
25 changes: 18 additions & 7 deletions cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,12 +645,28 @@ async fn test_command(
Ok(())
}

fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T {
match result {
Ok(value) => value,
Err(error) => {
let msg = format!(
"{}: {}",
colors::red_bold("error"),
error.to_string().trim()
);
eprintln!("{}", msg);
std::process::exit(1);
}
}
}

pub fn main() {
#[cfg(windows)]
colors::enable_ansi(); // For Windows 10

let args: Vec<String> = env::args().collect();
let flags = flags::flags_from_vec(args);
let flags =
unwrap_or_exit(flags::flags_from_vec(args).map_err(AnyError::from));

if let Some(ref v8_flags) = flags.v8_flags {
let v8_flags_includes_help = v8_flags
Expand Down Expand Up @@ -786,10 +802,5 @@ pub fn main() {
}
};

let result = tokio_util::run_basic(fut);
if let Err(err) = result {
let msg = format!("{}: {}", colors::red_bold("error"), err.to_string(),);
eprintln!("{}", msg);
std::process::exit(1);
}
unwrap_or_exit(tokio_util::run_basic(fut));
}
1 change: 1 addition & 0 deletions cli/ops/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ fn op_start(
"cwd": &env::current_dir().unwrap(),
"debugFlag": gs.flags.log_level.map_or(false, |l| l == log::Level::Debug),
"denoVersion": version::DENO,
"location": gs.flags.location.as_ref().map(|url| url.as_str()),
"noColor": !colors::use_color(),
"pid": std::process::id(),
"ppid": ppid(),
Expand Down
15 changes: 9 additions & 6 deletions cli/ops/worker_host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn create_web_worker(
let mut worker = WebWorker::new(
name.clone(),
permissions,
specifier,
specifier.clone(),
program_state.clone(),
has_deno_namespace,
);
Expand All @@ -79,8 +79,8 @@ fn create_web_worker(
// Instead of using name for log we use `worker-${id}` because
// WebWorkers can have empty string as name.
let script = format!(
"bootstrap.workerRuntime(\"{}\", {}, \"worker-{}\")",
name, worker.has_deno_namespace, worker_id
"bootstrap.workerRuntime(\"{}\", \"{}\", {}, \"worker-{}\")",
name, specifier, worker.has_deno_namespace, worker_id
);
worker.execute(&script)?;

Expand Down Expand Up @@ -198,6 +198,7 @@ fn op_create_worker(
args: Value,
_data: &mut [ZeroCopyBuf],
) -> Result<Value, AnyError> {
let program_state = super::program_state(state);
let args: CreateWorkerArgs = serde_json::from_value(args)?;

let specifier = args.specifier.clone();
Expand All @@ -215,14 +216,16 @@ fn op_create_worker(
let worker_id = state.take::<WorkerId>();
state.put::<WorkerId>(worker_id + 1);

let module_specifier = ModuleSpecifier::resolve_url(&specifier)?;
let module_specifier = match program_state.flags.location.as_ref() {
None => ModuleSpecifier::resolve_url(&specifier)?,
Some(url) => ModuleSpecifier::resolve_import(&specifier, url.as_str())?,
};
let worker_name = args_name.unwrap_or_else(|| "".to_string());
let cli_state = super::program_state(state);

let (join_handle, worker_handle) = run_worker_thread(
worker_id,
worker_name,
&cli_state,
&program_state,
permissions,
module_specifier,
use_deno_namespace,
Expand Down
23 changes: 20 additions & 3 deletions cli/rt/99_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ delete Object.prototype.__proto__;
const util = window.__bootstrap.util;
const { illegalConstructorKey } = window.__bootstrap.webUtil;
const eventTarget = window.__bootstrap.eventTarget;
const location = window.__bootstrap.location;
const dispatchMinimal = window.__bootstrap.dispatchMinimal;
const build = window.__bootstrap.build;
const version = window.__bootstrap.version;
Expand Down Expand Up @@ -230,6 +231,8 @@ delete Object.prototype.__proto__;

// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope
const windowOrWorkerGlobalScope = {
Location: location.locationConstructorDescriptor,
location: location.locationDescriptor,
Blob: util.nonEnumerable(fetch.Blob),
ByteLengthQueuingStrategy: util.nonEnumerable(
streams.ByteLengthQueuingStrategy,
Expand Down Expand Up @@ -333,8 +336,20 @@ delete Object.prototype.__proto__;
}
});

const { args, cwd, noColor, pid, ppid, unstableFlag } = runtimeStart();

const {
args,
cwd,
location: locationHref,
noColor,
pid,
ppid,
unstableFlag,
} = runtimeStart();

if (locationHref != null) {
location.setLocationHref(locationHref);
fetch.setBaseUrl(locationHref);
}
registerErrors();

const finalDenoNs = {
Expand Down Expand Up @@ -369,7 +384,7 @@ delete Object.prototype.__proto__;
util.log("args", args);
}

function bootstrapWorkerRuntime(name, useDenoNamespace, internalName) {
function bootstrapWorkerRuntime(name, url, useDenoNamespace, internalName) {
if (hasBootstrapped) {
throw new Error("Worker runtime already bootstrapped");
}
Expand All @@ -387,6 +402,8 @@ delete Object.prototype.__proto__;
internalName ?? name,
);

location.setLocationHref(url);
fetch.setBaseUrl(url);
registerErrors();

const finalDenoNs = {
Expand Down
2 changes: 2 additions & 0 deletions cli/rt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Some Web APIs are using ops under the hood, eg. `console`, `performance`.
[Body](https://developer.mozilla.org/en-US/docs/Web/API/Body) and
[Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers): modern
Promise-based HTTP Request API.
- [location](https://developer.mozilla.org/en-US/docs/Web/API/Window/location)
and [Location](https://developer.mozilla.org/en-US/docs/Web/API/Location).
- [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData): access
to a `multipart/form-data` serialization.
- [Performance](https://developer.mozilla.org/en-US/docs/Web/API/Performance):
Expand Down
8 changes: 8 additions & 0 deletions cli/tests/066_location.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
console.log(Location);
console.log(Location.prototype);
console.log(location);
try {
location.hostname = "bar";
} catch (error) {
console.log(error);
}
22 changes: 22 additions & 0 deletions cli/tests/066_location.ts.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[WILDCARD][Function: Location]
Location { [Symbol(Symbol.toStringTag)]: "Location" }
Location {
hash: [Getter/Setter],
host: [Getter/Setter],
hostname: [Getter/Setter],
href: [Getter/Setter],
origin: [Getter],
password: [Getter/Setter],
pathname: [Getter/Setter],
port: [Getter/Setter],
protocol: [Getter/Setter],
search: [Getter/Setter],
username: [Getter/Setter],
ancestorOrigins: [Getter],
assign: [Function: assign],
reload: [Function: reload],
replace: [Function: replace],
toString: [Function: toString]
}
NotSupportedError: Cannot set "location.hostname".
[WILDCARD]
3 changes: 3 additions & 0 deletions cli/tests/067_location_unset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
console.log(Location);
console.log(Location.prototype);
console.log(location);
4 changes: 4 additions & 0 deletions cli/tests/067_location_unset.ts.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[WILDCARD][Function: Location]
Location { [Symbol(Symbol.toStringTag)]: "Location" }
error: Uncaught ReferenceError: Access to "location", run again with --location <href>.
[WILDCARD]
2 changes: 2 additions & 0 deletions cli/tests/068_location_relative_fetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const response = await fetch("fetch/hello.txt");
console.log(await response.text());
2 changes: 2 additions & 0 deletions cli/tests/068_location_relative_fetch.ts.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[WILDCARD]Hello, world!

4 changes: 2 additions & 2 deletions cli/tests/complex_permissions_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ const test: { [key: string]: (...args: any[]) => void | Promise<void> } = {
Deno.writeFileSync(file, new Uint8Array(0), { append: true })
);
},
netFetch(hosts: string[]): void {
hosts.forEach((host) => fetch(host));
netFetch(urls: string[]): void {
urls.forEach((url) => fetch(url));
},
netListen(endpoints: string[]): void {
endpoints.forEach((endpoint) => {
Expand Down
1 change: 1 addition & 0 deletions cli/tests/fetch/hello.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello, world!
23 changes: 23 additions & 0 deletions cli/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1702,6 +1702,12 @@ fn workers() {
.current_dir(util::tests_path())
.arg("test")
.arg("--reload")
.arg("--location")
.arg(
url::Url::from_directory_path(util::tests_path())
.unwrap()
.as_str(),
)
.arg("--allow-net")
.arg("--allow-read")
.arg("--unstable")
Expand Down Expand Up @@ -1944,6 +1950,23 @@ fn _066_prompt() {
util::test_pty(args, output, input);
}

itest!(_066_location {
args: "run --location https://foo/bar?baz#bat 066_location.ts",
output: "066_location.ts.out",
});

itest!(_067_location_unset {
args: "run 067_location_unset.ts",
output: "067_location_unset.ts.out",
exit_code: 1,
});

itest!(_068_location_relative_fetch {
args: "run --location http://127.0.0.1:4545/cli/tests/ --allow-net 068_location_relative_fetch.ts",
output: "068_location_relative_fetch.ts.out",
http_server: true,
});

itest!(js_import_detect {
args: "run --quiet --reload js_import_detect.ts",
output: "js_import_detect.ts.out",
Expand Down
4 changes: 4 additions & 0 deletions cli/tests/subdir/worker_location.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
onmessage = function (): void {
postMessage(self.location.href);
close();
};
8 changes: 0 additions & 8 deletions cli/tests/unit/fetch_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,6 @@ unitTest({ perms: { net: true } }, async function responseClone(): Promise<
}
});

unitTest({ perms: { net: true } }, async function fetchEmptyInvalid(): Promise<
void
> {
await assertThrowsAsync(async () => {
await fetch("");
}, URIError);
});

unitTest(
{ perms: { net: true } },
async function fetchMultipartFormDataSuccess(): Promise<void> {
Expand Down
8 changes: 5 additions & 3 deletions cli/tests/unit/request_test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { assert, assertEquals, assertThrows, unitTest } from "./test_util.ts";
import { assert, assertEquals, unitTest } from "./test_util.ts";

unitTest(function fromInit(): void {
const req = new Request("http://foo/", {
Expand Down Expand Up @@ -42,8 +42,10 @@ unitTest(function requestNonString(): void {
});

unitTest(function requestRelativeUrl(): void {
// TODO(nayeemrmn): Base from `--location` when implemented and set.
assertThrows(() => new Request("relative-url"), TypeError, "Invalid URL.");
assertEquals(
new Request("relative-url").url,
"http://js-unit-tests/foo/relative-url",
);
});

unitTest(async function cloneRequestBodyStream(): Promise<void> {
Expand Down
1 change: 1 addition & 0 deletions cli/tests/unit/unit_test_runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ function spawnWorkerRunner(
Deno.execPath(),
"run",
"--unstable", // TODO(ry) be able to test stable vs unstable
"--location=http://js-unit-tests/foo/bar",
"-A",
"cli/tests/unit/unit_test_runner.ts",
"--worker",
Expand Down
36 changes: 36 additions & 0 deletions cli/tests/workers_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,39 @@ Deno.test({
w.terminate();
},
});

Deno.test({
name: "worker location",
fn: async function (): Promise<void> {
const promise = createResolvable();
const workerModuleHref =
new URL("subdir/worker_location.ts", import.meta.url).href;
const w = new Worker(workerModuleHref, { type: "module" });
w.onmessage = (e): void => {
assertEquals(e.data, workerModuleHref);
promise.resolve();
};
w.postMessage("Hello, world!");
await promise;
w.terminate();
},
});

Deno.test({
name: "worker with relative specifier",
fn: async function (): Promise<void> {
assertEquals(location.href, new URL(".", import.meta.url).href);
const promise = createResolvable();
const w = new Worker(
"./subdir/test_worker.ts",
{ type: "module", name: "tsWorker" },
);
w.onmessage = (e): void => {
assertEquals(e.data, "Hello, world!");
promise.resolve();
};
w.postMessage("Hello, world!");
await promise;
w.terminate();
},
});
2 changes: 1 addition & 1 deletion cli/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ mod tests {
false,
);
worker
.execute("bootstrap.workerRuntime(\"TEST\", false)")
.execute("bootstrap.workerRuntime(\"TEST\", \"https://foo\", false)")
.unwrap();
worker
}
Expand Down
Loading

0 comments on commit 9bab164

Please sign in to comment.