ts-proto 1.105.2 → 1.106.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/CHANGELOG.md +7 -0
- package/build/main.js +19 -17
- package/build/utils.js +16 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.106.0](https://github.com/stephenh/ts-proto/compare/v1.105.2...v1.106.0) (2022-02-21)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* 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))
|
|
7
|
+
|
|
1
8
|
## [1.105.2](https://github.com/stephenh/ts-proto/compare/v1.105.1...v1.105.2) (2022-02-17)
|
|
2
9
|
|
|
3
10
|
|
package/build/main.js
CHANGED
|
@@ -895,7 +895,8 @@ 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);
|
|
899
900
|
// get code that extracts value from incoming object
|
|
900
901
|
const readSnippet = (from) => {
|
|
901
902
|
if (types_1.isEnum(field)) {
|
|
@@ -1013,8 +1014,8 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
1013
1014
|
const fieldType = types_1.toTypeName(ctx, messageDesc, field);
|
|
1014
1015
|
const i = maybeCastToNumber(ctx, messageDesc, field, 'key');
|
|
1015
1016
|
chunks.push(ts_poet_1.code `
|
|
1016
|
-
${fieldName}: ${ctx.utils.isObject}(
|
|
1017
|
-
? Object.entries(
|
|
1017
|
+
${fieldName}: ${ctx.utils.isObject}(${jsonProperty})
|
|
1018
|
+
? Object.entries(${jsonProperty}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
1018
1019
|
acc[${i}] = ${readSnippet('value')};
|
|
1019
1020
|
return acc;
|
|
1020
1021
|
}, {})
|
|
@@ -1024,12 +1025,12 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
1024
1025
|
else {
|
|
1025
1026
|
const readValueSnippet = readSnippet('e');
|
|
1026
1027
|
if (readValueSnippet.toString() === ts_poet_1.code `e`.toString()) {
|
|
1027
|
-
chunks.push(ts_poet_1.code `${fieldName}: Array.isArray(object?.${jsonName}) ? [
|
|
1028
|
+
chunks.push(ts_poet_1.code `${fieldName}: Array.isArray(object?.${jsonName}) ? [...${jsonProperty}] : [],`);
|
|
1028
1029
|
}
|
|
1029
1030
|
else {
|
|
1030
1031
|
// Explicit `any` type required to make TS with noImplicitAny happy. `object` is also `any` here.
|
|
1031
1032
|
chunks.push(ts_poet_1.code `
|
|
1032
|
-
${fieldName}: Array.isArray(object?.${jsonName}) ?
|
|
1033
|
+
${fieldName}: Array.isArray(object?.${jsonName}) ? ${jsonProperty}.map((e: any) => ${readValueSnippet}): [],
|
|
1033
1034
|
`);
|
|
1034
1035
|
}
|
|
1035
1036
|
}
|
|
@@ -1042,8 +1043,8 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
1042
1043
|
const fieldName = case_1.maybeSnakeToCamel(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
1043
1044
|
chunks.push(ts_poet_1.code `${fieldName}: `);
|
|
1044
1045
|
}
|
|
1045
|
-
const ternaryIf = ts_poet_1.code `${ctx.utils.isSet}(
|
|
1046
|
-
const ternaryThen = ts_poet_1.code `{ $case: '${fieldName}', ${fieldName}: ${readSnippet(
|
|
1046
|
+
const ternaryIf = ts_poet_1.code `${ctx.utils.isSet}(${jsonProperty})`;
|
|
1047
|
+
const ternaryThen = ts_poet_1.code `{ $case: '${fieldName}', ${fieldName}: ${readSnippet(`${jsonProperty}`)}`;
|
|
1047
1048
|
chunks.push(ts_poet_1.code `${ternaryIf} ? ${ternaryThen}} : `);
|
|
1048
1049
|
if (field === lastCase) {
|
|
1049
1050
|
chunks.push(ts_poet_1.code `undefined,`);
|
|
@@ -1051,27 +1052,27 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
1051
1052
|
}
|
|
1052
1053
|
else if (types_1.isAnyValueType(field)) {
|
|
1053
1054
|
chunks.push(ts_poet_1.code `${fieldName}: ${ctx.utils.isSet}(object?.${jsonName})
|
|
1054
|
-
? ${readSnippet(
|
|
1055
|
+
? ${readSnippet(`${jsonProperty}`)}
|
|
1055
1056
|
: undefined,
|
|
1056
1057
|
`);
|
|
1057
1058
|
}
|
|
1058
1059
|
else if (types_1.isStructType(field)) {
|
|
1059
|
-
chunks.push(ts_poet_1.code `${fieldName}: ${ctx.utils.isObject}(
|
|
1060
|
-
? ${readSnippet(
|
|
1060
|
+
chunks.push(ts_poet_1.code `${fieldName}: ${ctx.utils.isObject}(${jsonProperty})
|
|
1061
|
+
? ${readSnippet(`${jsonProperty}`)}
|
|
1061
1062
|
: undefined,`);
|
|
1062
1063
|
}
|
|
1063
1064
|
else if (types_1.isListValueType(field)) {
|
|
1064
1065
|
chunks.push(ts_poet_1.code `
|
|
1065
|
-
${fieldName}: Array.isArray(
|
|
1066
|
-
? ${readSnippet(
|
|
1066
|
+
${fieldName}: Array.isArray(${jsonProperty})
|
|
1067
|
+
? ${readSnippet(`${jsonProperty}`)}
|
|
1067
1068
|
: undefined,
|
|
1068
1069
|
`);
|
|
1069
1070
|
}
|
|
1070
1071
|
else {
|
|
1071
1072
|
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
1072
1073
|
chunks.push(ts_poet_1.code `
|
|
1073
|
-
${fieldName}: ${ctx.utils.isSet}(
|
|
1074
|
-
? ${readSnippet(
|
|
1074
|
+
${fieldName}: ${ctx.utils.isSet}(${jsonProperty})
|
|
1075
|
+
? ${readSnippet(`${jsonProperty}`)}
|
|
1075
1076
|
: ${fallback},
|
|
1076
1077
|
`);
|
|
1077
1078
|
}
|
|
@@ -1092,7 +1093,8 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
1092
1093
|
// then add a case for each field
|
|
1093
1094
|
messageDesc.field.forEach((field) => {
|
|
1094
1095
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
1095
|
-
const jsonName = utils_1.
|
|
1096
|
+
const jsonName = utils_1.getFieldJsonName(field, options);
|
|
1097
|
+
const jsonProperty = utils_1.getPropertyAccessor('obj', jsonName);
|
|
1096
1098
|
const readSnippet = (from) => {
|
|
1097
1099
|
if (types_1.isEnum(field)) {
|
|
1098
1100
|
const toJson = types_1.getEnumMethod(ctx, field.typeName, 'ToJSON');
|
|
@@ -1205,11 +1207,11 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
1205
1207
|
// oneofs in a union are only output as `oneof name = ...`
|
|
1206
1208
|
const oneofName = case_1.maybeSnakeToCamel(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
1207
1209
|
const v = readSnippet(`message.${oneofName}?.${fieldName}`);
|
|
1208
|
-
chunks.push(ts_poet_1.code `message.${oneofName}?.$case === '${fieldName}' && (
|
|
1210
|
+
chunks.push(ts_poet_1.code `message.${oneofName}?.$case === '${fieldName}' && (${jsonProperty} = ${v});`);
|
|
1209
1211
|
}
|
|
1210
1212
|
else {
|
|
1211
1213
|
const v = readSnippet(`message.${fieldName}`);
|
|
1212
|
-
chunks.push(ts_poet_1.code `message.${fieldName} !== undefined && (
|
|
1214
|
+
chunks.push(ts_poet_1.code `message.${fieldName} !== undefined && (${jsonProperty} = ${v});`);
|
|
1213
1215
|
}
|
|
1214
1216
|
});
|
|
1215
1217
|
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,20 @@ 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
|
+
*/
|
|
164
|
+
function getPropertyAccessor(objectName, propertyName) {
|
|
165
|
+
let validIdentifier = /^[a-zA-Z_$][\w$]*$/;
|
|
166
|
+
return validIdentifier.test(propertyName)
|
|
167
|
+
? `${objectName}.${propertyName}`
|
|
168
|
+
: `${objectName}[${JSON.stringify(propertyName)}]`;
|
|
169
|
+
}
|
|
170
|
+
exports.getPropertyAccessor = getPropertyAccessor;
|
|
158
171
|
function impProto(options, module, type) {
|
|
159
172
|
return ts_poet_1.imp(`${type}@./${module}${options.fileSuffix}`);
|
|
160
173
|
}
|