summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/args/flags.rs57
-rw-r--r--cli/args/mod.rs20
-rw-r--r--cli/factory.rs6
-rw-r--r--cli/main.rs51
-rw-r--r--cli/tests/integration/check_tests.rs7
-rw-r--r--cli/tests/testdata/check/deno_unstable_not_found/deno.json3
-rw-r--r--cli/worker.rs26
-rw-r--r--ext/ffi/README.md2
-rw-r--r--runtime/js/90_deno_ns.js58
-rw-r--r--runtime/js/99_main.js52
-rw-r--r--runtime/ops/worker_host.rs2
-rw-r--r--runtime/worker_bootstrap.rs7
-rw-r--r--test_ffi/tests/integration_tests.rs2
13 files changed, 266 insertions, 27 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs
index dbc868efa..e558fe391 100644
--- a/cli/args/flags.rs
+++ b/cli/args/flags.rs
@@ -419,6 +419,7 @@ pub struct Flags {
pub unstable: bool,
pub unstable_bare_node_builtlins: bool,
pub unstable_byonm: bool,
+ pub unstable_features: Vec<String>,
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
pub v8_flags: Vec<String>,
}
@@ -814,6 +815,46 @@ pub fn flags_from_vec(args: Vec<String>) -> clap::error::Result<Flags> {
if matches.get_flag("unstable") {
flags.unstable = true;
}
+ if matches.get_flag("unstable-broadcast-channel") {
+ flags.unstable_features.push(
+ deno_runtime::deno_broadcast_channel::UNSTABLE_FEATURE_NAME.to_string(),
+ );
+ }
+ if matches.get_flag("unstable-ffi") {
+ flags
+ .unstable_features
+ .push(deno_runtime::deno_ffi::UNSTABLE_FEATURE_NAME.to_string());
+ }
+ if matches.get_flag("unstable-fs") {
+ flags
+ .unstable_features
+ .push(deno_runtime::deno_fs::UNSTABLE_FEATURE_NAME.to_string());
+ }
+ if matches.get_flag("unstable-http") {
+ flags
+ .unstable_features
+ .push(deno_runtime::ops::http::UNSTABLE_FEATURE_NAME.to_string());
+ }
+ if matches.get_flag("unstable-kv") {
+ flags
+ .unstable_features
+ .push(deno_runtime::deno_kv::UNSTABLE_FEATURE_NAME.to_string());
+ }
+ if matches.get_flag("unstable-net") {
+ flags
+ .unstable_features
+ .push(deno_runtime::deno_net::UNSTABLE_FEATURE_NAME.to_string());
+ }
+ if matches.get_flag("unstable-worker-options") {
+ flags
+ .unstable_features
+ .push(deno_runtime::ops::worker_host::UNSTABLE_FEATURE_NAME.to_string());
+ }
+ if matches.get_flag("unstable-cron") {
+ flags
+ .unstable_features
+ .push(deno_runtime::deno_cron::UNSTABLE_FEATURE_NAME.to_string());
+ }
flags.unstable_bare_node_builtlins =
matches.get_flag("unstable-bare-node-builtins");
@@ -901,7 +942,7 @@ fn clap_root() -> Command {
crate::version::TYPESCRIPT
);
- Command::new("deno")
+ let mut cmd = Command::new("deno")
.bin_name("deno")
.color(ColorChoice::Never)
.max_term_width(80)
@@ -931,7 +972,19 @@ fn clap_root() -> Command {
.value_parser(FalseyValueParser::new())
.action(ArgAction::SetTrue)
.global(true),
- )
+ );
+
+ for (flag_name, help, _) in crate::UNSTABLE_GRANULAR_FLAGS {
+ cmd = cmd.arg(
+ Arg::new(format!("unstable-{}", flag_name))
+ .long(format!("unstable-{}", flag_name))
+ .help(help)
+ .action(ArgAction::SetTrue)
+ .global(true),
+ );
+ }
+
+ cmd
.arg(
Arg::new("log-level")
.short('L')
diff --git a/cli/args/mod.rs b/cli/args/mod.rs
index 0778dee79..1d28df124 100644
--- a/cli/args/mod.rs
+++ b/cli/args/mod.rs
@@ -723,7 +723,14 @@ impl CliOptions {
}
pub fn ts_type_lib_window(&self) -> TsTypeLib {
- if self.flags.unstable {
+ if self.flags.unstable
+ || !self.flags.unstable_features.is_empty()
+ || self
+ .maybe_config_file
+ .as_ref()
+ .map(|f| !f.json.unstable.is_empty())
+ .unwrap_or(false)
+ {
TsTypeLib::UnstableDenoWindow
} else {
TsTypeLib::DenoWindow
@@ -1264,6 +1271,17 @@ impl CliOptions {
.unwrap_or(false)
}
+ pub fn unstable_features(&self) -> Vec<String> {
+ let mut from_config_file = self
+ .maybe_config_file()
+ .as_ref()
+ .map(|c| c.json.unstable.clone())
+ .unwrap_or_default();
+
+ from_config_file.extend_from_slice(&self.flags.unstable_features);
+ from_config_file
+ }
+
pub fn v8_flags(&self) -> &Vec<String> {
&self.flags.v8_flags
}
diff --git a/cli/factory.rs b/cli/factory.rs
index 389c4dbe0..06c9472fa 100644
--- a/cli/factory.rs
+++ b/cli/factory.rs
@@ -595,6 +595,12 @@ impl CliFactory {
if self.options.unstable() {
checker.enable_legacy_unstable();
}
+ let unstable_features = self.options.unstable_features();
+ for (flag_name, _, _) in crate::UNSTABLE_GRANULAR_FLAGS {
+ if unstable_features.contains(&flag_name.to_string()) {
+ checker.enable_feature(flag_name);
+ }
+ }
Arc::new(checker)
})
diff --git a/cli/main.rs b/cli/main.rs
index 7a8647a81..24b964169 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -256,6 +256,57 @@ fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T {
}
}
+// NOTE(bartlomieju): keep IDs in sync with `runtime/90_deno_ns.js`.
+pub(crate) static UNSTABLE_GRANULAR_FLAGS: &[(
+ // flag name
+ &str,
+ // help text
+ &str,
+ // id to enable it in runtime/99_main.js
+ i32,
+)] = &[
+ (
+ deno_runtime::deno_broadcast_channel::UNSTABLE_FEATURE_NAME,
+ "Enable unstable `BroadcastChannel` API",
+ 1,
+ ),
+ (
+ deno_runtime::deno_ffi::UNSTABLE_FEATURE_NAME,
+ "Enable unstable FFI APIs",
+ 2,
+ ),
+ (
+ deno_runtime::deno_fs::UNSTABLE_FEATURE_NAME,
+ "Enable unstable file system APIs",
+ 3,
+ ),
+ (
+ deno_runtime::deno_kv::UNSTABLE_FEATURE_NAME,
+ "Enable unstable Key-Value store APIs",
+ 4,
+ ),
+ (
+ deno_runtime::deno_net::UNSTABLE_FEATURE_NAME,
+ "Enable unstable net APIs",
+ 5,
+ ),
+ (
+ deno_runtime::ops::http::UNSTABLE_FEATURE_NAME,
+ "Enable unstable HTTP APIs",
+ 6,
+ ),
+ (
+ deno_runtime::ops::worker_host::UNSTABLE_FEATURE_NAME,
+ "Enable unstable Web Worker APIs",
+ 7,
+ ),
+ (
+ deno_runtime::deno_cron::UNSTABLE_FEATURE_NAME,
+ "Enable unstable Deno.cron API",
+ 8,
+ ),
+];
+
pub(crate) fn unstable_exit_cb(_feature: &str, api_name: &str) {
// TODO(bartlomieju): change to "The `--unstable-{feature}` flag must be provided.".
eprintln!("Unstable API '{api_name}'. The --unstable flag must be provided.");
diff --git a/cli/tests/integration/check_tests.rs b/cli/tests/integration/check_tests.rs
index ca80ffa94..029f89119 100644
--- a/cli/tests/integration/check_tests.rs
+++ b/cli/tests/integration/check_tests.rs
@@ -123,11 +123,16 @@ itest!(check_deno_not_found {
});
itest!(check_deno_unstable_not_found {
- args: "check --quiet check/deno_unstable_not_found/main.ts",
+ args: "check --quiet --no-config check/deno_unstable_not_found/main.ts",
output: "check/deno_unstable_not_found/main.out",
exit_code: 1,
});
+itest!(check_deno_unstable_from_config {
+ args: "check --quiet --config check/deno_unstable_not_found/deno.json check/deno_unstable_not_found/main.ts",
+ output_str: Some(""),
+});
+
#[test]
fn cache_switching_config_then_no_config() {
let context = TestContext::default();
diff --git a/cli/tests/testdata/check/deno_unstable_not_found/deno.json b/cli/tests/testdata/check/deno_unstable_not_found/deno.json
new file mode 100644
index 000000000..d7de05e18
--- /dev/null
+++ b/cli/tests/testdata/check/deno_unstable_not_found/deno.json
@@ -0,0 +1,3 @@
+{
+ "unstable": ["cron", "http", "kv"]
+}
diff --git a/cli/worker.rs b/cli/worker.rs
index 58bd96642..5022b39f1 100644
--- a/cli/worker.rs
+++ b/cli/worker.rs
@@ -529,6 +529,16 @@ impl CliMainWorkerFactory {
let mut extensions = ops::cli_exts(shared.npm_resolver.clone());
extensions.append(&mut custom_extensions);
+ // TODO(bartlomieju): this is cruft, update FeatureChecker to spit out
+ // list of enabled features.
+ let feature_checker = shared.feature_checker.clone();
+ let mut unstable_features = Vec::with_capacity(8);
+ for (feature_name, _, id) in crate::UNSTABLE_GRANULAR_FLAGS {
+ if feature_checker.check(feature_name) {
+ unstable_features.push(*id);
+ }
+ }
+
let options = WorkerOptions {
bootstrap: BootstrapOptions {
args: shared.options.argv.clone(),
@@ -544,6 +554,7 @@ impl CliMainWorkerFactory {
runtime_version: version::deno().to_string(),
ts_version: version::TYPESCRIPT.to_string(),
unstable: shared.options.unstable,
+ unstable_features,
user_agent: version::get_user_agent().to_string(),
inspect: shared.options.is_inspecting,
has_node_modules_dir: shared.options.has_node_modules_dir,
@@ -580,7 +591,7 @@ impl CliMainWorkerFactory {
shared.compiled_wasm_module_store.clone(),
),
stdio,
- feature_checker: shared.feature_checker.clone(),
+ feature_checker,
};
let worker = MainWorker::bootstrap_from_options(
@@ -704,6 +715,16 @@ fn create_web_worker_callback(
.join(checksum::gen(&[key.as_bytes()]))
});
+ // TODO(bartlomieju): this is cruft, update FeatureChecker to spit out
+ // list of enabled features.
+ let feature_checker = shared.feature_checker.clone();
+ let mut unstable_features = Vec::with_capacity(8);
+ for (feature_name, _, id) in crate::UNSTABLE_GRANULAR_FLAGS {
+ if feature_checker.check(feature_name) {
+ unstable_features.push(*id);
+ }
+ }
+
let options = WebWorkerOptions {
bootstrap: BootstrapOptions {
args: shared.options.argv.clone(),
@@ -719,6 +740,7 @@ fn create_web_worker_callback(
runtime_version: version::deno().to_string(),
ts_version: version::TYPESCRIPT.to_string(),
unstable: shared.options.unstable,
+ unstable_features,
user_agent: version::get_user_agent().to_string(),
inspect: shared.options.is_inspecting,
has_node_modules_dir: shared.options.has_node_modules_dir,
@@ -752,7 +774,7 @@ fn create_web_worker_callback(
),
stdio: stdio.clone(),
cache_storage_dir,
- feature_checker: shared.feature_checker.clone(),
+ feature_checker,
};
WebWorker::bootstrap_from_options(
diff --git a/ext/ffi/README.md b/ext/ffi/README.md
index 5f7f1cb9f..a821a3981 100644
--- a/ext/ffi/README.md
+++ b/ext/ffi/README.md
@@ -21,5 +21,5 @@ MacOS.
To run benchmarks:
```bash
-target/release/deno bench --allow-ffi --allow-read --unstable ./test_ffi/tests/bench.js
+target/release/deno bench --allow-ffi --allow-read --unstable-ffi ./test_ffi/tests/bench.js
```
diff --git a/runtime/js/90_deno_ns.js b/runtime/js/90_deno_ns.js
index c44c14bbe..ab2a5c308 100644
--- a/runtime/js/90_deno_ns.js
+++ b/runtime/js/90_deno_ns.js
@@ -154,6 +154,62 @@ const denoNs = {
ChildProcess: process.ChildProcess,
};
+// NOTE(bartlomieju): keep IDs in sync with `cli/main.rs`
+const denoNsUnstableById = {
+ // BroadcastChannel is always available?
+ // 1: {},
+
+ // FFI
+ 2: {
+ dlopen: ffi.dlopen,
+ UnsafeCallback: ffi.UnsafeCallback,
+ UnsafePointer: ffi.UnsafePointer,
+ UnsafePointerView: ffi.UnsafePointerView,
+ UnsafeFnPointer: ffi.UnsafeFnPointer,
+ },
+
+ // FS
+ 3: {
+ flock: fs.flock,
+ flockSync: fs.flockSync,
+ funlock: fs.funlock,
+ funlockSync: fs.funlockSync,
+ umask: fs.umask,
+ },
+
+ // KV
+ 4: {
+ openKv: kv.openKv,
+ AtomicOperation: kv.AtomicOperation,
+ Kv: kv.Kv,
+ KvU64: kv.KvU64,
+ KvListIterator: kv.KvListIterator,
+ },
+
+ // net
+ 5: {
+ listenDatagram: net.createListenDatagram(
+ ops.op_net_listen_udp,
+ ops.op_net_listen_unixpacket,
+ ),
+ },
+
+ // HTTP
+ 6: {
+ HttpClient: httpClient.HttpClient,
+ createHttpClient: httpClient.createHttpClient,
+ // TODO(bartlomieju): why is it needed?
+ http,
+ upgradeHttp: http.upgradeHttp,
+ },
+ // Worker options
+ // 7: {}
+
+ 8: {
+ cron: cron.cron,
+ },
+};
+
// when editing this list, also update unstableDenoProps in cli/tsc/99_main_compiler.js
const denoNsUnstable = {
listenDatagram: net.createListenDatagram(
@@ -183,4 +239,4 @@ const denoNsUnstable = {
cron: cron.cron,
};
-export { denoNs, denoNsUnstable };
+export { denoNs, denoNsUnstable, denoNsUnstableById };
diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js
index ac1f52e74..b06cef651 100644
--- a/runtime/js/99_main.js
+++ b/runtime/js/99_main.js
@@ -57,7 +57,11 @@ import * as performance from "ext:deno_web/15_performance.js";
import * as url from "ext:deno_url/00_url.js";
import * as fetch from "ext:deno_fetch/26_fetch.js";
import * as messagePort from "ext:deno_web/13_message_port.js";
-import { denoNs, denoNsUnstable } from "ext:runtime/90_deno_ns.js";
+import {
+ denoNs,
+ denoNsUnstable,
+ denoNsUnstableById,
+} from "ext:runtime/90_deno_ns.js";
import { errors } from "ext:runtime/01_errors.js";
import * as webidl from "ext:deno_webidl/00_webidl.js";
import DOMException from "ext:deno_web/01_dom_exception.js";
@@ -467,14 +471,15 @@ function bootstrapMainRuntime(runtimeOptions) {
7: isTty,
8: tsVersion,
9: unstableFlag,
- 10: pid,
- 11: target,
- 12: v8Version,
- 13: userAgent,
- 14: inspectFlag,
- // 15: enableTestingFeaturesFlag
- 16: hasNodeModulesDir,
- 17: maybeBinaryNpmCommandName,
+ 10: unstableFeatures,
+ 11: pid,
+ 12: target,
+ 13: v8Version,
+ 14: userAgent,
+ 15: inspectFlag,
+ // 16: enableTestingFeaturesFlag
+ 17: hasNodeModulesDir,
+ 18: maybeBinaryNpmCommandName,
} = runtimeOptions;
performance.setTimeOrigin(DateNow());
@@ -557,6 +562,7 @@ function bootstrapMainRuntime(runtimeOptions) {
mainModule: util.getterOnly(opMainModule),
});
+ // TODO(bartlomieju): deprecate --unstable
if (unstableFlag) {
ObjectAssign(finalDenoNs, denoNsUnstable);
// TODO(bartlomieju): this is not ideal, but because we use `ObjectAssign`
@@ -576,6 +582,11 @@ function bootstrapMainRuntime(runtimeOptions) {
jupyterNs = val;
},
});
+ } else {
+ for (let i = 0; i <= unstableFeatures.length; i++) {
+ const id = unstableFeatures[i];
+ ObjectAssign(finalDenoNs, denoNsUnstableById[id]);
+ }
}
// Setup `Deno` global - we're actually overriding already existing global
@@ -611,14 +622,15 @@ function bootstrapWorkerRuntime(
7: isTty,
8: tsVersion,
9: unstableFlag,
- 10: pid,
- 11: target,
- 12: v8Version,
- 13: userAgent,
- // 14: inspectFlag,
- 15: enableTestingFeaturesFlag,
- 16: hasNodeModulesDir,
- 17: maybeBinaryNpmCommandName,
+ 10: unstableFeatures,
+ 11: pid,
+ 12: target,
+ 13: v8Version,
+ 14: userAgent,
+ // 15: inspectFlag,
+ 16: enableTestingFeaturesFlag,
+ 17: hasNodeModulesDir,
+ 18: maybeBinaryNpmCommandName,
} = runtimeOptions;
performance.setTimeOrigin(DateNow());
@@ -688,8 +700,14 @@ function bootstrapWorkerRuntime(
globalThis.pollForMessages = pollForMessages;
+ // TODO(bartlomieju): deprecate --unstable
if (unstableFlag) {
ObjectAssign(finalDenoNs, denoNsUnstable);
+ } else {
+ for (let i = 0; i <= unstableFeatures.length; i++) {
+ const id = unstableFeatures[i];
+ ObjectAssign(finalDenoNs, denoNsUnstableById[id]);
+ }
}
ObjectDefineProperties(finalDenoNs, {
pid: util.readOnly(pid),
diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs
index 960e35b3d..b2ea1affe 100644
--- a/runtime/ops/worker_host.rs
+++ b/runtime/ops/worker_host.rs
@@ -26,7 +26,7 @@ use std::collections::HashMap;
use std::rc::Rc;
use std::sync::Arc;
-pub const UNSTABLE_FEATURE_NAME: &str = "worker";
+pub const UNSTABLE_FEATURE_NAME: &str = "worker-options";
pub struct CreateWebWorkerArgs {
pub name: String,
diff --git a/runtime/worker_bootstrap.rs b/runtime/worker_bootstrap.rs
index 0f533344f..b21b4aa21 100644
--- a/runtime/worker_bootstrap.rs
+++ b/runtime/worker_bootstrap.rs
@@ -54,7 +54,10 @@ pub struct BootstrapOptions {
pub runtime_version: String,
/// Sets `Deno.version.typescript` in JS runtime.
pub ts_version: String,
+ // --unstable flag, deprecated
pub unstable: bool,
+ // --unstable-* flags
+ pub unstable_features: Vec<i32>,
pub user_agent: String,
pub inspect: bool,
pub has_node_modules_dir: bool,
@@ -82,6 +85,7 @@ impl Default for BootstrapOptions {
locale: "en".to_string(),
location: Default::default(),
unstable: Default::default(),
+ unstable_features: Default::default(),
inspect: Default::default(),
args: Default::default(),
has_node_modules_dir: Default::default(),
@@ -121,6 +125,8 @@ struct BootstrapV8<'a>(
&'a str,
// unstable
bool,
+ // granular unstable flags
+ &'a [i32],
// process_id
i32,
// env!("TARGET")
@@ -159,6 +165,7 @@ impl BootstrapOptions {
self.is_tty,
&self.ts_version,
self.unstable,
+ self.unstable_features.as_ref(),
std::process::id() as _,
env!("TARGET"),
deno_core::v8_version(),
diff --git a/test_ffi/tests/integration_tests.rs b/test_ffi/tests/integration_tests.rs
index ad00465e6..99707438e 100644
--- a/test_ffi/tests/integration_tests.rs
+++ b/test_ffi/tests/integration_tests.rs
@@ -29,7 +29,7 @@ fn basic() {
.arg("run")
.arg("--allow-ffi")
.arg("--allow-read")
- .arg("--unstable")
+ .arg("--unstable-ffi")
.arg("--quiet")
.arg(r#"--v8-flags=--allow-natives-syntax"#)
.arg("tests/test.js")