Skip to content

Commit 4885b82

Browse files
committed
pbjs static target progress, uses customizable wrapper template [ci skip]
1 parent fce8276 commit 4885b82

File tree

10 files changed

+124
-72
lines changed

10 files changed

+124
-72
lines changed

Diff for: README.md

+3
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,10 @@ The `pbjs` command line utility can be used to bundle and translate between .pro
295295
Consolidates imports and converts between file formats.
296296
297297
-t, --target Specifies the target format. [json, proto2, proto3]
298+
Also accepts a path to require a custom target.
299+
298300
-p, --path Adds a directory to the include path.
301+
299302
-o, --out Saves to a file instead of writing to stdout.
300303
301304
usage: pbjs [options] file1.proto file2.json ...

Diff for: cli/pbjs.js

+14-9
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ exports.main = function(args) {
1616
alias: {
1717
target : "t",
1818
out : "o",
19-
path : "p"
19+
path : "p",
20+
wrap : "w"
2021
},
21-
string: [ "target", "out", "path" ],
22+
string: [ "target", "out", "path", "wrap" ],
2223
default: {
2324
target: "json"
2425
}
2526
});
27+
2628
var target = targets[argv.target],
2729
files = argv._,
2830
paths = typeof argv.path === 'string' ? [ argv.path ] : argv.path || [];
@@ -35,17 +37,18 @@ exports.main = function(args) {
3537
"",
3638
" -t, --target Specifies the target format. [" + Object.keys(targets).filter(function(key) { return !targets[key].private; }).join(', ') + "]",
3739
" Also accepts a path to require a custom target.",
40+
"",
3841
" -p, --path Adds a directory to the include path.",
42+
"",
3943
" -o, --out Saves to a file instead of writing to stdout.",
4044
"",
45+
" -w, --wrap Specifies an alternative wrapper for the static target.",
46+
"",
4147
"usage: " + chalk.bold.green(path.basename(process.argv[1])) + " [options] file1.proto file2.json ..."
4248
].join("\n"));
4349
return 1;
4450
}
4551

