summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorKevin (Kun) "Kassimo" Qian <kevinkassimo@gmail.com>2019-10-26 18:04:34 -0700
committerRy Dahl <ry@tinyclouds.org>2019-10-26 21:04:34 -0400
commit6869bfa4c63121f60284c7a2e48c5db1ce86f9cc (patch)
tree81be58ad8ff516aa86f0325a7516cd85bcbb23fb /cli
parentc5fe657dd3e81110f84cdff8ff1b35492de4d1a3 (diff)
Support named imports/exports for subset of properties in JSON modules (#3210)
Diffstat (limited to 'cli')
-rw-r--r--cli/compilers/json.rs39
-rw-r--r--cli/tests/050_more_jsons.ts7
-rw-r--r--cli/tests/050_more_jsons.ts.out5
-rw-r--r--cli/tests/integration_tests.rs5
-rw-r--r--cli/tests/subdir/json_1.json5
-rw-r--r--cli/tests/subdir/json_2.json1
6 files changed, 58 insertions, 4 deletions
diff --git a/cli/compilers/json.rs b/cli/compilers/json.rs
index 57e44d354..e61b38649 100644
--- a/cli/compilers/json.rs
+++ b/cli/compilers/json.rs
@@ -3,8 +3,13 @@ use crate::compilers::CompiledModule;
use crate::compilers::CompiledModuleFuture;
use crate::file_fetcher::SourceFile;
use crate::state::ThreadSafeState;
+use deno::ErrBox;
+use regex::Regex;
use std::str;
+// From https://github.com/mathiasbynens/mothereff.in/blob/master/js-variables/eff.js
+static JS_RESERVED_WORDS: &str = r"^(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|await|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$";
+
pub struct JsonCompiler {}
impl JsonCompiler {
@@ -13,11 +18,37 @@ impl JsonCompiler {
_state: ThreadSafeState,
source_file: &SourceFile,
) -> Box<CompiledModuleFuture> {
+ let maybe_json_value: serde_json::Result<serde_json::Value> =
+ serde_json::from_str(&str::from_utf8(&source_file.source_code).unwrap());
+ if let Err(err) = maybe_json_value {
+ return Box::new(futures::future::err(ErrBox::from(err)));
+ }
+
+ let mut code = format!(
+ "export default {};\n",
+ str::from_utf8(&source_file.source_code).unwrap()
+ );
+
+ if let serde_json::Value::Object(m) = maybe_json_value.unwrap() {
+ // Best effort variable name exports
+ // Actual all allowed JS variable names are way tricker.
+ // We only handle a subset of alphanumeric names.
+ let js_var_regex = Regex::new(r"^[a-zA-Z_$][0-9a-zA-Z_$]*$").unwrap();
+ // Also avoid collision with reserved words.
+ let reserved_words = Regex::new(JS_RESERVED_WORDS).unwrap();
+ for (key, value) in m.iter() {
+ if js_var_regex.is_match(&key) && !reserved_words.is_match(&key) {
+ code.push_str(&format!(
+ "export const {} = {};\n",
+ key,
+ value.to_string()
+ ));
+ }
+ }
+ }
+
let module = CompiledModule {
- code: format!(
- "export default {};",
- str::from_utf8(&source_file.source_code).unwrap()
- ),
+ code,
name: source_file.url.to_string(),
};
diff --git a/cli/tests/050_more_jsons.ts b/cli/tests/050_more_jsons.ts
new file mode 100644
index 000000000..90deabcd1
--- /dev/null
+++ b/cli/tests/050_more_jsons.ts
@@ -0,0 +1,7 @@
+import j1, { $var } from "./subdir/json_1.json";
+import j2 from "./subdir/json_2.json";
+console.log($var);
+console.log($var.a);
+console.log(j1);
+console.log(j1["with space"]);
+console.log(j2);
diff --git a/cli/tests/050_more_jsons.ts.out b/cli/tests/050_more_jsons.ts.out
new file mode 100644
index 000000000..0ca014a21
--- /dev/null
+++ b/cli/tests/050_more_jsons.ts.out
@@ -0,0 +1,5 @@
+{ a: 123, b: [ 1, 2, 3 ], c: null }
+123
+{ $var: { a: 123, b: [ 1, 2, 3 ], c: null }, with space: "invalid variable name", function: "reserved word" }
+invalid variable name
+just a string
diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs
index 909acfe04..ee8f1384c 100644
--- a/cli/tests/integration_tests.rs
+++ b/cli/tests/integration_tests.rs
@@ -343,6 +343,11 @@ itest!(_049_info_flag_script_jsx {
http_server: true,
});
+itest!(_050_more_jsons {
+ args: "run --reload 050_more_jsons.ts",
+ output: "050_more_jsons.ts.out",
+});
+
itest!(async_error {
exit_code: 1,
args: "run --reload async_error.ts",
diff --git a/cli/tests/subdir/json_1.json b/cli/tests/subdir/json_1.json
new file mode 100644
index 000000000..754d16b84
--- /dev/null
+++ b/cli/tests/subdir/json_1.json
@@ -0,0 +1,5 @@
+{
+ "$var": { "a": 123, "b": [1, 2, 3], "c": null },
+ "with space": "invalid variable name",
+ "function": "reserved word"
+}
diff --git a/cli/tests/subdir/json_2.json b/cli/tests/subdir/json_2.json
new file mode 100644
index 000000000..7deb8b173
--- /dev/null
+++ b/cli/tests/subdir/json_2.json
@@ -0,0 +1 @@
+"just a string"