Skip to content

Commit 1aacd1c

Browse files
committed
Update to protobufjs 6.x
1 parent c7d9999 commit 1aacd1c

File tree

4 files changed

+166
-46
lines changed

4 files changed

+166
-46
lines changed

packages/firestore/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"npm-run-all": "4.1.5",
6363
"nyc": "13.3.0",
6464
"prettier": "1.16.4",
65+
"protobufjs": "6.8.8",
6566
"rollup": "1.10.0",
6667
"rollup-plugin-copy-assets": "1.1.0",
6768
"rollup-plugin-node-resolve": "4.2.3",

packages/firestore/src/platform_node/load_protos.ts

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,52 +17,60 @@
1717

1818
import * as protoLoader from '@grpc/proto-loader';
1919
import * as grpc from 'grpc';
20-
import { resolve } from 'path';
20+
import * as path from 'path';
2121
import * as ProtobufJS from 'protobufjs';
2222

23+
export const protoLoaderOptions = {
24+
longs: String,
25+
enums: String,
26+
defaults: true,
27+
oneofs: true
28+
};
29+
2330
/**
2431
* Loads the protocol buffer definitions for Firestore.
2532
*
2633
* @returns The GrpcObject representing our protos.
2734
*/
2835
export function loadProtos(): grpc.GrpcObject {
29-
const root = resolve(
36+
const root = path.resolve(
3037
__dirname,
3138
process.env.FIRESTORE_PROTO_ROOT || '../protos'
3239
);
33-
const firestoreProtoFile = root + '/google/firestore/v1/firestore.proto';
40+
const firestoreProtoFile = path.join(
41+
root,
42+
'google/firestore/v1/firestore.proto'
43+
);
3444

35-
// Beware that converting fields to camel case (the default behaviour with
36-
// protoLoader) does not convert the tag fields in oneof groups (!!!). This
37-
// will likely be fixed when we upgrade to protobufjs 6.x
3845
const packageDefinition = protoLoader.loadSync(firestoreProtoFile, {
39-
longs: String,
40-
enums: String,
41-
defaults: true,
42-
oneofs: true,
43-
includeDirs: [root]
46+
...protoLoaderOptions,
47+
...{ includeDirs: [root] }
4448
});
4549

4650
return grpc.loadPackageDefinition(packageDefinition);
4751
}
4852

49-
export function loadRawProtos(): any {
50-
const options = {
51-
// Beware that converting fields to camel case does not convert the tag
52-
// fields in oneof groups (!!!). This will likely be fixed when we upgrade
53-
// to protobufjs 6.x
54-
convertFieldsToCamelCase: true
55-
};
56-
const root = resolve(
53+
export function loadRawProtos(): ProtobufJS.Root {
54+
const root = path.resolve(
5755
__dirname,
5856
process.env.FIRESTORE_PROTO_ROOT || '../protos'
5957
);
60-
const firestoreProtoFile = {
58+
const firestoreProtoFile = path.join(
6159
root,
62-
file: 'google/firestore/v1/firestore.proto'
60+
'google/firestore/v1/firestore.proto'
61+
);
62+
63+
const protoRoot = new ProtobufJS.Root();
64+
// Override the resolvePath function to look for protos in the 'root'
65+
// directory.
66+
protoRoot.resolvePath = (origin: string, target: string) => {
67+
if (path.isAbsolute(target)) {
68+
return target;
69+
}
70+
return path.join(root, target);
6371
};
6472

65-
let builder = ProtobufJS.newBuilder(options);
66-
builder = ProtobufJS.loadProtoFile(firestoreProtoFile, builder);
67-
return builder.build();
73+
protoRoot.loadSync(firestoreProtoFile);
74+
protoRoot.resolveAll();
75+
return protoRoot;
6876
}

packages/firestore/test/unit/remote/node/serializer.test.ts

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,13 @@ describe('Serializer', () => {
7878
const s = new JsonProtoSerializer(partition, { useProto3Json: false });
7979
const emptyResumeToken = new Uint8Array(0);
8080
const protos = loadRawProtos();
81-
const ds = protos['google']['firestore']['v1'];
81+
82+
// tslint:disable:variable-name
83+
const ValueMessage = protos.lookupType('google.firestore.v1.Value');
84+
const LatLngMessage = protos.lookupType('google.type.LatLng');
85+
const TimestampMessage = protos.lookupType('google.protobuf.Timestamp');
86+
const MapValueMessage = protos.lookupType('google.firestore.v1.MapValue');
87+
// tslint:enable:variable-name
8288

8389
/**
8490
* Wraps the given query in QueryData. This is useful because the APIs we're
@@ -100,9 +106,9 @@ describe('Serializer', () => {
100106
/**
101107
* Verifies that the given object can be parsed as a datastore Value proto.
102108
*/
103-
function expectValue(obj: unknown, tag: string): Chai.Assertion {
104-
const proto = new ds.Value(obj);
105-
expect(proto.value_type).to.equal(tag);
109+
function expectValue(obj: api.Value, tag: string): Chai.Assertion {
110+
const proto = ValueMessage.fromObject(obj);
111+
expect(proto['valueType']).to.equal(tag);
106112
return expect(proto[tag]);
107113
}
108114

@@ -207,7 +213,7 @@ describe('Serializer', () => {
207213
const expected = { timestampValue: expectedJson[i] };
208214
expect(obj).to.deep.equal(expected);
209215
expectValue(obj, 'timestampValue').to.deep.equal(
210-
new protos['google']['protobuf'].Timestamp(expectedJson[i]),
216+
TimestampMessage.fromObject(expectedJson[i]),
211217
'for date ' + example
212218
);
213219
}
@@ -226,7 +232,7 @@ describe('Serializer', () => {
226232
const obj = s.toValue(new fieldValue.GeoPointValue(example));
227233
expect(obj).to.deep.equal(expected);
228234
expectValue(obj, 'geoPointValue').to.deep.equal(
229-
new protos['google']['type'].LatLng(1.23, 4.56)
235+
LatLngMessage.fromObject(expected.geoPointValue)
230236
);
231237
});
232238

@@ -273,7 +279,9 @@ describe('Serializer', () => {
273279
const obj = s.toValue(fieldValue.ObjectValue.EMPTY);
274280
expect(obj).to.deep.equal({ mapValue: { fields: {} } });
275281

276-
expectValue(obj, 'mapValue').to.deep.equal(new ds.MapValue());
282+
expectValue(obj, 'mapValue').to.deep.equal(
283+
MapValueMessage.fromObject({})
284+
);
277285
});
278286

279287
it('converts nested ObjectValues', () => {
@@ -340,11 +348,8 @@ describe('Serializer', () => {
340348
const obj = s.toValue(objValue);
341349
expect(obj).to.deep.equal(expectedJson);
342350

343-
// Compare the raw object representation rather than the Message because
344-
// occasionally Jasmine will hang trying to generate the string form in
345-
// the event of an inequality.
346-
expect(new ds.Value(obj).toRaw(true, true)).to.deep.equal(
347-
new ds.Value(expectedJson).toRaw(true, true)
351+
expectValue(obj, 'mapValue').to.deep.equal(
352+
MapValueMessage.fromObject(expectedJson.mapValue)
348353
);
349354
// clang-format on
350355
});
@@ -355,15 +360,17 @@ describe('Serializer', () => {
355360

356361
it('converts NullValue', () => {
357362
const proto: api.Value = { nullValue: 'NULL_VALUE' };
358-
expect(new ds.Value(proto).value_type).to.equal('nullValue');
363+
expect(ValueMessage.fromObject(proto)['valueType']).to.equal('nullValue');
359364
expect(s.fromValue(proto)).to.equal(fieldValue.NullValue.INSTANCE);
360365
});
361366

362367
it('converts BooleanValue', () => {
363368
const examples = [true, false];
364369
for (const example of examples) {
365370
const proto = { booleanValue: example };
366-
expect(new ds.Value(proto).value_type).to.equal('booleanValue');
371+
expect(ValueMessage.fromObject(proto)['valueType']).to.equal(
372+
'booleanValue'
373+
);
367374
expect(s.fromValue(proto)).to.deep.equal(
368375
fieldValue.BooleanValue.of(example)
369376
);
@@ -382,7 +389,9 @@ describe('Serializer', () => {
382389
];
383390
for (const example of examples) {
384391
const proto: api.Value = { integerValue: '' + example };
385-
expect(new ds.Value(proto).value_type).to.equal('integerValue');
392+
expect(ValueMessage.fromObject(proto)['valueType']).to.equal(
393+
'integerValue'
394+
);
386395
expect(s.fromValue(proto)).to.deep.equal(
387396
new fieldValue.IntegerValue(example)
388397
);
@@ -404,7 +413,9 @@ describe('Serializer', () => {
404413
];
405414
for (const example of examples) {
406415
const proto = { doubleValue: example };
407-
expect(new ds.Value(proto).value_type).to.equal('doubleValue');
416+
expect(ValueMessage.fromObject(proto)['valueType']).to.equal(
417+
'doubleValue'
418+
);
408419
expect(s.fromValue(proto)).to.deep.equal(
409420
new fieldValue.DoubleValue(example)
410421
);
@@ -422,7 +433,9 @@ describe('Serializer', () => {
422433
];
423434
for (const example of examples) {
424435
const proto = { stringValue: example };
425-
expect(new ds.Value(proto).value_type).to.equal('stringValue');
436+
expect(ValueMessage.fromObject(proto)['valueType']).to.equal(
437+
'stringValue'
438+
);
426439
expect(s.fromValue(proto)).to.deep.equal(
427440
new fieldValue.StringValue(example)
428441
);
@@ -433,7 +446,9 @@ describe('Serializer', () => {
433446
const proto = {
434447
arrayValue: { values: [{ booleanValue: true }, { stringValue: 'foo' }] }
435448
};
436-
expect(new ds.Value(proto).value_type).to.equal('arrayValue');
449+
expect(ValueMessage.fromObject(proto)['valueType']).to.equal(
450+
'arrayValue'
451+
);
437452
expect(s.fromValue(proto)).to.deep.equal(
438453
new fieldValue.ArrayValue([
439454
fieldValue.BooleanValue.TRUE,
@@ -444,13 +459,17 @@ describe('Serializer', () => {
444459

445460
it('converts empty ArrayValue', () => {
446461
const proto = { arrayValue: {} };
447-
expect(new ds.Value(proto).value_type).to.equal('arrayValue');
462+
expect(ValueMessage.fromObject(proto)['valueType']).to.equal(
463+
'arrayValue'
464+
);
448465
expect(s.fromValue(proto)).to.deep.equal(new fieldValue.ArrayValue([]));
449466
});
450467

451468
it('converts ObjectValue.EMPTY', () => {
452469
const proto = { mapValue: { fields: {} } };
453-
expect(new ds.Value(proto).mapValue).to.deep.equal(new ds.MapValue());
470+
expect(ValueMessage.fromObject(proto)['mapValue']).to.deep.equal(
471+
MapValueMessage.fromObject({})
472+
);
454473
expect(s.fromValue(proto)).to.deep.equal(fieldValue.ObjectValue.EMPTY);
455474
});
456475

@@ -471,7 +490,9 @@ describe('Serializer', () => {
471490
// because the proto interface definition isn't comprehensive.
472491
// tslint:disable-next-line:no-any
473492
const proto: api.Value = { timestampValue: example as any };
474-
expect(new ds.Value(proto).value_type).to.equal('timestampValue');
493+
expect(ValueMessage.fromObject(proto)['valueType']).to.equal(
494+
'timestampValue'
495+
);
475496
expect(s.fromValue(proto)).to.deep.equal(
476497
new fieldValue.TimestampValue(Timestamp.fromDate(date))
477498
);

yarn.lock

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,14 @@
837837
through2 "^2.0.0"
838838
xdg-basedir "^3.0.0"
839839

840+
"@grpc/proto-loader@^0.4.0":
841+
version "0.4.0"
842+
resolved "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.4.0.tgz#a823a51eb2fde58369bef1deb5445fd808d70901"
843+
integrity sha512-Jm6o+75uWT7E6+lt8edg4J1F/9+BedOjaMgwE14pxS/AO43/0ZqK+rCLVVrXLoExwSAZvgvOD2B0ivy3Spsspw==
844+
dependencies:
845+
lodash.camelcase "^4.3.0"
846+
protobufjs "^6.8.6"
847+
840848
"@gulp-sourcemaps/[email protected]":
841849
version "1.0.2"
842850
resolved "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz#1e6fe5d8027b1f285dc0d31762f566bccd73d5a9"
@@ -1532,6 +1540,59 @@
15321540
universal-user-agent "^2.0.0"
15331541
url-template "^2.0.8"
15341542

1543+
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
1544+
version "1.1.2"
1545+
resolved "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
1546+
integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78=
1547+
1548+
"@protobufjs/base64@^1.1.2":
1549+
version "1.1.2"
1550+
resolved "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735"
1551+
integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==
1552+
1553+
"@protobufjs/codegen@^2.0.4":
1554+
version "2.0.4"
1555+
resolved "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb"
1556+
integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==
1557+
1558+
"@protobufjs/eventemitter@^1.1.0":
1559+
version "1.1.0"
1560+
resolved "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
1561+
integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A=
1562+
1563+
"@protobufjs/fetch@^1.1.0":
1564+
version "1.1.0"
1565+
resolved "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
1566+
integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=
1567+
dependencies:
1568+
"@protobufjs/aspromise" "^1.1.1"
1569+
"@protobufjs/inquire" "^1.1.0"
1570+
1571+
"@protobufjs/float@^1.0.2":
1572+
version "1.0.2"
1573+
resolved "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
1574+
integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=
1575+
1576+
"@protobufjs/inquire@^1.1.0":
1577+
version "1.1.0"
1578+
resolved "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
1579+
integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=
1580+
1581+
"@protobufjs/path@^1.1.2":
1582+
version "1.1.2"
1583+
resolved "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
1584+
integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=
1585+
1586+
"@protobufjs/pool@^1.1.0":
1587+
version "1.1.0"
1588+
resolved "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
1589+
integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=
1590+
1591+
"@protobufjs/utf8@^1.1.0":
1592+
version "1.1.0"
1593+
resolved "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
1594+
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
1595+
15351596
"@samverschueren/stream-to-observable@^0.3.0":
15361597
version "0.3.0"
15371598
resolved "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
@@ -1724,7 +1785,7 @@
17241785
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.106.tgz#6093e9a02aa567ddecfe9afadca89e53e5dce4dd"
17251786
integrity sha512-tOSvCVrvSqFZ4A/qrqqm6p37GZoawsZtoR0SJhlF7EonNZUgrn8FfT+RNQ11h+NUpMt6QVe36033f3qEKBwfWA==
17261787

1727-
1788+
"@types/[email protected]", "@types/long@^4.0.0":
17281789
version "4.0.0"
17291790
resolved "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef"
17301791
integrity sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==
@@ -1759,6 +1820,11 @@
17591820
resolved "https://registry.npmjs.org/@types/node/-/node-11.13.4.tgz#f83ec3c3e05b174b7241fadeb6688267fe5b22ca"
17601821
integrity sha512-+rabAZZ3Yn7tF/XPGHupKIL5EcAbrLxnTr/hgQICxbeuAfWtT0UZSfULE+ndusckBItcv4o6ZeOJplQikVcLvQ==
17611822

1823+
"@types/node@^10.1.0":
1824+
version "10.14.4"
1825+
resolved "https://registry.npmjs.org/@types/node/-/node-10.14.4.tgz#1c586b991457cbb58fef51bc4e0cfcfa347714b5"
1826+
integrity sha512-DT25xX/YgyPKiHFOpNuANIQIVvYEwCWXgK2jYYwqgaMrYE6+tq+DtmMwlD3drl6DJbUwtlIDnn0d7tIn/EbXBg==
1827+
17621828
17631829
version "2.48.1"
17641830
resolved "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz#e402d691aa6670fbbff1957b15f1270230ab42fa"
@@ -8893,6 +8959,11 @@ [email protected], long@~3:
88938959
resolved "https://registry.npmjs.org/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b"
88948960
integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=
88958961

8962+
long@^4.0.0:
8963+
version "4.0.0"
8964+
resolved "https://registry.npmjs.org/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
8965+
integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
8966+
88968967
longest@^1.0.1:
88978968
version "1.0.1"
88988969
resolved "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
@@ -10804,6 +10875,25 @@ proto-list@~1.2.1:
1080410875
resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
1080510876
integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
1080610877

10878+
[email protected], protobufjs@^6.8.6:
10879+
version "6.8.8"
10880+
resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c"
10881+
integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==
10882+
dependencies:
10883+
"@protobufjs/aspromise" "^1.1.2"
10884+
"@protobufjs/base64" "^1.1.2"
10885+
"@protobufjs/codegen" "^2.0.4"
10886+
"@protobufjs/eventemitter" "^1.1.0"
10887+
"@protobufjs/fetch" "^1.1.0"
10888+
"@protobufjs/float" "^1.0.2"
10889+
"@protobufjs/inquire" "^1.1.0"
10890+
"@protobufjs/path" "^1.1.2"
10891+
"@protobufjs/pool" "^1.1.0"
10892+
"@protobufjs/utf8" "^1.1.0"
10893+
"@types/long" "^4.0.0"
10894+
"@types/node" "^10.1.0"
10895+
long "^4.0.0"
10896+
1080710897
protobufjs@^5.0.3:
1080810898
version "5.0.3"
1080910899
resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz#e4dfe9fb67c90b2630d15868249bcc4961467a17"

0 commit comments

Comments
 (0)