summaryrefslogtreecommitdiff
path: root/cli/compilers
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/compilers
parentc5fe657dd3e81110f84cdff8ff1b35492de4d1a3 (diff)
Support named imports/exports for subset of properties in JSON modules (#3210)
Diffstat (limited to 'cli/compilers')
-rw-r--r--cli/compilers/json.rs39
1 files changed, 35 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(),
};