ts-proto 1.158.0 → 1.159.0

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.
package/README.markdown CHANGED
@@ -289,6 +289,10 @@ Generated code will be placed in the Gradle build directory.
289
289
 
290
290
  ### Supported options
291
291
 
292
+ - With `--ts_proto_opt=globalThisPolyfill=true`, ts-proto will include a polyfill for globalThis.
293
+
294
+ Defaults to `false`, i.e. we assume `globalThis` is available.
295
+
292
296
  - With `--ts_proto_opt=context=true`, the services will have a Go-style `ctx` parameter, which is useful for tracing/logging/etc. if you're not using node's `async_hooks` api due to performance reasons.
293
297
 
294
298
  - With `--ts_proto_opt=forceLong=long`, all 64-bit numbers will be parsed as instances of `Long` (using the [long](https://www.npmjs.com/package/long) library).
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateDecodeTransform = exports.generateEncodeTransform = void 0;
4
4
  const ts_poet_1 = require("ts-poet");
5
5
  /** Creates a function to transform a message Source to a Uint8Array Source. */
6
- function generateEncodeTransform(fullName) {
6
+ function generateEncodeTransform(utils, fullName) {
7
7
  return (0, ts_poet_1.code) `
8
8
  // encodeTransform encodes a source of message objects.
9
9
  // Transform<${fullName}, Uint8Array>
@@ -11,12 +11,12 @@ function generateEncodeTransform(fullName) {
11
11
  source: AsyncIterable<${fullName} | ${fullName}[]> | Iterable<${fullName} | ${fullName}[]>
12
12
  ): AsyncIterable<Uint8Array> {
13
13
  for await (const pkt of source) {
14
- if (Array.isArray(pkt)) {
15
- for (const p of pkt) {
14
+ if (${utils.globalThis}.Array.isArray(pkt)) {
15
+ for (const p of (pkt as any)) {
16
16
  yield* [${fullName}.encode(p).finish()]
17
17
  }
18
18
  } else {
19
- yield* [${fullName}.encode(pkt).finish()]
19
+ yield* [${fullName}.encode(pkt as any).finish()]
20
20
  }
21
21
  }
22
22
  }
@@ -24,7 +24,7 @@ function generateEncodeTransform(fullName) {
24
24
  }
25
25
  exports.generateEncodeTransform = generateEncodeTransform;
26
26
  /** Creates a function to transform a Uint8Array Source to a message Source. */
27
- function generateDecodeTransform(fullName) {
27
+ function generateDecodeTransform(utils, fullName) {
28
28
  return (0, ts_poet_1.code) `
29
29
  // decodeTransform decodes a source of encoded messages.
30
30
  // Transform<Uint8Array, ${fullName}>
@@ -32,12 +32,12 @@ function generateDecodeTransform(fullName) {
32
32
  source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>
33
33
  ): AsyncIterable<${fullName}> {
34
34
  for await (const pkt of source) {
35
- if (Array.isArray(pkt)) {
36
- for (const p of pkt) {
35
+ if (${utils.globalThis}.Array.isArray(pkt)) {
36
+ for (const p of (pkt as any)) {
37
37
  yield* [${fullName}.decode(p)]
38
38
  }
39
39
  } else {
40
- yield* [${fullName}.decode(pkt)]
40
+ yield* [${fullName}.decode(pkt as any)]
41
41
  }
42
42
  }
43
43
  }
@@ -46,7 +46,7 @@ function generateWrapDeep(ctx, fullProtoTypeName, fieldNames) {
46
46
  result.${fieldNames.numberValue} = value;
47
47
  } else if (typeof value === 'string') {
48
48
  result.${fieldNames.stringValue} = value;
49
- } else if (Array.isArray(value)) {
49
+ } else if (${ctx.utils.globalThis}.Array.isArray(value)) {
50
50
  result.${fieldNames.listValue} = ListValue.wrap(value);
51
51
  } else if (typeof value === 'object') {
52
52
  result.${fieldNames.structValue} = Struct.wrap(value);
@@ -126,7 +126,7 @@ function generateUnwrapDeep(ctx, fullProtoTypeName, fieldNames) {
126
126
  }
127
127
  if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
128
128
  chunks.push((0, ts_poet_1.code) `unwrap(message: ${ctx.options.useReadonlyTypes ? "any" : "ListValue"}): Array<any> {
129
- if (message?.hasOwnProperty('values') && Array.isArray(message.values)) {
129
+ if (message?.hasOwnProperty('values') && ${ctx.utils.globalThis}.Array.isArray(message.values)) {
130
130
  return message.values.map(Value.unwrap);
131
131
  } else {
132
132
  return message as any;
@@ -175,7 +175,7 @@ function generateWrapShallow(ctx, fullProtoTypeName, fieldNames) {
175
175
  result.kind = {$case: '${fieldNames.numberValue}', ${fieldNames.numberValue}: value};
176
176
  } else if (typeof value === 'string') {
177
177
  result.kind = {$case: '${fieldNames.stringValue}', ${fieldNames.stringValue}: value};
178
- } else if (Array.isArray(value)) {
178
+ } else if (${ctx.utils.globalThis}.Array.isArray(value)) {
179
179
  result.kind = {$case: '${fieldNames.listValue}', ${fieldNames.listValue}: value};
180
180
  } else if (typeof value === 'object') {
181
181
  result.kind = {$case: '${fieldNames.structValue}', ${fieldNames.structValue}: value};
@@ -196,7 +196,7 @@ function generateWrapShallow(ctx, fullProtoTypeName, fieldNames) {
196
196
  result.${fieldNames.numberValue} = value;
197
197
  } else if (typeof value === 'string') {
198
198
  result.${fieldNames.stringValue} = value;
199
- } else if (Array.isArray(value)) {
199
+ } else if (${ctx.utils.globalThis}.Array.isArray(value)) {
200
200
  result.${fieldNames.listValue} = value;
201
201
  } else if (typeof value === 'object') {
202
202
  result.${fieldNames.structValue} = value;
@@ -295,7 +295,7 @@ function generateUnwrapShallow(ctx, fullProtoTypeName, fieldNames) {
295
295
  }
296
296
  if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
297
297
  chunks.push((0, ts_poet_1.code) `unwrap(message: ${ctx.options.useReadonlyTypes ? "any" : "ListValue"}): Array<any> {
298
- if (message?.hasOwnProperty('values') && Array.isArray(message.values)) {
298
+ if (message?.hasOwnProperty('values') && ${ctx.utils.globalThis}.Array.isArray(message.values)) {
299
299
  return message.values;
300
300
  } else {
301
301
  return message as any;
package/build/main.js CHANGED
@@ -121,8 +121,8 @@ function generateFile(ctx, fileDesc) {
121
121
  }
122
122
  }
123
123
  if (options.useAsyncIterable) {
124
- staticMembers.push((0, generate_async_iterable_1.generateEncodeTransform)(fullName));
125
- staticMembers.push((0, generate_async_iterable_1.generateDecodeTransform)(fullName));
124
+ staticMembers.push((0, generate_async_iterable_1.generateEncodeTransform)(ctx.utils, fullName));
125
+ staticMembers.push((0, generate_async_iterable_1.generateDecodeTransform)(ctx.utils, fullName));
126
126
  }
127
127
  if (options.outputJsonMethods) {
128
128
  if (options.outputJsonMethods === true || options.outputJsonMethods === "from-only") {
@@ -273,13 +273,13 @@ function generateFile(ctx, fileDesc) {
273
273
  exports.generateFile = generateFile;
274
274
  /** These are runtime utility methods used by the generated code. */
275
275
  function makeUtils(options) {
276
- const bytes = makeByteUtils();
276
+ const bytes = makeByteUtils(options);
277
277
  const longs = makeLongUtils(options, bytes);
278
278
  return {
279
279
  ...bytes,
280
280
  ...makeDeepPartial(options, longs),
281
281
  ...makeObjectIdMethods(),
282
- ...makeTimestampMethods(options, longs),
282
+ ...makeTimestampMethods(options, longs, bytes),
283
283
  ...longs,
284
284
  ...makeComparisonUtils(),
285
285
  ...makeNiceGrpcServerStreamingMethodResult(),
@@ -346,7 +346,7 @@ function makeLongUtils(options, bytes) {
346
346
  `);
347
347
  const longToNumber = (0, ts_poet_1.conditionalOutput)("longToNumber", (0, ts_poet_1.code) `
348
348
  function longToNumber(long: ${Long}): number {
349
- if (long.gt(Number.MAX_SAFE_INTEGER)) {
349
+ if (long.gt(${bytes.globalThis}.Number.MAX_SAFE_INTEGER)) {
350
350
  throw new ${bytes.globalThis}.Error("Value is larger than Number.MAX_SAFE_INTEGER")
351
351
  }
352
352
  return long.toNumber();
@@ -354,12 +354,12 @@ function makeLongUtils(options, bytes) {
354
354
  `);
355
355
  return { numberToLong, longToNumber, longToString, longToBigint, Long };
356
356
  }
357
- function makeByteUtils() {
358
- const globalThis = (0, ts_poet_1.conditionalOutput)("tsProtoGlobalThis", (0, ts_poet_1.code) `
357
+ function makeByteUtils(options) {
358
+ const globalThisPolyfill = (0, ts_poet_1.conditionalOutput)("gt", (0, ts_poet_1.code) `
359
359
  declare const self: any | undefined;
360
360
  declare const window: any | undefined;
361
361
  declare const global: any | undefined;
362
- const tsProtoGlobalThis: any = (() => {
362
+ const gt: any = (() => {
363
363
  if (typeof globalThis !== "undefined") return globalThis;
364
364
  if (typeof self !== "undefined") return self;
365
365
  if (typeof window !== "undefined") return window;
@@ -367,6 +367,7 @@ function makeByteUtils() {
367
367
  throw "Unable to locate global object";
368
368
  })();
369
369
  `);
370
+ const globalThis = options.globalThisPolyfill ? globalThisPolyfill : (0, ts_poet_1.conditionalOutput)("globalThis", (0, ts_poet_1.code) ``);
370
371
  const bytesFromBase64 = (0, ts_poet_1.conditionalOutput)("bytesFromBase64", (0, ts_poet_1.code) `
371
372
  function bytesFromBase64(b64: string): Uint8Array {
372
373
  if (${globalThis}.Buffer) {
@@ -388,7 +389,7 @@ function makeByteUtils() {
388
389
  } else {
389
390
  const bin: string[] = [];
390
391
  arr.forEach((byte) => {
391
- bin.push(String.fromCharCode(byte));
392
+ bin.push(${globalThis}.String.fromCharCode(byte));
392
393
  });
393
394
  return ${globalThis}.btoa(bin.join(''));
394
395
  }
@@ -459,7 +460,7 @@ function makeObjectIdMethods() {
459
460
  `);
460
461
  return { fromJsonObjectId, fromProtoObjectId, toProtoObjectId };
461
462
  }
462
- function makeTimestampMethods(options, longs) {
463
+ function makeTimestampMethods(options, longs, bytes) {
463
464
  const Timestamp = (0, utils_1.impProto)(options, "google/protobuf/timestamp", "Timestamp");
464
465
  let seconds = "date.getTime() / 1_000";
465
466
  let toNumberCode = "t.seconds";
@@ -468,11 +469,11 @@ function makeTimestampMethods(options, longs) {
468
469
  seconds = (0, ts_poet_1.code) `${longs.numberToLong}(date.getTime() / 1_000)`;
469
470
  }
470
471
  else if (options.forceLong === options_1.LongOption.BIGINT) {
471
- toNumberCode = "Number(t.seconds.toString())";
472
+ toNumberCode = (0, ts_poet_1.code) `${bytes.globalThis}.Number(t.seconds.toString())`;
472
473
  seconds = (0, ts_poet_1.code) `BigInt(Math.trunc(date.getTime() / 1_000))`;
473
474
  }
474
475
  else if (options.forceLong === options_1.LongOption.STRING) {
475
- toNumberCode = "Number(t.seconds)";
476
+ toNumberCode = (0, ts_poet_1.code) `${bytes.globalThis}.Number(t.seconds)`;
476
477
  // Must discard the fractional piece here
477
478
  // Otherwise the fraction ends up on the seconds when parsed as a Long
478
479
  // (note this only occurs when the string is > 8 characters)
@@ -482,7 +483,7 @@ function makeTimestampMethods(options, longs) {
482
483
  const toTimestamp = (0, ts_poet_1.conditionalOutput)("toTimestamp", options.useDate === options_1.DateOption.STRING
483
484
  ? (0, ts_poet_1.code) `
484
485
  function toTimestamp(dateStr: string): ${Timestamp} {
485
- const date = new Date(dateStr);
486
+ const date = new ${bytes.globalThis}.Date(dateStr);
486
487
  const seconds = ${seconds};
487
488
  const nanos = (date.getTime() % 1_000) * 1_000_000;
488
489
  return { ${maybeTypeField} seconds, nanos };
@@ -500,23 +501,23 @@ function makeTimestampMethods(options, longs) {
500
501
  function fromTimestamp(t: ${Timestamp}): string {
501
502
  let millis = (${toNumberCode} || 0) * 1_000;
502
503
  millis += (t.nanos || 0) / 1_000_000;
503
- return new Date(millis).toISOString();
504
+ return new ${bytes.globalThis}.Date(millis).toISOString();
504
505
  }
505
506
  `
506
507
  : (0, ts_poet_1.code) `
507
508
  function fromTimestamp(t: ${Timestamp}): Date {
508
509
  let millis = (${toNumberCode} || 0) * 1_000;
509
510
  millis += (t.nanos || 0) / 1_000_000;
510
- return new Date(millis);
511
+ return new ${bytes.globalThis}.Date(millis);
511
512
  }
512
513
  `);
513
514
  const fromJsonTimestamp = (0, ts_poet_1.conditionalOutput)("fromJsonTimestamp", options.useDate === options_1.DateOption.DATE
514
515
  ? (0, ts_poet_1.code) `
515
516
  function fromJsonTimestamp(o: any): Date {
516
- if (o instanceof Date) {
517
+ if (o instanceof ${bytes.globalThis}.Date) {
517
518
  return o;
518
519
  } else if (typeof o === "string") {
519
- return new Date(o);
520
+ return new ${bytes.globalThis}.Date(o);
520
521
  } else {
521
522
  return ${fromTimestamp}(Timestamp.fromJSON(o));
522
523
  }
@@ -524,10 +525,10 @@ function makeTimestampMethods(options, longs) {
524
525
  `
525
526
  : (0, ts_poet_1.code) `
526
527
  function fromJsonTimestamp(o: any): Timestamp {
527
- if (o instanceof Date) {
528
+ if (o instanceof ${bytes.globalThis}.Date) {
528
529
  return ${toTimestamp}(o);
529
530
  } else if (typeof o === "string") {
530
- return ${toTimestamp}(new Date(o));
531
+ return ${toTimestamp}(new ${bytes.globalThis}.Date(o));
531
532
  } else {
532
533
  return Timestamp.fromJSON(o);
533
534
  }
@@ -1399,9 +1400,9 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1399
1400
  const canonicalFromJson = {
1400
1401
  ["google.protobuf.FieldMask"]: {
1401
1402
  paths: (from) => (0, ts_poet_1.code) `typeof(${from}) === 'string'
1402
- ? ${from}.split(",").filter(Boolean)
1403
- : Array.isArray(${from}?.paths)
1404
- ? ${from}.paths.map(String)
1403
+ ? ${from}.split(",").filter(${ctx.utils.globalThis}.Boolean)
1404
+ : ${ctx.utils.globalThis}.Array.isArray(${from}?.paths)
1405
+ ? ${from}.paths.map(${ctx.utils.globalThis}.String)
1405
1406
  : []`,
1406
1407
  },
1407
1408
  };
@@ -1444,7 +1445,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1444
1445
  return (0, ts_poet_1.code) `${utils.fromJsonObjectId}(${from})`;
1445
1446
  }
1446
1447
  else if ((0, types_1.isTimestamp)(field) && options.useDate === options_1.DateOption.STRING) {
1447
- return (0, ts_poet_1.code) `String(${from})`;
1448
+ return (0, ts_poet_1.code) `${utils.globalThis}.String(${from})`;
1448
1449
  }
1449
1450
  else if ((0, types_1.isTimestamp)(field) &&
1450
1451
  (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.TIMESTAMP)) {
@@ -1507,7 +1508,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1507
1508
  return (0, ts_poet_1.code) `${utils.fromJsonObjectId}(${from})`;
1508
1509
  }
1509
1510
  else if ((0, types_1.isTimestamp)(valueField) && options.useDate === options_1.DateOption.STRING) {
1510
- return (0, ts_poet_1.code) `String(${from})`;
1511
+ return (0, ts_poet_1.code) `${utils.globalThis}.String(${from})`;
1511
1512
  }
1512
1513
  else if ((0, types_1.isTimestamp)(valueField) &&
1513
1514
  (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.TIMESTAMP)) {
@@ -1568,12 +1569,12 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1568
1569
  const fallback = noDefaultValue ? "undefined" : "[]";
1569
1570
  const readValueSnippet = readSnippet("e");
1570
1571
  if (readValueSnippet.toString() === (0, ts_poet_1.code) `e`.toString()) {
1571
- chunks.push((0, ts_poet_1.code) `${fieldName}: Array.isArray(${jsonPropertyOptional}) ? [...${jsonProperty}] : [],`);
1572
+ chunks.push((0, ts_poet_1.code) `${fieldName}: ${ctx.utils.globalThis}.Array.isArray(${jsonPropertyOptional}) ? [...${jsonProperty}] : [],`);
1572
1573
  }
1573
1574
  else {
1574
1575
  // Explicit `any` type required to make TS with noImplicitAny happy. `object` is also `any` here.
1575
1576
  chunks.push((0, ts_poet_1.code) `
1576
- ${fieldName}: Array.isArray(${jsonPropertyOptional}) ? ${jsonProperty}.map((e: any) => ${readValueSnippet}): ${fallback},
1577
+ ${fieldName}: ${ctx.utils.globalThis}.Array.isArray(${jsonPropertyOptional}) ? ${jsonProperty}.map((e: any) => ${readValueSnippet}): ${fallback},
1577
1578
  `);
1578
1579
  }
1579
1580
  }
@@ -1606,7 +1607,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1606
1607
  }
1607
1608
  else if ((0, types_1.isListValueType)(field)) {
1608
1609
  chunks.push((0, ts_poet_1.code) `
1609
- ${fieldName}: Array.isArray(${jsonProperty})
1610
+ ${fieldName}: ${ctx.utils.globalThis}.Array.isArray(${jsonProperty})
1610
1611
  ? ${readSnippet(`${jsonProperty}`)}
1611
1612
  : undefined,
1612
1613
  `);
@@ -1988,14 +1989,14 @@ function convertFromObjectKey(ctx, messageDesc, field, variableName) {
1988
1989
  return (0, ts_poet_1.code) `BigInt(${variableName})`;
1989
1990
  }
1990
1991
  else if (ctx.options.forceLong === options_1.LongOption.STRING) {
1991
- return (0, ts_poet_1.code) `String(${variableName})`;
1992
+ return (0, ts_poet_1.code) `${ctx.utils.globalThis}.String(${variableName})`;
1992
1993
  }
1993
1994
  else {
1994
- return (0, ts_poet_1.code) `Number(${variableName})`;
1995
+ return (0, ts_poet_1.code) `${ctx.utils.globalThis}.Number(${variableName})`;
1995
1996
  }
1996
1997
  }
1997
1998
  else {
1998
- return (0, ts_poet_1.code) `Number(${variableName})`;
1999
+ return (0, ts_poet_1.code) `${ctx.utils.globalThis}.Number(${variableName})`;
1999
2000
  }
2000
2001
  }
2001
2002
  function convertToObjectKey(ctx, messageDesc, field, variableName) {
package/build/options.js CHANGED
@@ -38,6 +38,7 @@ function defaultOptions() {
38
38
  context: false,
39
39
  snakeToCamel: ["json", "keys"],
40
40
  emitDefaultValues: [],
41
+ globalThisPolyfill: false,
41
42
  forceLong: LongOption.NUMBER,
42
43
  useOptionals: "none",
43
44
  useDate: DateOption.DATE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.158.0",
3
+ "version": "1.159.0",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",