ts-proto 1.105.2 → 1.106.2
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/CHANGELOG.md +21 -0
- package/build/main.js +25 -22
- package/build/utils.js +17 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
## [1.106.2](https://github.com/stephenh/ts-proto/compare/v1.106.1...v1.106.2) (2022-02-27)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Add M1/ARM support for the test suite ([#516](https://github.com/stephenh/ts-proto/issues/516)) ([7cf5625](https://github.com/stephenh/ts-proto/commit/7cf56251726d149eebd015367476f36e4edb48aa))
|
|
7
|
+
|
|
8
|
+
## [1.106.1](https://github.com/stephenh/ts-proto/compare/v1.106.0...v1.106.1) (2022-02-21)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* support json_name containing hyphen on all field types ([#521](https://github.com/stephenh/ts-proto/issues/521)) ([8d9e78e](https://github.com/stephenh/ts-proto/commit/8d9e78eb39c460f6727458f6a2dd149deb983668))
|
|
14
|
+
|
|
15
|
+
# [1.106.0](https://github.com/stephenh/ts-proto/compare/v1.105.2...v1.106.0) (2022-02-21)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* Support json names containing non-alphanumeric characters ([#520](https://github.com/stephenh/ts-proto/issues/520)) ([ce44668](https://github.com/stephenh/ts-proto/commit/ce44668b8fe01b14f50ac3c5c950f73db769fa76))
|
|
21
|
+
|
|
1
22
|
## [1.105.2](https://github.com/stephenh/ts-proto/compare/v1.105.1...v1.105.2) (2022-02-17)
|
|
2
23
|
|
|
3
24
|
|
package/build/main.js
CHANGED
|
@@ -895,7 +895,9 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
895
895
|
// add a check for each incoming field
|
|
896
896
|
messageDesc.field.forEach((field) => {
|
|
897
897
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
898
|
-
const jsonName = utils_1.
|
|
898
|
+
const jsonName = utils_1.getFieldJsonName(field, options);
|
|
899
|
+
const jsonProperty = utils_1.getPropertyAccessor('object', jsonName);
|
|
900
|
+
const jsonPropertyOptional = utils_1.getPropertyAccessor('object', jsonName, true);
|
|
899
901
|
// get code that extracts value from incoming object
|
|
900
902
|
const readSnippet = (from) => {
|
|
901
903
|
if (types_1.isEnum(field)) {
|
|
@@ -1013,8 +1015,8 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
1013
1015
|
const fieldType = types_1.toTypeName(ctx, messageDesc, field);
|
|
1014
1016
|
const i = maybeCastToNumber(ctx, messageDesc, field, 'key');
|
|
1015
1017
|
chunks.push(ts_poet_1.code `
|
|
1016
|
-
${fieldName}: ${ctx.utils.isObject}(
|
|
1017
|
-
? Object.entries(
|
|
1018
|
+
${fieldName}: ${ctx.utils.isObject}(${jsonProperty})
|
|
1019
|
+
? Object.entries(${jsonProperty}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
1018
1020
|
acc[${i}] = ${readSnippet('value')};
|
|
1019
1021
|
return acc;
|
|
1020
1022
|
}, {})
|
|
@@ -1024,12 +1026,12 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
1024
1026
|
else {
|
|
1025
1027
|
const readValueSnippet = readSnippet('e');
|
|
1026
1028
|
if (readValueSnippet.toString() === ts_poet_1.code `e`.toString()) {
|
|
1027
|
-
chunks.push(ts_poet_1.code `${fieldName}: Array.isArray(
|
|
1029
|
+
chunks.push(ts_poet_1.code `${fieldName}: Array.isArray(${jsonPropertyOptional}) ? [...${jsonProperty}] : [],`);
|
|
1028
1030
|
}
|
|
1029
1031
|
else {
|
|
1030
1032
|
// Explicit `any` type required to make TS with noImplicitAny happy. `object` is also `any` here.
|
|
1031
1033
|
chunks.push(ts_poet_1.code `
|
|
1032
|
-
${fieldName}: Array.isArray(
|
|
1034
|
+
${fieldName}: Array.isArray(${jsonPropertyOptional}) ? ${jsonProperty}.map((e: any) => ${readValueSnippet}): [],
|
|
1033
1035
|
`);
|
|
1034
1036
|
}
|
|
1035
1037
|
}
|
|
@@ -1042,36 +1044,36 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
1042
1044
|
const fieldName = case_1.maybeSnakeToCamel(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
1043
1045
|
chunks.push(ts_poet_1.code `${fieldName}: `);
|
|
1044
1046
|
}
|
|
1045
|
-
const ternaryIf = ts_poet_1.code `${ctx.utils.isSet}(
|
|
1046
|
-
const ternaryThen = ts_poet_1.code `{ $case: '${fieldName}', ${fieldName}: ${readSnippet(
|
|
1047
|
+
const ternaryIf = ts_poet_1.code `${ctx.utils.isSet}(${jsonProperty})`;
|
|
1048
|
+
const ternaryThen = ts_poet_1.code `{ $case: '${fieldName}', ${fieldName}: ${readSnippet(`${jsonProperty}`)}`;
|
|
1047
1049
|
chunks.push(ts_poet_1.code `${ternaryIf} ? ${ternaryThen}} : `);
|
|
1048
1050
|
if (field === lastCase) {
|
|
1049
1051
|
chunks.push(ts_poet_1.code `undefined,`);
|
|
1050
1052
|
}
|
|
1051
1053
|
}
|
|
1052
1054
|
else if (types_1.isAnyValueType(field)) {
|
|
1053
|
-
chunks.push(ts_poet_1.code `${fieldName}: ${ctx.utils.isSet}(
|
|
1054
|
-
? ${readSnippet(
|
|
1055
|
+
chunks.push(ts_poet_1.code `${fieldName}: ${ctx.utils.isSet}(${jsonPropertyOptional})
|
|
1056
|
+
? ${readSnippet(`${jsonProperty}`)}
|
|
1055
1057
|
: undefined,
|
|
1056
1058
|
`);
|
|
1057
1059
|
}
|
|
1058
1060
|
else if (types_1.isStructType(field)) {
|
|
1059
|
-
chunks.push(ts_poet_1.code `${fieldName}: ${ctx.utils.isObject}(
|
|
1060
|
-
? ${readSnippet(
|
|
1061
|
+
chunks.push(ts_poet_1.code `${fieldName}: ${ctx.utils.isObject}(${jsonProperty})
|
|
1062
|
+
? ${readSnippet(`${jsonProperty}`)}
|
|
1061
1063
|
: undefined,`);
|
|
1062
1064
|
}
|
|
1063
1065
|
else if (types_1.isListValueType(field)) {
|
|
1064
1066
|
chunks.push(ts_poet_1.code `
|
|
1065
|
-
${fieldName}: Array.isArray(
|
|
1066
|
-
? ${readSnippet(
|
|
1067
|
+
${fieldName}: Array.isArray(${jsonProperty})
|
|
1068
|
+
? ${readSnippet(`${jsonProperty}`)}
|
|
1067
1069
|
: undefined,
|
|
1068
1070
|
`);
|
|
1069
1071
|
}
|
|
1070
1072
|
else {
|
|
1071
1073
|
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
1072
1074
|
chunks.push(ts_poet_1.code `
|
|
1073
|
-
${fieldName}: ${ctx.utils.isSet}(
|
|
1074
|
-
? ${readSnippet(
|
|
1075
|
+
${fieldName}: ${ctx.utils.isSet}(${jsonProperty})
|
|
1076
|
+
? ${readSnippet(`${jsonProperty}`)}
|
|
1075
1077
|
: ${fallback},
|
|
1076
1078
|
`);
|
|
1077
1079
|
}
|
|
@@ -1092,7 +1094,8 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
1092
1094
|
// then add a case for each field
|
|
1093
1095
|
messageDesc.field.forEach((field) => {
|
|
1094
1096
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
1095
|
-
const jsonName = utils_1.
|
|
1097
|
+
const jsonName = utils_1.getFieldJsonName(field, options);
|
|
1098
|
+
const jsonProperty = utils_1.getPropertyAccessor('obj', jsonName);
|
|
1096
1099
|
const readSnippet = (from) => {
|
|
1097
1100
|
if (types_1.isEnum(field)) {
|
|
1098
1101
|
const toJson = types_1.getEnumMethod(ctx, field.typeName, 'ToJSON');
|
|
@@ -1183,10 +1186,10 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
1183
1186
|
if (types_1.isMapType(ctx, messageDesc, field)) {
|
|
1184
1187
|
// Maps might need their values transformed, i.e. bytes --> base64
|
|
1185
1188
|
chunks.push(ts_poet_1.code `
|
|
1186
|
-
|
|
1189
|
+
${jsonProperty} = {};
|
|
1187
1190
|
if (message.${fieldName}) {
|
|
1188
1191
|
Object.entries(message.${fieldName}).forEach(([k, v]) => {
|
|
1189
|
-
|
|
1192
|
+
${jsonProperty}[k] = ${readSnippet('v')};
|
|
1190
1193
|
});
|
|
1191
1194
|
}
|
|
1192
1195
|
`);
|
|
@@ -1195,9 +1198,9 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
1195
1198
|
// Arrays might need their elements transformed
|
|
1196
1199
|
chunks.push(ts_poet_1.code `
|
|
1197
1200
|
if (message.${fieldName}) {
|
|
1198
|
-
|
|
1201
|
+
${jsonProperty} = message.${fieldName}.map(e => ${readSnippet('e')});
|
|
1199
1202
|
} else {
|
|
1200
|
-
|
|
1203
|
+
${jsonProperty} = [];
|
|
1201
1204
|
}
|
|
1202
1205
|
`);
|
|
1203
1206
|
}
|
|
@@ -1205,11 +1208,11 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
1205
1208
|
// oneofs in a union are only output as `oneof name = ...`
|
|
1206
1209
|
const oneofName = case_1.maybeSnakeToCamel(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
1207
1210
|
const v = readSnippet(`message.${oneofName}?.${fieldName}`);
|
|
1208
|
-
chunks.push(ts_poet_1.code `message.${oneofName}?.$case === '${fieldName}' && (
|
|
1211
|
+
chunks.push(ts_poet_1.code `message.${oneofName}?.$case === '${fieldName}' && (${jsonProperty} = ${v});`);
|
|
1209
1212
|
}
|
|
1210
1213
|
else {
|
|
1211
1214
|
const v = readSnippet(`message.${fieldName}`);
|
|
1212
|
-
chunks.push(ts_poet_1.code `message.${fieldName} !== undefined && (
|
|
1215
|
+
chunks.push(ts_poet_1.code `message.${fieldName} !== undefined && (${jsonProperty} = ${v});`);
|
|
1213
1216
|
}
|
|
1214
1217
|
});
|
|
1215
1218
|
chunks.push(ts_poet_1.code `return obj;`);
|
package/build/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.impProto = exports.
|
|
3
|
+
exports.impProto = exports.getPropertyAccessor = exports.getFieldJsonName = exports.FormattedMethodDescriptor = exports.assertInstanceOf = exports.maybePrefixPackage = exports.prefixDisableLinter = exports.maybeAddComment = exports.upperFirst = exports.lowerFirst = exports.singular = exports.fail = exports.readToBuffer = exports.protoFilesToGenerate = void 0;
|
|
4
4
|
const ts_poet_1 = require("ts-poet");
|
|
5
5
|
const options_1 = require("./options");
|
|
6
6
|
const case_1 = require("./case");
|
|
@@ -144,7 +144,7 @@ class FormattedMethodDescriptor {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
exports.FormattedMethodDescriptor = FormattedMethodDescriptor;
|
|
147
|
-
function
|
|
147
|
+
function getFieldJsonName(field, options) {
|
|
148
148
|
// jsonName will be camelCased by the protocol compiler, plus can be overridden by the user,
|
|
149
149
|
// so just use that instead of our own maybeSnakeToCamel
|
|
150
150
|
if (options.snakeToCamel.includes('json')) {
|
|
@@ -154,7 +154,21 @@ function determineFieldJsonName(field, options) {
|
|
|
154
154
|
return field.name;
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
|
-
exports.
|
|
157
|
+
exports.getFieldJsonName = getFieldJsonName;
|
|
158
|
+
/**
|
|
159
|
+
* Returns a snippet for reading an object's property, such as `foo.bar`, or `foo['bar']` if the property name contains unusual characters.
|
|
160
|
+
* For simplicity, we don't match the ECMA 5/6 rules for valid identifiers exactly, and return array syntax liberally.
|
|
161
|
+
* @param objectName
|
|
162
|
+
* @param propertyName
|
|
163
|
+
* @param optional
|
|
164
|
+
*/
|
|
165
|
+
function getPropertyAccessor(objectName, propertyName, optional = false) {
|
|
166
|
+
let validIdentifier = /^[a-zA-Z_$][\w$]*$/;
|
|
167
|
+
return validIdentifier.test(propertyName)
|
|
168
|
+
? `${objectName}${optional ? '?' : ''}.${propertyName}`
|
|
169
|
+
: `${objectName}${optional ? '?.' : ''}[${JSON.stringify(propertyName)}]`;
|
|
170
|
+
}
|
|
171
|
+
exports.getPropertyAccessor = getPropertyAccessor;
|
|
158
172
|
function impProto(options, module, type) {
|
|
159
173
|
return ts_poet_1.imp(`${type}@./${module}${options.fileSuffix}`);
|
|
160
174
|
}
|