From 735da4315a98a6960f3b5089115e308548b91c07 Mon Sep 17 00:00:00 2001 From: dcodeIO Date: Tue, 24 Jan 2017 03:12:32 +0100 Subject: [PATCH] CLI: Also reuse specified root in pbjs for JSON modules, see #653 --- cli/targets/json-module.js | 17 ++++++++++---- cli/targets/json.js | 2 -- cli/targets/static-module.js | 4 +--- cli/targets/static.js | 11 --------- cli/util.js | 21 +++++++++++++++++- tests/split/root.js | 43 ++++++++++++++++++++++++++++++++++++ tests/split/test.proto | 15 +++++++++++++ 7 files changed, 92 insertions(+), 21 deletions(-) create mode 100644 tests/split/root.js create mode 100644 tests/split/test.proto diff --git a/cli/targets/json-module.js b/cli/targets/json-module.js index f8c50432c..e707b5068 100644 --- a/cli/targets/json-module.js +++ b/cli/targets/json-module.js @@ -3,12 +3,21 @@ module.exports = json_module; var util = require("../util"); -json_module.description = "JSON representation as a module" +json_module.description = "JSON representation as a module"; function json_module(root, options, callback) { - try { - var output = "var $root = protobuf.Root.fromJSON(" + JSON.stringify(root, null, 2).replace(/^(?!$)/mg, " ").trim() + ");"; - output = util.wrap(output, options); + try { + var rootProp = util.safeProp(options.root || "default"); + var output = [ + "var $root = ($protobuf.roots" + rootProp + " || ($protobuf.roots" + rootProp + " = new $protobuf.Root()))\n" + ]; + if (root.options) { + var optionsJson = util.jsonSafeProp(JSON.stringify(root.options, null, 2)); + output.push(".setOptions(" + optionsJson + ")\n"); + } + var json = util.jsonSafeProp(JSON.stringify(root.nested, null, 2).trim()); + output.push(".addJSON(" + json + ");"); + output = util.wrap(output.join(""), options); process.nextTick(function() { callback(null, output); }); diff --git a/cli/targets/json.js b/cli/targets/json.js index 75b7a0a87..c164717f9 100644 --- a/cli/targets/json.js +++ b/cli/targets/json.js @@ -1,8 +1,6 @@ "use strict"; module.exports = json_target; -var protobuf = require("../.."); - json_target.description = "JSON representation" function json_target(root, options, callback) { diff --git a/cli/targets/static-module.js b/cli/targets/static-module.js index b639fecc8..9cb2b6844 100644 --- a/cli/targets/static-module.js +++ b/cli/targets/static-module.js @@ -6,9 +6,7 @@ module.exports = static_module_target; // - CommonJS modules depend on the minimal build for reduced package size with browserify. // - AMD and global scope depend on the full library for now. -var path = require("path"), - fs = require("fs"), - util = require("../util"); +var util = require("../util"); var protobuf = require("../.."); diff --git a/cli/targets/static.js b/cli/targets/static.js index 72e8150eb..59343852e 100644 --- a/cli/targets/static.js +++ b/cli/targets/static.js @@ -93,17 +93,6 @@ function aOrAn(name) { : "a ") + name; } -// generate dot-notation property accessors where possible. this saves a few chars (i.e. m.hello -// instead of m["hello"]) but has no measurable performance impact (on V8). not present within the -// library itself because the reserved words check requires a rather longish regex. -util.safeProp = (function(safeProp) { - return function safeProp_dn(name) { - return !/^[$\w]+$/.test(name) || cliUtil.reserved(name) - ? safeProp(name) - : "." + name; - } -})(util.safeProp); - function buildNamespace(ref, ns) { if (!ns) return; diff --git a/cli/util.js b/cli/util.js index aac97ceda..f8077b5b1 100644 --- a/cli/util.js +++ b/cli/util.js @@ -139,6 +139,25 @@ exports.pad = function(str, len, l) { return str; }; -exports.reserved = function(name) { +exports.reserved = function reserved(name) { return /^(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|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)$/.test(name); }; + +// generate dot-notation property accessors where possible. this saves a few chars (i.e. m.hello +// instead of m["hello"]) but has no measurable performance impact (on V8). not present within the +// library itself because the reserved words check requires a rather longish regex. +exports.safeProp = protobuf.util.safeProp = (function(safeProp) { + return function safeProp_dn(name) { + return !/^[$\w]+$/.test(name) || exports.reserved(name) + ? safeProp(name) + : "." + name; + } +})(protobuf.util.safeProp); + +exports.jsonSafeProp = function(json) { + return json.replace(/^( +)"(\w+)":/mg, function($0, $1, $2) { + return exports.safeProp($2).charAt(0) === "." + ? $1 + $2 + ":" + : $0; + }); +}; diff --git a/tests/split/root.js b/tests/split/root.js new file mode 100644 index 000000000..75b480c56 --- /dev/null +++ b/tests/split/root.js @@ -0,0 +1,43 @@ +/*eslint-disable block-scoped-var, no-redeclare, no-control-regex, no-prototype-builtins*/ +"use strict"; + +var $protobuf = require("protobufjs"); + +var $root = ($protobuf.roots.split || ($protobuf.roots.split = new $protobuf.Root())) +.setOptions({ + "(foo)": "bar" +}) +.addJSON({ + com: { + nested: { + Outer: { + fields: { + inner: { + type: "Inner", + id: 1 + }, + other: { + type: "Other", + id: 2 + } + }, + nested: { + Inner: { + fields: {} + } + } + }, + Other: { + fields: { + "var": { + rule: "required", + type: "uint32", + id: 1 + } + } + } + } + } +}); + +module.exports = $root; diff --git a/tests/split/test.proto b/tests/split/test.proto new file mode 100644 index 000000000..2b08a4f49 --- /dev/null +++ b/tests/split/test.proto @@ -0,0 +1,15 @@ +option (foo) = "bar"; + +package com; + +message Outer { + optional Inner inner = 1; + optional Other other = 2; + + message Inner { + } +} + +message Other { + required uint32 var = 1; +} \ No newline at end of file