diff --git a/cli/js/lib.deno.ns.d.ts b/cli/js/lib.deno.ns.d.ts index c79007ebdd..972405680f 100644 --- a/cli/js/lib.deno.ns.d.ts +++ b/cli/js/lib.deno.ns.d.ts @@ -130,6 +130,16 @@ declare namespace Deno { * Requires `allow-env` permission. */ set(key: string, value: string): void; + /** Delete the value of an environment variable. + * + * ```ts + * Deno.env.set("SOME_VAR", "Value")); + * Deno.env.delete("SOME_VAR"); // outputs "Undefined" + * ``` + * + * Requires `allow-env` permission. */ + delete(key: string): void; + /** Returns a snapshot of the environment variables at invocation. * * ```ts diff --git a/cli/js/ops/os.ts b/cli/js/ops/os.ts index 30aa6d0d48..e63d8b3583 100644 --- a/cli/js/ops/os.ts +++ b/cli/js/ops/os.ts @@ -27,12 +27,17 @@ function getEnv(key: string): string | undefined { return sendSync("op_get_env", { key })[0]; } +function deleteEnv(key: string): void { + sendSync("op_delete_env", { key }); +} + export const env = { get: getEnv, toObject(): { [key: string]: string } { return sendSync("op_env"); }, set: setEnv, + delete: deleteEnv, }; type DirKind = diff --git a/cli/ops/os.rs b/cli/ops/os.rs index 36cd99577d..ab7ed28766 100644 --- a/cli/ops/os.rs +++ b/cli/ops/os.rs @@ -15,6 +15,7 @@ pub fn init(i: &mut CoreIsolate, s: &State) { i.register_op("op_exec_path", s.stateful_json_op(op_exec_path)); i.register_op("op_set_env", s.stateful_json_op(op_set_env)); i.register_op("op_get_env", s.stateful_json_op(op_get_env)); + i.register_op("op_delete_env", s.stateful_json_op(op_delete_env)); i.register_op("op_get_dir", s.stateful_json_op(op_get_dir)); i.register_op("op_hostname", s.stateful_json_op(op_hostname)); i.register_op("op_loadavg", s.stateful_json_op(op_loadavg)); @@ -137,6 +138,22 @@ fn op_get_env( Ok(JsonOp::Sync(r)) } +#[derive(Deserialize)] +struct DeleteEnv { + key: String, +} + +fn op_delete_env( + state: &State, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: DeleteEnv = serde_json::from_value(args)?; + state.check_env()?; + env::remove_var(args.key); + Ok(JsonOp::Sync(json!({}))) +} + #[derive(Deserialize)] struct Exit { code: i32, diff --git a/cli/tests/unit/os_test.ts b/cli/tests/unit/os_test.ts index 72c88b0e10..9698692c79 100644 --- a/cli/tests/unit/os_test.ts +++ b/cli/tests/unit/os_test.ts @@ -20,6 +20,13 @@ unitTest({ perms: { env: true } }, function envNotFound(): void { assertEquals(r, undefined); }); +unitTest({ perms: { env: true } }, function deleteEnv(): void { + Deno.env.set("TEST_VAR", "A"); + assertEquals(Deno.env.get("TEST_VAR"), "A"); + assertEquals(Deno.env.delete("TEST_VAR"), undefined); + assertEquals(Deno.env.get("TEST_VAR"), undefined); +}); + unitTest(function envPermissionDenied1(): void { let err; try {