46-
if (!target)
47-
target = require(path.resolve(process.cwd(), argv.target));
48-
4952
// Resolve glob expressions
5053
for (var i = 0; i < files.length;) {
5154
if (glob.hasMagic(files[i])) {
@@ -56,9 +59,13 @@ exports.main = function(args) {
5659
++i;
5760
}
5861

62+
// Require custom target
63+
if (!target)
64+
target = require(path.resolve(process.cwd(), argv.target));
65+
5966
var root = new protobuf.Root();
6067

61-
// Fall back to include paths when resolving imports
68+
// Search include paths when resolving imports
6269
root.resolvePath = function pbjsResolvePath(origin, target) {
6370
var filepath = protobuf.util.resolvePath(origin, target);
6471
if (fs.existsSync(filepath))
@@ -71,12 +78,10 @@ exports.main = function(args) {
7178
return filepath;
7279
};
7380

74-
var options = {};
75-
7681
root.load(files, function(err) {
7782
if (err)
7883
throw err;
79-
target(root, options, function(err, output) {
84+
target(root, argv, function(err, output) {
8085
if (err)
8186
throw err;
8287
if (output !== "") {

Diff for: cli/targets/json.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"use strict";
12
module.exports = json_target;
23

34
var protobuf = require("../..");

Diff for: cli/targets/proto.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"use strict";
12
module.exports = proto_target;
23

34
proto_target.private = true;

Diff for: cli/targets/proto2.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"use strict";
12
module.exports = proto2_target;
23

34
var protobuf = require("../..");

Diff for: cli/targets/proto3.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"use strict";
12
module.exports = proto3_target;
23

34
var protobuf = require("../..");

Diff for: cli/targets/static.js

+38-35
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1+
"use strict";
12
module.exports = static_target;
23

3-
static_target.private = true;
4+
// - Static code does not have any reflection or JSON features.
5+
// - The default wrapper supports AMD, CommonJS and the global scope (as window.root), in this order.
6+
// - You can specify a custom wrapper with the --wrap argument.
7+
// - CommonJS modules depend on the minimal static runtime for reduced package size with browserify.
8+
// - AMD and global scope depend on the full library for now.
9+
// - Services aren't supported, yet.
410

5-
// Currently, this target builds single file CommonJS modules.
6-
// - There is no reflection and no message inheritance from Prototype.
7-
// - Generated code is tailored for browerify build processes (minimal runtime).
8-
9-
// TBD:
10-
// - Generate a single file or scaffold an entire project directory? Both?
11-
// - Targets: ES5, ES6, TypeScript? CommonJS? AMD?
12-
// - What about generating typescript definitions for non-ts targets?
11+
var path = require("path"),
12+
fs = require("fs");
1313

1414
var protobuf = require("../..");
1515

@@ -26,14 +26,21 @@ var out = [];
2626
var indent = 0;
2727

2828
function static_target(root, options, callback) {
29-
tree = {};
29+
if (options.wrap)
30+
options.wrap = path.resolve(process.cwd(), options.wrap);
31+
else
32+
options.wrap = path.join(__dirname, "static.tpl");
3033
try {
31-
buildNamespace("module.exports", root);
32-
callback(null, out.join('\n'));
34+
var wrap = fs.readFileSync(options.wrap).toString("utf8");
35+
++indent;
36+
buildNamespace(null, root);
37+
--indent;
38+
callback(null, wrap.replace(/\r?\n%OUTPUT%/, out.join('\n')));
3339
} catch (err) {
3440
callback(err);
3541
} finally {
3642
out = [];
43+
indent = 0;
3744
}
3845
}
3946

@@ -63,17 +70,7 @@ function name(name) {
6370
function buildNamespace(ref, ns) {
6471
if (!ns)
6572
return;
66-
if (ns.name === "") { // root
67-
push(name(ref) + " = (function() {");
68-
++indent;
69-
push('"use strict";');
70-
push("");
71-
push("// Minimal static codegen runtime");
72-
push("var $runtime = require(\"protobufjs/runtime\");")
73-
push("");
74-
push("// Lazily resolved type references");
75-
push("var $lazyTypes = [];");
76-
} else {
73+
if (ns.name !== "") {
7774
push("");
7875
push("/** @alias " + ns.fullName.substring(1) + " */");
7976
push(name(ref) + "." + name(ns.name) + " = (function() {");
@@ -84,7 +81,7 @@ function buildNamespace(ref, ns) {
8481
buildType(undefined, ns);
8582
} else if (ns instanceof Service)
8683
buildService(undefined, ns);
87-
else {
84+
else if (ns.name !== "") {
8885
push("");
8986
push("/** @alias " + (ns.name && ns.fullName.substring(1) || "exports") + " */");
9087
push("var " + name(ns.name) + " = {};");
@@ -96,13 +93,12 @@ function buildNamespace(ref, ns) {
9693
else if (nested instanceof Namespace)
9794
buildNamespace(ns.name, nested);
9895
});
99-
push("");
100-
if (ns.name === "") // root
101-
push("return $runtime.resolve($root, $lazyTypes);");
102-
else
96+
if (ns.name !== "") {
97+
push("");
10398
push("return " + name(ns.name) + ";");
104-
--indent;
105-
push("})();");
99+
--indent;
100+
push("})();");
101+
}
106102
}
107103

108104
function buildFunction(type, functionName, gen, scope) {
@@ -235,17 +231,24 @@ function buildType(ref, type) {
235231

236232
function buildService(ref, service) {
237233
push("");
238-
push(name(ref) + "." + name(service.name) + " = {};"); // currently just an empty object
234+
push(name(ref) + "." + name(service.name) + " = {};");
235+
// TODO: Services are just empty objects currently
239236
}
240237

241238
function buildEnum(ref, enm) {
242239
push("");
243-
push(ref + "." + enm.name + " = {");
240+
pushComment([
241+
enm.name + " values.",
242+
"@exports " + enm.fullName.substring(1),
243+
"@type {Object.<string,number>}"
244+
]);
245+
push(name(ref) + "." + name(enm.name) + " = {");
244246
++indent;
245247
push("");
246-
Object.keys(enm.values).forEach(function(key) {
247-
push(name(key) + ": " + enm.values[key].toString(10) + ",");
248-
});
248+
var keys = Object.keys(enm.values);
249+
for (var i = 0; i < keys.length; ++i) {
250+
push(name(keys[i]) + ": " + enm.values[keys[i]].toString(10) + (i < keys.length - 1 ? "," : ""));
251+
}
249252
--indent;
250253
push("};");
251254
}

Diff for: cli/targets/static.tpl

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
;(function(global, factory) {
2+
3+
/* AMD */ if (typeof define === 'function' && define.amd)
4+
define(["protobuf"], factory);
5+
6+
/* CommonJS */ else if (typeof require === 'function' && typeof module === 'object' && module && module.exports)
7+
module.exports = factory(require("protobufjs/runtime"));
8+
9+
/* Global */ else
10+
global.root = factory(global.protobuf);
11+
12+
})(this, function($runtime) {
13+
"use strict";
14+
15+
// Lazily resolved type references
16+
var $lazyTypes = [];
17+
18+
// Exported root namespace
19+
var $root = {};
20+
21+
%OUTPUT%
22+
23+
// Resolve lazy types
24+
$lazyTypes.forEach(function(types) {
25+
types.forEach(function(path, i) {
26+
if (!path)
27+
return;
28+
path = path.split('.');
29+
var ptr = $root;
30+
while (path.length)
31+
ptr = ptr[path.shift()];
32+
types[i] = ptr;
33+
});
34+
});
35+
36+
return $root;
37+
});

Diff for: runtime.js

-21
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,3 @@ runtime.Writer = require("./src/writer");
2121
* @memberof runtime
2222
*/
2323
runtime.util = require("./src/util/runtime");
24-
25-
/**
26-
* Resolves lazy type references.
27-
* @param {Object} root Root object
28-
* @param {string[][]} lazyTypes Lazy type references
29-
* @returns {Object} `root`
30-
*/
31-
runtime.resolve = function resolve(root, lazyTypes) {
32-
lazyTypes.forEach(function(types) {
33-
types.forEach(function(path, i) {
34-
if (!path)
35-
return;
36-
path = path.split('.');
37-
var ptr = root;
38-
while (path.length)
39-
ptr = ptr[path.shift()];
40-
types[i] = ptr;
41-
});
42-
});
43-
return root;
44-
};

Diff for: tests/data/package.js

+28-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
1-
module.exports = (function() {
2-
"use strict";
1+
;(function(global, factory) {
2+
3+
/* AMD */ if (typeof define === 'function' && define.amd)
4+
define(["protobuf"], factory);
5+
6+
/* CommonJS */ else if (typeof require === 'function' && typeof module === 'object' && module && module.exports)
7+
module.exports = factory(require("../../runtime"));
8+
9+
/* Global */ else
10+
global.root = factory(global.protobuf);
311

4-
// Minimal static codegen runtime
5-
var $runtime = require("../../runtime");
12+
})(this, function($runtime) {
13+
"use strict";
614

715
// Lazily resolved type references
816
var $lazyTypes = [];
917

10-
/** @alias exports */
18+
// Exported root namespace
1119
var $root = {};
1220

1321
/** @alias Package */
@@ -416,5 +424,18 @@ module.exports = (function() {
416424
return Package;
417425
})();
418426

419-
return $runtime.resolve($root, $lazyTypes);
420-
})();
427+
// Resolve lazy types
428+
$lazyTypes.forEach(function(types) {
429+
types.forEach(function(path, i) {
430+
if (!path)
431+
return;
432+
path = path.split('.');
433+
var ptr = $root;
434+
while (path.length)
435+
ptr = ptr[path.shift()];
436+
types[i] = ptr;
437+
});
438+
});
439+
440+
return $root;
441+
});

0 commit comments

Comments
 (0)