ts-proto 1.112.0 → 1.113.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 +21 -0
- package/build/enums.js +34 -6
- package/build/main.js +1 -1
- package/build/schema.js +188 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
# [1.113.0](https://github.com/stephenh/ts-proto/compare/v1.112.2...v1.113.0) (2022-05-27)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* add options to schema output ([#437](https://github.com/stephenh/ts-proto/issues/437)) ([e8e4e39](https://github.com/stephenh/ts-proto/commit/e8e4e3937292e07280f5154b584e60124118f093))
|
|
7
|
+
|
|
8
|
+
## [1.112.2](https://github.com/stephenh/ts-proto/compare/v1.112.1...v1.112.2) (2022-05-18)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* enum type returns 'UNRECOGNIZED' or '-1' in xxxToJSON/xxxToNumber ([#566](https://github.com/stephenh/ts-proto/issues/566)) ([19911a1](https://github.com/stephenh/ts-proto/commit/19911a1c62e3fe5c8a0eb0a795489340512898da))
|
|
14
|
+
|
|
15
|
+
## [1.112.1](https://github.com/stephenh/ts-proto/compare/v1.112.0...v1.112.1) (2022-05-06)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* use Long.fromValue instead of Long.fromString ([#562](https://github.com/stephenh/ts-proto/issues/562)) ([c99891e](https://github.com/stephenh/ts-proto/commit/c99891e0fec6d9b7225025eb0c5bd7393e80af36))
|
|
21
|
+
|
|
1
22
|
# [1.112.0](https://github.com/stephenh/ts-proto/compare/v1.111.0...v1.112.0) (2022-05-02)
|
|
2
23
|
|
|
3
24
|
|
package/build/enums.js
CHANGED
|
@@ -43,11 +43,11 @@ function generateEnum(ctx, fullName, enumDesc, sourceInfo) {
|
|
|
43
43
|
}
|
|
44
44
|
if (options.outputJsonMethods) {
|
|
45
45
|
chunks.push(ts_poet_1.code `\n`);
|
|
46
|
-
chunks.push(generateEnumToJson(fullName, enumDesc));
|
|
46
|
+
chunks.push(generateEnumToJson(ctx, fullName, enumDesc));
|
|
47
47
|
}
|
|
48
48
|
if (options.stringEnums && options.outputEncodeMethods) {
|
|
49
49
|
chunks.push(ts_poet_1.code `\n`);
|
|
50
|
-
chunks.push(generateEnumToNumber(fullName, enumDesc));
|
|
50
|
+
chunks.push(generateEnumToNumber(ctx, fullName, enumDesc));
|
|
51
51
|
}
|
|
52
52
|
return ts_poet_1.joinCode(chunks, { on: '\n' });
|
|
53
53
|
}
|
|
@@ -87,7 +87,8 @@ function generateEnumFromJson(ctx, fullName, enumDesc) {
|
|
|
87
87
|
}
|
|
88
88
|
exports.generateEnumFromJson = generateEnumFromJson;
|
|
89
89
|
/** Generates a function with a big switch statement to encode our enum -> JSON. */
|
|
90
|
-
function generateEnumToJson(fullName, enumDesc) {
|
|
90
|
+
function generateEnumToJson(ctx, fullName, enumDesc) {
|
|
91
|
+
const { options, utils } = ctx;
|
|
91
92
|
const chunks = [];
|
|
92
93
|
const functionName = case_1.camelCase(fullName) + 'ToJSON';
|
|
93
94
|
chunks.push(ts_poet_1.code `export function ${ts_poet_1.def(functionName)}(object: ${fullName}): string {`);
|
|
@@ -95,14 +96,28 @@ function generateEnumToJson(fullName, enumDesc) {
|
|
|
95
96
|
for (const valueDesc of enumDesc.value) {
|
|
96
97
|
chunks.push(ts_poet_1.code `case ${fullName}.${valueDesc.name}: return "${valueDesc.name}";`);
|
|
97
98
|
}
|
|
98
|
-
|
|
99
|
+
if (options.unrecognizedEnum) {
|
|
100
|
+
chunks.push(ts_poet_1.code `
|
|
101
|
+
case ${fullName}.${UNRECOGNIZED_ENUM_NAME}:
|
|
102
|
+
default:
|
|
103
|
+
return "${UNRECOGNIZED_ENUM_NAME}";
|
|
104
|
+
`);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// We use globalThis to avoid conflicts on protobuf types named `Error`.
|
|
108
|
+
chunks.push(ts_poet_1.code `
|
|
109
|
+
default:
|
|
110
|
+
throw new ${utils.globalThis}.Error("Unrecognized enum value " + object + " for enum ${fullName}");
|
|
111
|
+
`);
|
|
112
|
+
}
|
|
99
113
|
chunks.push(ts_poet_1.code `}`);
|
|
100
114
|
chunks.push(ts_poet_1.code `}`);
|
|
101
115
|
return ts_poet_1.joinCode(chunks, { on: '\n' });
|
|
102
116
|
}
|
|
103
117
|
exports.generateEnumToJson = generateEnumToJson;
|
|
104
118
|
/** Generates a function with a big switch statement to encode our string enum -> int value. */
|
|
105
|
-
function generateEnumToNumber(fullName, enumDesc) {
|
|
119
|
+
function generateEnumToNumber(ctx, fullName, enumDesc) {
|
|
120
|
+
const { options, utils } = ctx;
|
|
106
121
|
const chunks = [];
|
|
107
122
|
const functionName = case_1.camelCase(fullName) + 'ToNumber';
|
|
108
123
|
chunks.push(ts_poet_1.code `export function ${ts_poet_1.def(functionName)}(object: ${fullName}): number {`);
|
|
@@ -110,7 +125,20 @@ function generateEnumToNumber(fullName, enumDesc) {
|
|
|
110
125
|
for (const valueDesc of enumDesc.value) {
|
|
111
126
|
chunks.push(ts_poet_1.code `case ${fullName}.${valueDesc.name}: return ${valueDesc.number};`);
|
|
112
127
|
}
|
|
113
|
-
|
|
128
|
+
if (options.unrecognizedEnum) {
|
|
129
|
+
chunks.push(ts_poet_1.code `
|
|
130
|
+
case ${fullName}.${UNRECOGNIZED_ENUM_NAME}:
|
|
131
|
+
default:
|
|
132
|
+
return ${UNRECOGNIZED_ENUM_VALUE};
|
|
133
|
+
`);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// We use globalThis to avoid conflicts on protobuf types named `Error`.
|
|
137
|
+
chunks.push(ts_poet_1.code `
|
|
138
|
+
default:
|
|
139
|
+
throw new ${utils.globalThis}.Error("Unrecognized enum value " + object + " for enum ${fullName}");
|
|
140
|
+
`);
|
|
141
|
+
}
|
|
114
142
|
chunks.push(ts_poet_1.code `}`);
|
|
115
143
|
chunks.push(ts_poet_1.code `}`);
|
|
116
144
|
return ts_poet_1.joinCode(chunks, { on: '\n' });
|
package/build/main.js
CHANGED
|
@@ -948,7 +948,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
948
948
|
}
|
|
949
949
|
else if (types_1.isLong(field) && options.forceLong === options_1.LongOption.LONG) {
|
|
950
950
|
const cstr = case_1.capitalize(types_1.basicTypeName(ctx, field, { keepValueType: true }).toCodeString());
|
|
951
|
-
return ts_poet_1.code `${cstr}.
|
|
951
|
+
return ts_poet_1.code `${cstr}.fromValue(${from})`;
|
|
952
952
|
}
|
|
953
953
|
else {
|
|
954
954
|
const cstr = case_1.capitalize(types_1.basicTypeName(ctx, field, { keepValueType: true }).toCodeString());
|
package/build/schema.js
CHANGED
|
@@ -5,16 +5,50 @@ const ts_proto_descriptors_1 = require("ts-proto-descriptors");
|
|
|
5
5
|
const ts_poet_1 = require("ts-poet");
|
|
6
6
|
const visit_1 = require("./visit");
|
|
7
7
|
const utils_1 = require("./utils");
|
|
8
|
+
const types_1 = require("./types");
|
|
9
|
+
const minimal_1 = require("protobufjs/minimal");
|
|
8
10
|
const fileDescriptorProto = ts_poet_1.imp('FileDescriptorProto@ts-proto-descriptors');
|
|
11
|
+
const extensionCache = {};
|
|
9
12
|
function generateSchema(ctx, fileDesc, sourceInfo) {
|
|
10
13
|
var _a;
|
|
11
14
|
const { options } = ctx;
|
|
12
15
|
const chunks = [];
|
|
16
|
+
fileDesc.extension.forEach((extension) => {
|
|
17
|
+
if (!(extension.extendee in extensionCache)) {
|
|
18
|
+
extensionCache[extension.extendee] = {};
|
|
19
|
+
}
|
|
20
|
+
extensionCache[extension.extendee][extension.number] = extension;
|
|
21
|
+
});
|
|
13
22
|
chunks.push(ts_poet_1.code `
|
|
23
|
+
type ProtoMetaMessageOptions = {
|
|
24
|
+
options?: { [key: string]: any };
|
|
25
|
+
fields?: { [key: string]: { [key: string]: any } };
|
|
26
|
+
oneof?: { [key: string]: { [key: string]: any } };
|
|
27
|
+
nested?: { [key: string]: ProtoMetaMessageOptions };
|
|
28
|
+
};
|
|
29
|
+
|
|
14
30
|
export interface ProtoMetadata {
|
|
15
31
|
fileDescriptor: ${fileDescriptorProto};
|
|
16
32
|
references: { [key: string]: any };
|
|
17
33
|
dependencies?: ProtoMetadata[];
|
|
34
|
+
options?: {
|
|
35
|
+
options?: { [key: string]: any };
|
|
36
|
+
services?: {
|
|
37
|
+
[key: string]: {
|
|
38
|
+
options?: { [key: string]: any };
|
|
39
|
+
methods?: { [key: string]: { [key: string]: any } };
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
messages?: {
|
|
43
|
+
[key: string]: ProtoMetaMessageOptions;
|
|
44
|
+
};
|
|
45
|
+
enums?: {
|
|
46
|
+
[key: string]: {
|
|
47
|
+
options?: { [key: string]: any };
|
|
48
|
+
values?: { [key: string]: { [key: string]: any } };
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
};
|
|
18
52
|
}
|
|
19
53
|
`);
|
|
20
54
|
const references = [];
|
|
@@ -42,13 +76,167 @@ function generateSchema(ctx, fileDesc, sourceInfo) {
|
|
|
42
76
|
descriptor.sourceCodeInfo = {
|
|
43
77
|
location: ((_a = descriptor.sourceCodeInfo) === null || _a === void 0 ? void 0 : _a.location.filter((loc) => loc['leadingComments'] || loc['trailingComments'])) || [],
|
|
44
78
|
};
|
|
79
|
+
let fileOptions;
|
|
80
|
+
if (fileDesc.options) {
|
|
81
|
+
fileOptions = encodedOptionsToOptions(ctx, '.google.protobuf.FileOptions', fileDesc.options['_unknownFields']);
|
|
82
|
+
delete fileDesc.options['_unknownFields'];
|
|
83
|
+
}
|
|
84
|
+
const messagesOptions = [];
|
|
85
|
+
(fileDesc.messageType || []).forEach((message) => {
|
|
86
|
+
const resolvedMessage = resolveMessageOptions(ctx, message);
|
|
87
|
+
if (resolvedMessage) {
|
|
88
|
+
messagesOptions.push(resolvedMessage);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
const servicesOptions = [];
|
|
92
|
+
(fileDesc.service || []).forEach((service) => {
|
|
93
|
+
const methodsOptions = [];
|
|
94
|
+
service.method.forEach((method) => {
|
|
95
|
+
if (method.options) {
|
|
96
|
+
const methodOptions = encodedOptionsToOptions(ctx, '.google.protobuf.MethodOptions', method.options['_unknownFields']);
|
|
97
|
+
delete method.options['_unknownFields'];
|
|
98
|
+
if (methodOptions) {
|
|
99
|
+
methodsOptions.push(ts_poet_1.code `'${method.name}': ${methodOptions}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
let serviceOptions;
|
|
104
|
+
if (service.options) {
|
|
105
|
+
serviceOptions = encodedOptionsToOptions(ctx, '.google.protobuf.ServiceOptions', service.options['_unknownFields']);
|
|
106
|
+
delete service.options['_unknownFields'];
|
|
107
|
+
}
|
|
108
|
+
if (methodsOptions.length > 0 || serviceOptions) {
|
|
109
|
+
servicesOptions.push(ts_poet_1.code `
|
|
110
|
+
'${service.name}': {
|
|
111
|
+
options: ${serviceOptions},
|
|
112
|
+
methods: {${ts_poet_1.joinCode(methodsOptions, { on: ',' })}}
|
|
113
|
+
}
|
|
114
|
+
`);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
const enumsOptions = [];
|
|
118
|
+
(fileDesc.enumType || []).forEach((Enum) => {
|
|
119
|
+
const valuesOptions = [];
|
|
120
|
+
Enum.value.forEach((value) => {
|
|
121
|
+
if (value.options) {
|
|
122
|
+
const valueOptions = encodedOptionsToOptions(ctx, '.google.protobuf.EnumValueOptions', value.options['_unknownFields']);
|
|
123
|
+
delete value.options['_unknownFields'];
|
|
124
|
+
if (valueOptions) {
|
|
125
|
+
valuesOptions.push(ts_poet_1.code `'${value.name}': ${valueOptions}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
let enumOptions;
|
|
130
|
+
if (Enum.options) {
|
|
131
|
+
enumOptions = encodedOptionsToOptions(ctx, '.google.protobuf.EnumOptions', Enum.options['_unknownFields']);
|
|
132
|
+
delete Enum.options['_unknownFields'];
|
|
133
|
+
}
|
|
134
|
+
if (valuesOptions.length > 0 || enumOptions) {
|
|
135
|
+
enumsOptions.push(ts_poet_1.code `
|
|
136
|
+
'${Enum.name}': {
|
|
137
|
+
options: ${enumOptions},
|
|
138
|
+
values: {${ts_poet_1.joinCode(valuesOptions, { on: ',' })}}
|
|
139
|
+
}
|
|
140
|
+
`);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
45
143
|
chunks.push(ts_poet_1.code `
|
|
46
144
|
export const ${ts_poet_1.def('protoMetadata')}: ProtoMetadata = {
|
|
47
145
|
fileDescriptor: ${fileDescriptorProto}.fromPartial(${descriptor}),
|
|
48
146
|
references: { ${ts_poet_1.joinCode(references, { on: ',' })} },
|
|
49
147
|
dependencies: [${ts_poet_1.joinCode(dependencies, { on: ',' })}],
|
|
148
|
+
${fileOptions || messagesOptions.length > 0 || servicesOptions.length > 0 || enumsOptions.length > 0
|
|
149
|
+
? ts_poet_1.code `options: {
|
|
150
|
+
${fileOptions ? ts_poet_1.code `options: ${fileOptions},` : ''}
|
|
151
|
+
${messagesOptions.length > 0 ? ts_poet_1.code `messages: {${ts_poet_1.joinCode(messagesOptions, { on: ',' })}},` : ''}
|
|
152
|
+
${servicesOptions.length > 0 ? ts_poet_1.code `services: {${ts_poet_1.joinCode(servicesOptions, { on: ',' })}},` : ''}
|
|
153
|
+
${enumsOptions.length > 0 ? ts_poet_1.code `enums: {${ts_poet_1.joinCode(enumsOptions, { on: ',' })}}` : ''}
|
|
154
|
+
}`
|
|
155
|
+
: ''}
|
|
50
156
|
}
|
|
51
157
|
`);
|
|
52
158
|
return chunks;
|
|
53
159
|
}
|
|
54
160
|
exports.generateSchema = generateSchema;
|
|
161
|
+
function getExtensionValue(ctx, extension, data) {
|
|
162
|
+
if (extension.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_MESSAGE) {
|
|
163
|
+
const typeName = types_1.basicTypeName(ctx, extension);
|
|
164
|
+
const resultBuffer = Buffer.concat(data.map((d) => {
|
|
165
|
+
// Skip length byte
|
|
166
|
+
const reader = new minimal_1.Reader(d);
|
|
167
|
+
reader.uint32();
|
|
168
|
+
return reader.buf.slice(reader.pos);
|
|
169
|
+
}));
|
|
170
|
+
const result = resultBuffer.toString('base64');
|
|
171
|
+
return ts_poet_1.code `'${extension.name}': ${typeName}.decode(Buffer.from('${result}', 'base64'))`;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
const reader = new minimal_1.Reader(data[0]);
|
|
175
|
+
let value = reader[types_1.toReaderCall(extension)]();
|
|
176
|
+
if (typeof value === 'string') {
|
|
177
|
+
value = ts_poet_1.code `"${value}"`;
|
|
178
|
+
}
|
|
179
|
+
return ts_poet_1.code `'${extension.name}': ${value}`;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/** Takes the protoc's input of options as proto-encoded messages, and turns them into embedded-able-in-source-code representations. */
|
|
183
|
+
function encodedOptionsToOptions(ctx, extendee, encodedOptions) {
|
|
184
|
+
if (!encodedOptions) {
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
const resultOptions = [];
|
|
188
|
+
for (const [key, value] of Object.entries(encodedOptions)) {
|
|
189
|
+
const extension = extensionCache[extendee][parseInt(key, 10) >>> 3];
|
|
190
|
+
resultOptions.push(getExtensionValue(ctx, extension, value));
|
|
191
|
+
}
|
|
192
|
+
if (resultOptions.length == 0) {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
return ts_poet_1.code `{${ts_poet_1.joinCode(resultOptions, { on: ',' })}}`;
|
|
196
|
+
}
|
|
197
|
+
function resolveMessageOptions(ctx, message) {
|
|
198
|
+
const fieldsOptions = [];
|
|
199
|
+
message.field.forEach((field) => {
|
|
200
|
+
if (field.options) {
|
|
201
|
+
const fieldOptions = encodedOptionsToOptions(ctx, '.google.protobuf.FieldOptions', field.options['_unknownFields']);
|
|
202
|
+
delete field.options['_unknownFields'];
|
|
203
|
+
if (fieldOptions) {
|
|
204
|
+
fieldsOptions.push(ts_poet_1.code `'${field.name}': ${fieldOptions}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
const oneOfsOptions = [];
|
|
209
|
+
message.oneofDecl.forEach((oneOf) => {
|
|
210
|
+
if (oneOf.options) {
|
|
211
|
+
const oneOfOptions = encodedOptionsToOptions(ctx, '.google.protobuf.OneofOptions', oneOf.options['_unknownFields']);
|
|
212
|
+
delete oneOf.options['_unknownFields'];
|
|
213
|
+
if (oneOfOptions) {
|
|
214
|
+
oneOfsOptions.push(ts_poet_1.code `'${oneOf.name}': ${oneOfOptions}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
let nestedOptions = [];
|
|
219
|
+
if (message.nestedType && message.nestedType.length > 0) {
|
|
220
|
+
message.nestedType.forEach((nested) => {
|
|
221
|
+
const resolvedMessage = resolveMessageOptions(ctx, nested);
|
|
222
|
+
if (resolvedMessage) {
|
|
223
|
+
nestedOptions.push(resolvedMessage);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
let messageOptions;
|
|
228
|
+
if (message.options) {
|
|
229
|
+
messageOptions = encodedOptionsToOptions(ctx, '.google.protobuf.MessageOptions', message.options['_unknownFields']);
|
|
230
|
+
delete message.options['_unknownFields'];
|
|
231
|
+
}
|
|
232
|
+
if (fieldsOptions.length > 0 || oneOfsOptions.length > 0 || nestedOptions.length > 0 || messageOptions) {
|
|
233
|
+
return ts_poet_1.code `
|
|
234
|
+
'${message.name}': {
|
|
235
|
+
${messageOptions ? ts_poet_1.code `options: ${messageOptions},` : ''}
|
|
236
|
+
${fieldsOptions.length > 0 ? ts_poet_1.code `fields: {${ts_poet_1.joinCode(fieldsOptions, { on: ',' })}},` : ''}
|
|
237
|
+
${oneOfsOptions.length > 0 ? ts_poet_1.code `oneof: {${ts_poet_1.joinCode(oneOfsOptions, { on: ',' })}},` : ''}
|
|
238
|
+
${nestedOptions.length > 0 ? ts_poet_1.code `nested: {${ts_poet_1.joinCode(nestedOptions, { on: ',' })}},` : ''}
|
|
239
|
+
}
|
|
240
|
+
`;
|
|
241
|
+
}
|
|
242
|
+
}
|