From dc22c68727047db1849c118a97f6a098a5bff11a Mon Sep 17 00:00:00 2001 From: Luke Thomas Date: Sat, 12 Jan 2019 13:43:19 -0600 Subject: [PATCH 1/2] Add support for jstype options --- .../lib/format/partial/FieldTypesFormatter.js | 11 +++++++++++ build/lib/format/partial/MessageFormatter.js | 11 ++++++++++- src/lib/format/partial/FieldTypesFormatter.ts | 18 +++++++++++++++++- src/lib/format/partial/MessageFormatter.ts | 12 +++++++++++- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/build/lib/format/partial/FieldTypesFormatter.js b/build/lib/format/partial/FieldTypesFormatter.js index e295d59..cc87fac 100644 --- a/build/lib/format/partial/FieldTypesFormatter.js +++ b/build/lib/format/partial/FieldTypesFormatter.js @@ -4,6 +4,9 @@ const Utility_1 = require("../../Utility"); exports.MESSAGE_TYPE = 11; exports.BYTES_TYPE = 12; exports.ENUM_TYPE = 14; +exports.JS_NORMAL = 0; +exports.JS_STRING = 1; +exports.JS_NUMBER = 2; const TypeNumToTypeString = {}; TypeNumToTypeString[1] = "number"; // TYPE_DOUBLE TypeNumToTypeString[2] = "number"; // TYPE_FLOAT @@ -23,12 +26,20 @@ TypeNumToTypeString[15] = "number"; // TYPE_SFIXED32 TypeNumToTypeString[16] = "number"; // TYPE_SFIXED64 TypeNumToTypeString[17] = "number"; // TYPE_SINT32 - Uses ZigZag encoding. TypeNumToTypeString[18] = "number"; // TYPE_SINT64 - Uses ZigZag encoding. +const JsTypeNumToTypeString = {}; +JsTypeNumToTypeString[exports.JS_NORMAL] = null; // [jstype = JS_NORMAL] +JsTypeNumToTypeString[exports.JS_STRING] = "string"; // [jstype = JS_STRING] +JsTypeNumToTypeString[exports.JS_NUMBER] = "number"; // [jstype = JS_NUMBER] var FieldTypesFormatter; (function (FieldTypesFormatter) { function getTypeName(fieldTypeNum) { return TypeNumToTypeString[fieldTypeNum]; } FieldTypesFormatter.getTypeName = getTypeName; + function getJsTypeName(fieldTypeNum) { + return fieldTypeNum === exports.JS_NORMAL ? null : JsTypeNumToTypeString[fieldTypeNum]; + } + FieldTypesFormatter.getJsTypeName = getJsTypeName; function getFieldType(type, typeName, currentFileName, exportMap) { let fieldType; let fromExport; diff --git a/build/lib/format/partial/MessageFormatter.js b/build/lib/format/partial/MessageFormatter.js index 8087b9b..e075b66 100644 --- a/build/lib/format/partial/MessageFormatter.js +++ b/build/lib/format/partial/MessageFormatter.js @@ -131,7 +131,16 @@ var MessageFormatter; fieldData.exportType = exportType; } else { - exportType = fieldData.exportType = FieldTypesFormatter_1.FieldTypesFormatter.getTypeName(fieldData.type); + let type = FieldTypesFormatter_1.FieldTypesFormatter.getTypeName(fieldData.type); + // Check for [jstype = JS_STRING] overrides + const options = field.getOptions(); + if (options && options.hasJstype()) { + const jstype = FieldTypesFormatter_1.FieldTypesFormatter.getJsTypeName(options.getJstype()); + if (jstype) { + type = jstype; + } + } + exportType = fieldData.exportType = type; } fieldData.isOptionalValue = field.getType() === FieldTypesFormatter_1.MESSAGE_TYPE; fieldData.isRepeatField = field.getLabel() === descriptor_pb_1.FieldDescriptorProto.Label.LABEL_REPEATED; diff --git a/src/lib/format/partial/FieldTypesFormatter.ts b/src/lib/format/partial/FieldTypesFormatter.ts index 80ba0a7..0a81ce7 100644 --- a/src/lib/format/partial/FieldTypesFormatter.ts +++ b/src/lib/format/partial/FieldTypesFormatter.ts @@ -5,8 +5,15 @@ import {Utility} from "../../Utility"; export const MESSAGE_TYPE = 11; export const BYTES_TYPE = 12; export const ENUM_TYPE = 14; +export const JS_NORMAL = 0; +export const JS_STRING = 1; +export const JS_NUMBER = 2; -const TypeNumToTypeString: { [key: number]: string } = {}; +interface TypeMap { + [key: number]: string +} + +const TypeNumToTypeString = {}; TypeNumToTypeString[1] = "number"; // TYPE_DOUBLE TypeNumToTypeString[2] = "number"; // TYPE_FLOAT TypeNumToTypeString[3] = "number"; // TYPE_INT64 @@ -26,12 +33,21 @@ TypeNumToTypeString[16] = "number"; // TYPE_SFIXED64 TypeNumToTypeString[17] = "number"; // TYPE_SINT32 - Uses ZigZag encoding. TypeNumToTypeString[18] = "number"; // TYPE_SINT64 - Uses ZigZag encoding. +const JsTypeNumToTypeString = {}; +JsTypeNumToTypeString[JS_NORMAL] = null; // [jstype = JS_NORMAL] +JsTypeNumToTypeString[JS_STRING] = "string"; // [jstype = JS_STRING] +JsTypeNumToTypeString[JS_NUMBER] = "number"; // [jstype = JS_NUMBER] + export namespace FieldTypesFormatter { export function getTypeName(fieldTypeNum: number): string { return TypeNumToTypeString[fieldTypeNum]; } + export function getJsTypeName(fieldTypeNum: number): string { + return fieldTypeNum === JS_NORMAL ? null : JsTypeNumToTypeString[fieldTypeNum]; + } + export function getFieldType(type: FieldDescriptorProto.Type, typeName: string, currentFileName: string, diff --git a/src/lib/format/partial/MessageFormatter.ts b/src/lib/format/partial/MessageFormatter.ts index 54c606e..4ffd7a1 100644 --- a/src/lib/format/partial/MessageFormatter.ts +++ b/src/lib/format/partial/MessageFormatter.ts @@ -192,8 +192,18 @@ export namespace MessageFormatter { fieldData.exportType = exportType; } else { + let type = FieldTypesFormatter.getTypeName(fieldData.type); + + // Check for [jstype = JS_STRING] overrides + const options = field.getOptions() + if (options && options.hasJstype()) { + const jstype = FieldTypesFormatter.getJsTypeName(options.getJstype()); + if (jstype) { + type = jstype + } + } - exportType = fieldData.exportType = FieldTypesFormatter.getTypeName(fieldData.type); + exportType = fieldData.exportType = type } From 5881b1ad8bccd14465567c689836818ccf22d68a Mon Sep 17 00:00:00 2001 From: Luke Thomas Date: Sat, 12 Jan 2019 13:43:27 -0600 Subject: [PATCH 2/2] Update README --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index dcd43a0..9333ce7 100644 --- a/README.md +++ b/README.md @@ -357,7 +357,39 @@ export class BookServiceClient extends grpc.Client implements IBookServiceClient } ``` +## Gotchas + +JavaScript can safely handle numbers below `Number.MAX_SAFE_INTEGER`. Beyond the +limit, it begins to overflow: + +``` +> 90071992547409912131 + 1 +90071992547409920000 +``` + +If you are expecting large, 64bit fields consider using a `jstype` option to +override the field type. + +```proto +# example.proto +message Example { + fixed64 id = 1 [jstype = JS_STRING]; +} +``` + +```typescript +// example_pb.d.ts +export namespace Example { + export type AsObject = { + id: string + } +} +``` + ## Changes +### 2.4.3 +Add support for `[jstype = JS_STRING]` overrides + ### 2.4.2 Update grpc version in package.json of examples, to keep consistent. Update handlebars-helpers version to 0.10.0 to fix vulnerability version of randomatic.