protobufjs 6.11.3 → 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +7 -174
  2. package/dist/light/protobuf.js +77 -29
  3. package/dist/light/protobuf.js.map +1 -1
  4. package/dist/light/protobuf.min.js +3 -3
  5. package/dist/light/protobuf.min.js.map +1 -1
  6. package/dist/minimal/protobuf.js +27 -10
  7. package/dist/minimal/protobuf.js.map +1 -1
  8. package/dist/minimal/protobuf.min.js +3 -3
  9. package/dist/minimal/protobuf.min.js.map +1 -1
  10. package/dist/protobuf.js +163 -61
  11. package/dist/protobuf.js.map +1 -1
  12. package/dist/protobuf.min.js +3 -3
  13. package/dist/protobuf.min.js.map +1 -1
  14. package/index.d.ts +9 -7
  15. package/package.json +12 -31
  16. package/scripts/postinstall.js +0 -3
  17. package/src/converter.js +12 -4
  18. package/src/decoder.js +4 -3
  19. package/src/enum.js +24 -7
  20. package/src/field.js +6 -3
  21. package/src/namespace.js +3 -3
  22. package/src/parse.js +55 -16
  23. package/src/roots.js +1 -1
  24. package/src/tokenize.js +31 -16
  25. package/src/util/minimal.js +24 -7
  26. package/src/wrappers.js +2 -2
  27. package/tsconfig.json +2 -1
  28. package/CHANGELOG.md +0 -1027
  29. package/bin/pbjs +0 -6
  30. package/bin/pbts +0 -6
  31. package/cli/LICENSE +0 -33
  32. package/cli/README.md +0 -174
  33. package/cli/bin/pbjs +0 -6
  34. package/cli/bin/pbts +0 -6
  35. package/cli/index.d.ts +0 -3
  36. package/cli/index.js +0 -3
  37. package/cli/lib/tsd-jsdoc/LICENSE +0 -21
  38. package/cli/lib/tsd-jsdoc/README.md +0 -23
  39. package/cli/lib/tsd-jsdoc/plugin.js +0 -21
  40. package/cli/lib/tsd-jsdoc/publish.js +0 -705
  41. package/cli/lib/tsd-jsdoc.json +0 -18
  42. package/cli/package.json +0 -8
  43. package/cli/package.standalone.json +0 -32
  44. package/cli/pbjs.d.ts +0 -9
  45. package/cli/pbjs.js +0 -330
  46. package/cli/pbts.d.ts +0 -9
  47. package/cli/pbts.js +0 -197
  48. package/cli/targets/json-module.js +0 -38
  49. package/cli/targets/json.js +0 -8
  50. package/cli/targets/proto.js +0 -326
  51. package/cli/targets/proto2.js +0 -10
  52. package/cli/targets/proto3.js +0 -10
  53. package/cli/targets/static-module.js +0 -29
  54. package/cli/targets/static.js +0 -711
  55. package/cli/util.js +0 -183
  56. package/cli/wrappers/amd.js +0 -7
  57. package/cli/wrappers/closure.js +0 -7
  58. package/cli/wrappers/commonjs.js +0 -7
  59. package/cli/wrappers/default.js +0 -15
  60. package/cli/wrappers/es6.js +0 -5
  61. package/dist/README.md +0 -31
  62. package/dist/light/README.md +0 -31
  63. package/dist/minimal/README.md +0 -31
  64. package/package-lock.json +0 -7870
  65. package/scripts/changelog.js +0 -150
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // DO NOT EDIT! This is a generated file. Edit the JSDoc in src/*.js instead and run 'npm run types'.
1
+ // DO NOT EDIT! This is a generated file. Edit the JSDoc in src/*.js instead and run 'npm run build:types'.
2
2
 
3
3
  export as namespace protobuf;
4
4
 
@@ -160,8 +160,9 @@ export class Enum extends ReflectionObject {
160
160
  * @param [options] Declared options
161
161
  * @param [comment] The comment for this enum
162
162
  * @param [comments] The value comments for this enum
163
+ * @param [valuesOptions] The value options for this enum
163
164
  */
164
- constructor(name: string, values?: { [k: string]: number }, options?: { [k: string]: any }, comment?: string, comments?: { [k: string]: string });
165
+ constructor(name: string, values?: { [k: string]: number }, options?: { [k: string]: any }, comment?: string, comments?: { [k: string]: string }, valuesOptions?: ({ [k: string]: { [k: string]: any } }|undefined));
165
166
 
166
167
  /** Enum values by id. */
167
168
  public valuesById: { [k: number]: string };
@@ -175,6 +176,9 @@ export class Enum extends ReflectionObject {
175
176
  /** Value comment texts, if any. */
176
177
  public comments: { [k: string]: string };
177
178
 
179
+ /** Values options, if any */
180
+ public valuesOptions?: { [k: string]: { [k: string]: any } };
181
+
178
182
  /** Reserved ranges, if any. */
179
183
  public reserved: (number[]|string)[];
180
184
 
@@ -199,11 +203,12 @@ export class Enum extends ReflectionObject {
199
203
  * @param name Value name
200
204
  * @param id Value id
201
205
  * @param [comment] Comment, if any
206
+ * @param {Object.<string, *>|undefined} [options] Options, if any
202
207
  * @returns `this`
203
208
  * @throws {TypeError} If arguments are invalid
204
209
  * @throws {Error} If there is already a value with this name or id
205
210
  */
206
- public add(name: string, id: number, comment?: string): Enum;
211
+ public add(name: string, id: number, comment?: string, options?: ({ [k: string]: any }|undefined)): Enum;
207
212
 
208
213
  /**
209
214
  * Removes a value from this enum
@@ -300,9 +305,6 @@ export class FieldBase extends ReflectionObject {
300
305
  */
301
306
  constructor(name: string, id: number, type: string, rule?: (string|{ [k: string]: any }), extend?: (string|{ [k: string]: any }), options?: { [k: string]: any }, comment?: string);
302
307
 
303
- /** Field rule, if any. */
304
- public rule?: string;
305
-
306
308
  /** Field type. */
307
309
  public type: string;
308
310
 
@@ -1312,7 +1314,7 @@ export class Root extends NamespaceBase {
1312
1314
  /**
1313
1315
  * Named roots.
1314
1316
  * This is where pbjs stores generated structures (the option `-r, --root` specifies a name).
1315
- * Can also be used manually to make roots available accross modules.
1317
+ * Can also be used manually to make roots available across modules.
1316
1318
  */
1317
1319
  export let roots: { [k: string]: Root };
1318
1320
 
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "protobufjs",
3
- "version": "6.11.3",
3
+ "version": "7.1.1",
4
4
  "versionScheme": "~",
5
5
  "description": "Protocol Buffers for JavaScript (& TypeScript).",
6
6
  "author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
7
7
  "license": "BSD-3-Clause",
8
8
  "repository": "protobufjs/protobuf.js",
9
- "bugs": "https://github.com/dcodeIO/protobuf.js/issues",
9
+ "bugs": "https://github.com/protobufjs/protobuf.js/issues",
10
10
  "homepage": "https://protobufjs.github.io/protobuf.js/",
11
+ "engines": {
12
+ "node": ">=12.0.0"
13
+ },
11
14
  "keywords": [
12
15
  "protobuf",
13
16
  "protocol-buffers",
@@ -16,15 +19,11 @@
16
19
  ],
17
20
  "main": "index.js",
18
21
  "types": "index.d.ts",
19
- "bin": {
20
- "pbjs": "bin/pbjs",
21
- "pbts": "bin/pbts"
22
- },
23
22
  "scripts": {
24
23
  "bench": "node bench",
25
24
  "build": "npm run build:bundle && npm run build:types",
26
25
  "build:bundle": "gulp --gulpfile scripts/gulpfile.js",
27
- "build:types": "node bin/pbts --main --global protobuf --out index.d.ts src/ lib/aspromise/index.js lib/base64/index.js lib/codegen/index.js lib/eventemitter/index.js lib/float/index.js lib/fetch/index.js lib/inquire/index.js lib/path/index.js lib/pool/index.js lib/utf8/index.js",
26
+ "build:types": "node cli/bin/pbts --main --global protobuf --out index.d.ts src/ lib/aspromise/index.js lib/base64/index.js lib/codegen/index.js lib/eventemitter/index.js lib/float/index.js lib/fetch/index.js lib/inquire/index.js lib/path/index.js lib/pool/index.js lib/utf8/index.js",
28
27
  "changelog": "node scripts/changelog -w",
29
28
  "coverage": "nyc tape -r ./lib/tape-adapter tests/*.js tests/node/*.js",
30
29
  "docs": "jsdoc -c config/jsdoc.json -R README.md --verbose --pedantic",
@@ -32,12 +31,12 @@
32
31
  "lint:sources": "eslint \"**/*.js\" -c config/eslint.json",
33
32
  "lint:types": "tslint \"**/*.d.ts\" -e \"**/node_modules/**\" -t stylish -c config/tslint.json",
34
33
  "pages": "node scripts/pages",
35
- "prepublish": "node scripts/prepublish",
34
+ "prepublish": "cd cli && npm install && cd .. && npm run build",
36
35
  "postinstall": "node scripts/postinstall",
37
36
  "prof": "node bench/prof",
38
37
  "test": "npm run test:sources && npm run test:types",
39
38
  "test:sources": "tape -r ./lib/tape-adapter tests/*.js tests/node/*.js",
40
- "test:types": "tsc tests/comp_typescript.ts --lib es2015 --strictNullChecks --experimentalDecorators --emitDecoratorMetadata && tsc tests/data/test.js.ts --lib es2015 --noEmit --strictNullChecks && tsc tests/data/*.ts --lib es2015 --noEmit --strictNullChecks",
39
+ "test:types": "tsc tests/comp_typescript.ts --lib es2015 --esModuleInterop --strictNullChecks --experimentalDecorators --emitDecoratorMetadata && tsc tests/data/test.js.ts --lib es2015 --esModuleInterop --noEmit --strictNullChecks && tsc tests/data/*.ts --lib es2015 --esModuleInterop --noEmit --strictNullChecks",
41
40
  "make": "npm run lint:sources && npm run build && npm run lint:types && node ./scripts/gentests.js && npm test"
42
41
  },
43
42
  "dependencies": {
@@ -51,9 +50,8 @@
51
50
  "@protobufjs/path": "^1.1.2",
52
51
  "@protobufjs/pool": "^1.1.0",
53
52
  "@protobufjs/utf8": "^1.1.0",
54
- "@types/long": "^4.0.1",
55
53
  "@types/node": ">=13.7.0",
56
- "long": "^4.0.0"
54
+ "long": "^5.0.0"
57
55
  },
58
56
  "devDependencies": {
59
57
  "benchmark": "^2.1.4",
@@ -62,27 +60,24 @@
62
60
  "bundle-collapser": "^1.3.0",
63
61
  "chalk": "^4.0.0",
64
62
  "escodegen": "^1.13.0",
65
- "espree": "^7.0.0",
66
63
  "eslint": "^8.15.0",
64
+ "espree": "^9.0.0",
67
65
  "estraverse": "^5.1.0",
68
- "gh-pages": "^3.0.0",
66
+ "gh-pages": "^4.0.0",
69
67
  "git-raw-commits": "^2.0.3",
70
68
  "git-semver-tags": "^4.0.0",
71
- "glob": "^7.1.6",
72
69
  "google-protobuf": "^3.11.3",
73
70
  "gulp": "^4.0.2",
74
71
  "gulp-header": "^2.0.9",
75
72
  "gulp-if": "^3.0.0",
76
- "gulp-sourcemaps": "^2.6.5",
73
+ "gulp-sourcemaps": "^3.0.0",
77
74
  "gulp-uglify": "^3.0.2",
78
75
  "jaguarjs-jsdoc": "github:dcodeIO/jaguarjs-jsdoc",
79
76
  "jsdoc": "^3.6.3",
80
77
  "minimist": "^1.2.0",
81
78
  "nyc": "^15.0.0",
82
79
  "reflect-metadata": "^0.1.13",
83
- "semver": "^7.1.2",
84
80
  "tape": "^5.0.0",
85
- "tmp": "^0.2.0",
86
81
  "tslint": "^6.0.0",
87
82
  "typescript": "^3.7.5",
88
83
  "uglify-js": "^3.7.7",
@@ -90,18 +85,6 @@
90
85
  "vinyl-fs": "^3.0.3",
91
86
  "vinyl-source-stream": "^2.0.0"
92
87
  },
93
- "cliDependencies": [
94
- "semver",
95
- "chalk",
96
- "glob",
97
- "jsdoc",
98
- "minimist",
99
- "tmp",
100
- "uglify-js",
101
- "espree",
102
- "escodegen",
103
- "estraverse"
104
- ],
105
88
  "files": [
106
89
  "index.js",
107
90
  "index.d.ts",
@@ -112,8 +95,6 @@
112
95
  "package-lock.json",
113
96
  "tsconfig.json",
114
97
  "scripts/postinstall.js",
115
- "bin/**",
116
- "cli/**",
117
98
  "dist/**",
118
99
  "ext/**",
119
100
  "google/**",
@@ -4,9 +4,6 @@ var path = require("path"),
4
4
  fs = require("fs"),
5
5
  pkg = require(path.join(__dirname, "..", "package.json"));
6
6
 
7
- // ensure that there is a node_modules folder for cli dependencies
8
- try { fs.mkdirSync(path.join(__dirname, "..", "cli", "node_modules")); } catch (e) {/**/}
9
-
10
7
  // check version scheme used by dependents
11
8
  if (!pkg.versionScheme)
12
9
  return;
package/src/converter.js CHANGED
@@ -18,13 +18,21 @@ var Enum = require("./enum"),
18
18
  * @ignore
19
19
  */
20
20
  function genValuePartial_fromObject(gen, field, fieldIndex, prop) {
21
+ var defaultAlreadyEmitted = false;
21
22
  /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
22
23
  if (field.resolvedType) {
23
24
  if (field.resolvedType instanceof Enum) { gen
24
25
  ("switch(d%s){", prop);
25
26
  for (var values = field.resolvedType.values, keys = Object.keys(values), i = 0; i < keys.length; ++i) {
26
- if (field.repeated && values[keys[i]] === field.typeDefault) gen
27
- ("default:");
27
+ // enum unknown values passthrough
28
+ if (values[keys[i]] === field.typeDefault && !defaultAlreadyEmitted) { gen
29
+ ("default:")
30
+ ("if(typeof(d%s)===\"number\"){m%s=d%s;break}", prop, prop, prop);
31
+ if (!field.repeated) gen // fallback to default value only for
32
+ // arrays, to avoid leaving holes.
33
+ ("break"); // for non-repeated fields, just ignore
34
+ defaultAlreadyEmitted = true;
35
+ }
28
36
  gen
29
37
  ("case%j:", keys[i])
30
38
  ("case %i:", values[keys[i]])
@@ -71,7 +79,7 @@ function genValuePartial_fromObject(gen, field, fieldIndex, prop) {
71
79
  case "bytes": gen
72
80
  ("if(typeof d%s===\"string\")", prop)
73
81
  ("util.base64.decode(d%s,m%s=util.newBuffer(util.base64.length(d%s)),0)", prop, prop, prop)
74
- ("else if(d%s.length)", prop)
82
+ ("else if(d%s.length >= 0)", prop)
75
83
  ("m%s=d%s", prop, prop);
76
84
  break;
77
85
  case "string": gen
@@ -156,7 +164,7 @@ function genValuePartial_toObject(gen, field, fieldIndex, prop) {
156
164
  /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
157
165
  if (field.resolvedType) {
158
166
  if (field.resolvedType instanceof Enum) gen
159
- ("d%s=o.enums===String?types[%i].values[m%s]:m%s", prop, fieldIndex, prop, prop);
167
+ ("d%s=o.enums===String?(types[%i].values[m%s]===undefined?m%s:types[%i].values[m%s]):m%s", prop, fieldIndex, prop, prop, fieldIndex, prop, prop);
160
168
  else gen
161
169
  ("d%s=types[%i].toObject(m%s,o)", prop, fieldIndex, prop);
162
170
  } else {
package/src/decoder.js CHANGED
@@ -33,7 +33,7 @@ function decoder(mtype) {
33
33
  var field = mtype._fieldsArray[i].resolve(),
34
34
  type = field.resolvedType instanceof Enum ? "int32" : field.type,
35
35
  ref = "m" + util.safeProp(field.name); gen
36
- ("case %i:", field.id);
36
+ ("case %i: {", field.id);
37
37
 
38
38
  // Map fields
39
39
  if (field.map) { gen
@@ -104,8 +104,9 @@ function decoder(mtype) {
104
104
  else gen
105
105
  ("%s=r.%s()", ref, type);
106
106
  gen
107
- ("break");
108
- // Unknown fields
107
+ ("break")
108
+ ("}");
109
+ // Unknown fields
109
110
  } gen
110
111
  ("default:")
111
112
  ("r.skipType(t&7)")
package/src/enum.js CHANGED
@@ -18,8 +18,9 @@ var Namespace = require("./namespace"),
18
18
  * @param {Object.<string,*>} [options] Declared options
19
19
  * @param {string} [comment] The comment for this enum
20
20
  * @param {Object.<string,string>} [comments] The value comments for this enum
21
+ * @param {Object.<string,Object<string,*>>|undefined} [valuesOptions] The value options for this enum
21
22
  */
22
- function Enum(name, values, options, comment, comments) {
23
+ function Enum(name, values, options, comment, comments, valuesOptions) {
23
24
  ReflectionObject.call(this, name, options);
24
25
 
25
26
  if (values && typeof values !== "object")
@@ -49,6 +50,12 @@ function Enum(name, values, options, comment, comments) {
49
50
  */
50
51
  this.comments = comments || {};
51
52
 
53
+ /**
54
+ * Values options, if any
55
+ * @type {Object<string, Object<string, *>>|undefined}
56
+ */
57
+ this.valuesOptions = valuesOptions;
58
+
52
59
  /**
53
60
  * Reserved ranges, if any.
54
61
  * @type {Array.<number[]|string>}
@@ -93,11 +100,12 @@ Enum.fromJSON = function fromJSON(name, json) {
93
100
  Enum.prototype.toJSON = function toJSON(toJSONOptions) {
94
101
  var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
95
102
  return util.toObject([
96
- "options" , this.options,
97
- "values" , this.values,
98
- "reserved" , this.reserved && this.reserved.length ? this.reserved : undefined,
99
- "comment" , keepComments ? this.comment : undefined,
100
- "comments" , keepComments ? this.comments : undefined
103
+ "options" , this.options,
104
+ "valuesOptions" , this.valuesOptions,
105
+ "values" , this.values,
106
+ "reserved" , this.reserved && this.reserved.length ? this.reserved : undefined,
107
+ "comment" , keepComments ? this.comment : undefined,
108
+ "comments" , keepComments ? this.comments : undefined
101
109
  ]);
102
110
  };
103
111
 
@@ -106,11 +114,12 @@ Enum.prototype.toJSON = function toJSON(toJSONOptions) {
106
114
  * @param {string} name Value name
107
115
  * @param {number} id Value id
108
116
  * @param {string} [comment] Comment, if any
117
+ * @param {Object.<string, *>|undefined} [options] Options, if any
109
118
  * @returns {Enum} `this`
110
119
  * @throws {TypeError} If arguments are invalid
111
120
  * @throws {Error} If there is already a value with this name or id
112
121
  */
113
- Enum.prototype.add = function add(name, id, comment) {
122
+ Enum.prototype.add = function add(name, id, comment, options) {
114
123
  // utilized by the parser but not by .fromJSON
115
124
 
116
125
  if (!util.isString(name))
@@ -135,6 +144,12 @@ Enum.prototype.add = function add(name, id, comment) {
135
144
  } else
136
145
  this.valuesById[this.values[name] = id] = name;
137
146
 
147
+ if (options) {
148
+ if (this.valuesOptions === undefined)
149
+ this.valuesOptions = {};
150
+ this.valuesOptions[name] = options || null;
151
+ }
152
+
138
153
  this.comments[name] = comment || null;
139
154
  return this;
140
155
  };
@@ -158,6 +173,8 @@ Enum.prototype.remove = function remove(name) {
158
173
  delete this.valuesById[val];
159
174
  delete this.values[name];
160
175
  delete this.comments[name];
176
+ if (this.valuesOptions)
177
+ delete this.valuesOptions[name];
161
178
 
162
179
  return this;
163
180
  };
package/src/field.js CHANGED
@@ -78,13 +78,13 @@ function Field(name, id, type, rule, extend, options, comment) {
78
78
  if (extend !== undefined && !util.isString(extend))
79
79
  throw TypeError("extend must be a string");
80
80
 
81
- if (rule === "proto3_optional") {
82
- rule = "optional";
83
- }
84
81
  /**
85
82
  * Field rule, if any.
86
83
  * @type {string|undefined}
87
84
  */
85
+ if (rule === "proto3_optional") {
86
+ rule = "optional";
87
+ }
88
88
  this.rule = rule && rule !== "optional" ? rule : undefined; // toJSON
89
89
 
90
90
  /**
@@ -270,6 +270,9 @@ Field.prototype.resolve = function resolve() {
270
270
  this.typeDefault = null;
271
271
  else // instanceof Enum
272
272
  this.typeDefault = this.resolvedType.values[Object.keys(this.resolvedType.values)[0]]; // first defined
273
+ } else if (this.options && this.options.proto3_optional) {
274
+ // proto3 scalar value marked optional; should default to null
275
+ this.typeDefault = null;
273
276
  }
274
277
 
275
278
  // use explicitly set default value if present
package/src/namespace.js CHANGED
@@ -6,8 +6,8 @@ var ReflectionObject = require("./object");
6
6
  ((Namespace.prototype = Object.create(ReflectionObject.prototype)).constructor = Namespace).className = "Namespace";
7
7
 
8
8
  var Field = require("./field"),
9
- OneOf = require("./oneof"),
10
- util = require("./util");
9
+ util = require("./util"),
10
+ OneOf = require("./oneof");
11
11
 
12
12
  var Type, // cyclic
13
13
  Service,
@@ -218,7 +218,7 @@ Namespace.prototype.getEnum = function getEnum(name) {
218
218
  */
219
219
  Namespace.prototype.add = function add(object) {
220
220
 
221
- if (!(object instanceof Field && object.extend !== undefined || object instanceof Type || object instanceof Enum || object instanceof Service || object instanceof Namespace || object instanceof OneOf))
221
+ if (!(object instanceof Field && object.extend !== undefined || object instanceof Type || object instanceof OneOf || object instanceof Enum || object instanceof Service || object instanceof Namespace))
222
222
  throw TypeError("object must be a valid nested object");
223
223
 
224
224
  if (!this.nested)
package/src/parse.js CHANGED
@@ -443,6 +443,14 @@ function parse(source, root, options) {
443
443
  }
444
444
  break;
445
445
 
446
+ case "message":
447
+ parseType(type, token);
448
+ break;
449
+
450
+ case "enum":
451
+ parseEnum(type, token);
452
+ break;
453
+
446
454
  /* istanbul ignore next */
447
455
  default:
448
456
  throw illegal(token); // there are no groups with proto3 semantics
@@ -543,7 +551,14 @@ function parse(source, root, options) {
543
551
 
544
552
  skip("=");
545
553
  var value = parseId(next(), true),
546
- dummy = {};
554
+ dummy = {
555
+ options: undefined
556
+ };
557
+ dummy.setOption = function(name, value) {
558
+ if (this.options === undefined)
559
+ this.options = {};
560
+ this.options[name] = value;
561
+ };
547
562
  ifBlock(dummy, function parseEnumValue_block(token) {
548
563
 
549
564
  /* istanbul ignore else */
@@ -556,7 +571,7 @@ function parse(source, root, options) {
556
571
  }, function parseEnumValue_line() {
557
572
  parseInlineOptions(dummy); // skip
558
573
  });
559
- parent.add(token, value, dummy.comment);
574
+ parent.add(token, value, dummy.comment, dummy.options);
560
575
  }
561
576
 
562
577
  function parseOption(parent, token) {
@@ -576,7 +591,7 @@ function parse(source, root, options) {
576
591
  option = name;
577
592
  token = peek();
578
593
  if (fqTypeRefRe.test(token)) {
579
- propName = token.substr(1); //remove '.' before property name
594
+ propName = token.slice(1); //remove '.' before property name
580
595
  name += token;
581
596
  next();
582
597
  }
@@ -587,33 +602,57 @@ function parse(source, root, options) {
587
602
  }
588
603
 
589
604
  function parseOptionValue(parent, name) {
590
- if (skip("{", true)) { // { a: "foo" b { c: "bar" } }
591
- var result = {};
605
+ // { a: "foo" b { c: "bar" } }
606
+ if (skip("{", true)) {
607
+ var objectResult = {};
608
+
592
609
  while (!skip("}", true)) {
593
610
  /* istanbul ignore if */
594
- if (!nameRe.test(token = next()))
611
+ if (!nameRe.test(token = next())) {
595
612
  throw illegal(token, "name");
613
+ }
596
614
 
597
615
  var value;
598
616
  var propName = token;
617
+
618
+ skip(":", true);
619
+
599
620
  if (peek() === "{")
600
621
  value = parseOptionValue(parent, name + "." + token);
601
- else {
602
- skip(":");
603
- if (peek() === "{")
604
- value = parseOptionValue(parent, name + "." + token);
605
- else {
606
- value = readValue(true);
607
- setOption(parent, name + "." + token, value);
622
+ else if (peek() === "[") {
623
+ // option (my_option) = {
624
+ // repeated_value: [ "foo", "bar" ]
625
+ // };
626
+ value = [];
627
+ var lastValue;
628
+ if (skip("[", true)) {
629
+ do {
630
+ lastValue = readValue(true);
631
+ value.push(lastValue);
632
+ } while (skip(",", true));
633
+ skip("]");
634
+ if (typeof lastValue !== "undefined") {
635
+ setOption(parent, name + "." + token, lastValue);
636
+ }
608
637
  }
638
+ } else {
639
+ value = readValue(true);
640
+ setOption(parent, name + "." + token, value);
609
641
  }
610
- var prevValue = result[propName];
642
+
643
+ var prevValue = objectResult[propName];
644
+
611
645
  if (prevValue)
612
646
  value = [].concat(prevValue).concat(value);
613
- result[propName] = value;
647
+
648
+ objectResult[propName] = value;
649
+
650
+ // Semicolons and commas can be optional
614
651
  skip(",", true);
652
+ skip(";", true);
615
653
  }
616
- return result;
654
+
655
+ return objectResult;
617
656
  }
618
657
 
619
658
  var simpleValue = readValue(true);
package/src/roots.js CHANGED
@@ -4,7 +4,7 @@ module.exports = {};
4
4
  /**
5
5
  * Named roots.
6
6
  * This is where pbjs stores generated structures (the option `-r, --root` specifies a name).
7
- * Can also be used manually to make roots available accross modules.
7
+ * Can also be used manually to make roots available across modules.
8
8
  * @name roots
9
9
  * @type {Object.<string,Root>}
10
10
  * @example
package/src/tokenize.js CHANGED
@@ -103,11 +103,8 @@ function tokenize(source, alternateCommentMode) {
103
103
  var offset = 0,
104
104
  length = source.length,
105
105
  line = 1,
106
- commentType = null,
107
- commentText = null,
108
- commentLine = 0,
109
- commentLineEmpty = false,
110
- commentIsLeading = false;
106
+ lastCommentLine = 0,
107
+ comments = {};
111
108
 
112
109
  var stack = [];
113
110
 
@@ -160,10 +157,11 @@ function tokenize(source, alternateCommentMode) {
160
157
  * @inner
161
158
  */
162
159
  function setComment(start, end, isLeading) {
163
- commentType = source.charAt(start++);
164
- commentLine = line;
165
- commentLineEmpty = false;
166
- commentIsLeading = isLeading;
160
+ var comment = {
161
+ type: source.charAt(start++),
162
+ lineEmpty: false,
163
+ leading: isLeading,
164
+ };
167
165
  var lookback;
168
166
  if (alternateCommentMode) {
169
167
  lookback = 2; // alternate comment parsing: "//" or "/*"
@@ -175,7 +173,7 @@ function tokenize(source, alternateCommentMode) {
175
173
  do {
176
174
  if (--commentOffset < 0 ||
177
175
  (c = source.charAt(commentOffset)) === "\n") {
178
- commentLineEmpty = true;
176
+ comment.lineEmpty = true;
179
177
  break;
180
178
  }
181
179
  } while (c === " " || c === "\t");
@@ -186,9 +184,12 @@ function tokenize(source, alternateCommentMode) {
186
184
  lines[i] = lines[i]
187
185
  .replace(alternateCommentMode ? setCommentAltRe : setCommentRe, "")
188
186
  .trim();
189
- commentText = lines
187
+ comment.text = lines
190
188
  .join("\n")
191
189
  .trim();
190
+
191
+ comments[line] = comment;
192
+ lastCommentLine = line;
192
193
  }
193
194
 
194
195
  function isDoubleSlashCommentLine(startOffset) {
@@ -257,6 +258,9 @@ function tokenize(source, alternateCommentMode) {
257
258
  ++offset;
258
259
  if (isDoc) {
259
260
  setComment(start, offset - 1, isLeadingComment);
261
+ // Trailing comment cannot not be multi-line,
262
+ // so leading comment state should be reset to handle potential next comments
263
+ isLeadingComment = true;
260
264
  }
261
265
  ++line;
262
266
  repeat = true;
@@ -272,12 +276,17 @@ function tokenize(source, alternateCommentMode) {
272
276
  break;
273
277
  }
274
278
  offset++;
279
+ if (!isLeadingComment) {
280
+ // Trailing comment cannot not be multi-line
281
+ break;
282
+ }
275
283
  } while (isDoubleSlashCommentLine(offset));
276
284
  } else {
277
285
  offset = Math.min(length, findEndOfLine(offset) + 1);
278
286
  }
279
287
  if (isDoc) {
280
288
  setComment(start, offset, isLeadingComment);
289
+ isLeadingComment = true;
281
290
  }
282
291
  line++;
283
292
  repeat = true;
@@ -299,6 +308,7 @@ function tokenize(source, alternateCommentMode) {
299
308
  ++offset;
300
309
  if (isDoc) {
301
310
  setComment(start, offset - 2, isLeadingComment);
311
+ isLeadingComment = true;
302
312
  }
303
313
  repeat = true;
304
314
  } else {
@@ -374,17 +384,22 @@ function tokenize(source, alternateCommentMode) {
374
384
  */
375
385
  function cmnt(trailingLine) {
376
386
  var ret = null;
387
+ var comment;
377
388
  if (trailingLine === undefined) {
378
- if (commentLine === line - 1 && (alternateCommentMode || commentType === "*" || commentLineEmpty)) {
379
- ret = commentIsLeading ? commentText : null;
389
+ comment = comments[line - 1];
390
+ delete comments[line - 1];
391
+ if (comment && (alternateCommentMode || comment.type === "*" || comment.lineEmpty)) {
392
+ ret = comment.leading ? comment.text : null;
380
393
  }
381
394
  } else {
382
395
  /* istanbul ignore else */
383
- if (commentLine < trailingLine) {
396
+ if (lastCommentLine < trailingLine) {
384
397
  peek();
385
398
  }
386
- if (commentLine === trailingLine && !commentLineEmpty && (alternateCommentMode || commentType === "/")) {
387
- ret = commentIsLeading ? null : commentText;
399
+ comment = comments[trailingLine];
400
+ delete comments[trailingLine];
401
+ if (comment && !comment.lineEmpty && (alternateCommentMode || comment.type === "/")) {
402
+ ret = comment.leading ? null : comment.text;
388
403
  }
389
404
  }
390
405
  return ret;
@@ -280,13 +280,30 @@ function newError(name) {
280
280
  merge(this, properties);
281
281
  }
282
282
 
283
- (CustomError.prototype = Object.create(Error.prototype)).constructor = CustomError;
284
-
285
- Object.defineProperty(CustomError.prototype, "name", { get: function() { return name; } });
286
-
287
- CustomError.prototype.toString = function toString() {
288
- return this.name + ": " + this.message;
289
- };
283
+ CustomError.prototype = Object.create(Error.prototype, {
284
+ constructor: {
285
+ value: CustomError,
286
+ writable: true,
287
+ enumerable: false,
288
+ configurable: true,
289
+ },
290
+ name: {
291
+ get() { return name; },
292
+ set: undefined,
293
+ enumerable: false,
294
+ // configurable: false would accurately preserve the behavior of
295
+ // the original, but I'm guessing that was not intentional.
296
+ // For an actual error subclass, this property would
297
+ // be configurable.
298
+ configurable: true,
299
+ },
300
+ toString: {
301
+ value() { return this.name + ": " + this.message; },
302
+ writable: true,
303
+ enumerable: false,
304
+ configurable: true,
305
+ },
306
+ });
290
307
 
291
308
  return CustomError;
292
309
  }