UNPKG

ts-proto

Version:

[![npm](https://img.shields.io/npm/v/ts-proto)](https://www.npmjs.com/package/ts-proto) [![build](https://github.com/stephenh/ts-proto/workflows/Build/badge.svg)](https://github.com/stephenh/ts-proto/actions)

309 lines (307 loc) 11.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OutputSchemaOption = exports.ServiceOption = exports.OneofOption = exports.EnvOption = exports.DurationOption = exports.JsonTimestampOption = exports.DateOption = exports.LongOption = void 0; exports.defaultOptions = defaultOptions; exports.optionsFromParameter = optionsFromParameter; exports.getTsPoetOpts = getTsPoetOpts; exports.addTypeToMessages = addTypeToMessages; var LongOption; (function (LongOption) { LongOption["NUMBER"] = "number"; LongOption["LONG"] = "long"; LongOption["STRING"] = "string"; LongOption["BIGINT"] = "bigint"; })(LongOption || (exports.LongOption = LongOption = {})); var DateOption; (function (DateOption) { DateOption["DATE"] = "date"; DateOption["STRING"] = "string"; DateOption["STRING_NANO"] = "string-nano"; DateOption["TEMPORAL"] = "temporal"; DateOption["TIMESTAMP"] = "timestamp"; })(DateOption || (exports.DateOption = DateOption = {})); var JsonTimestampOption; (function (JsonTimestampOption) { JsonTimestampOption["RFC3339"] = "rfc3339"; JsonTimestampOption["RAW"] = "raw"; })(JsonTimestampOption || (exports.JsonTimestampOption = JsonTimestampOption = {})); var DurationOption; (function (DurationOption) { DurationOption["DURATION"] = "duration"; DurationOption["STRING"] = "string"; })(DurationOption || (exports.DurationOption = DurationOption = {})); var EnvOption; (function (EnvOption) { EnvOption["NODE"] = "node"; EnvOption["BROWSER"] = "browser"; EnvOption["BOTH"] = "both"; })(EnvOption || (exports.EnvOption = EnvOption = {})); var OneofOption; (function (OneofOption) { OneofOption["PROPERTIES"] = "properties"; OneofOption["UNIONS"] = "unions"; OneofOption["UNIONS_VALUE"] = "unions-value"; })(OneofOption || (exports.OneofOption = OneofOption = {})); var ServiceOption; (function (ServiceOption) { ServiceOption["GRPC"] = "grpc-js"; ServiceOption["NICE_GRPC"] = "nice-grpc"; ServiceOption["GENERIC"] = "generic-definitions"; ServiceOption["DEFAULT"] = "default"; ServiceOption["NONE"] = "none"; })(ServiceOption || (exports.ServiceOption = ServiceOption = {})); var OutputSchemaOption; (function (OutputSchemaOption) { OutputSchemaOption["TRUE"] = "true"; OutputSchemaOption["NO_FILE_DESCRIPTOR"] = "no-file-descriptor"; OutputSchemaOption["CONST"] = "const"; })(OutputSchemaOption || (exports.OutputSchemaOption = OutputSchemaOption = {})); function defaultOptions() { return { context: false, snakeToCamel: ["json", "keys"], protoJsonFormat: true, emitDefaultValues: [], globalThisPolyfill: false, forceLong: LongOption.NUMBER, useJsTypeOverride: false, useOptionals: "none", useDate: DateOption.DATE, useJsonTimestamp: JsonTimestampOption.RFC3339, useMongoObjectId: false, oneof: OneofOption.PROPERTIES, esModuleInterop: false, fileSuffix: "", importSuffix: "", lowerCaseServiceMethods: false, outputEncodeMethods: true, outputEncodeIncludeTypes: "", outputDecodeIncludeTypes: "", outputJsonMethods: true, outputPartialMethods: true, outputTypeAnnotations: false, outputTypeRegistry: false, stringEnums: false, constEnums: false, removeEnumPrefix: false, enumsAsLiterals: false, outputClientImpl: true, outputServices: [], returnObservable: false, addGrpcMetadata: false, metadataType: undefined, addNestjsRestParameter: false, nestJs: false, env: EnvOption.BOTH, unrecognizedEnum: true, unrecognizedEnumName: "UNRECOGNIZED", unrecognizedEnumValue: -1, exportCommonSymbols: true, outputSchema: false, onlyTypes: false, emitImportedFiles: true, useExactTypes: true, useAbortSignal: false, useAsyncIterable: false, unknownFields: false, usePrototypeForDefaults: false, useJsonName: false, useJsonWireFormat: false, useNumericEnumForJson: false, initializeFieldsAsUndefined: true, useMapType: false, useReadonlyTypes: false, useSnakeTypeName: true, outputExtensions: false, outputIndex: false, M: {}, rpcBeforeRequest: false, rpcAfterResponse: false, rpcErrorHandler: false, comments: true, disableProto2Optionals: false, disableProto2DefaultValues: false, useNullAsOptional: false, annotateFilesWithVersion: true, noDefaultsForOptionals: false, bigIntLiteral: true, typePrefix: "", typeSuffix: "", useDuration: DurationOption.DURATION, }; } const nestJsOptions = { lowerCaseServiceMethods: true, outputEncodeMethods: false, outputJsonMethods: false, outputPartialMethods: false, outputClientImpl: false, useDate: DateOption.TIMESTAMP, }; function optionsFromParameter(parameter) { const options = defaultOptions(); if (parameter) { const parsed = parseParameter(parameter); if (parsed.nestJs) { Object.assign(options, nestJsOptions); } Object.assign(options, parsed); } // onlyTypes=true implies outputJsonMethods=false,outputEncodeMethods=false,outputClientImpl=false,nestJs=false if (options.onlyTypes) { options.outputJsonMethods = false; options.outputEncodeMethods = false; options.outputClientImpl = false; options.nestJs = false; } else if (!options.outputJsonMethods && !options.outputEncodeMethods && !options.outputClientImpl && !options.nestJs) { options.onlyTypes = true; } // Treat forceLong=true as LONG if (options.forceLong === true) { options.forceLong = LongOption.LONG; } // Treat outputServices=false as NONE if (options.outputServices === false) { options.outputServices = [ServiceOption.NONE]; } // Existing type-coercion inside parseParameter leaves a little to be desired. if (typeof options.outputServices == "string") { options.outputServices = [options.outputServices]; } // Assume the user wants the default service output, unless they're using nestJs, which has // its own controllers output (although nestjs users can ask for other services too). if (options.outputServices.length == 0 && !options.nestJs) { options.outputServices = [ServiceOption.DEFAULT]; } // If using nestJs + other services, add the encode methods back if (options.nestJs && options.outputServices.length > 0) { options.outputEncodeMethods = true; } // Handle outputSchema=true if (options.outputSchema === true) { options.outputSchema = []; } if (typeof options.outputSchema === "string") { options.outputSchema = [options.outputSchema]; } if (options.useDate === true) { // Treat useDate=true as DATE options.useDate = DateOption.DATE; } else if (options.useDate === false) { // Treat useDate=false as TIMESTAMP options.useDate = DateOption.TIMESTAMP; } if (options.snakeToCamel === false) { options.snakeToCamel = []; } else if (options.snakeToCamel === true) { options.snakeToCamel = ["keys", "json"]; } else if (typeof options.snakeToCamel === "string") { options.snakeToCamel = options.snakeToCamel.split("_"); } if (options.protoJsonFormat && !options.snakeToCamel.includes("json")) { // protoJSONFormat implies snakeToCamel=json, Message field names must be mapped to lowerCamelCase and become JSON object keys. // If the json_name field option is specified, the specified value will be used as the key instead. options.snakeToCamel.push("json"); } if (options.emitDefaultValues === "json-methods") { options.emitDefaultValues = ["json-methods"]; } else { options.emitDefaultValues = []; } if (options.useJsonWireFormat) { if (!options.onlyTypes) { // useJsonWireFormat requires onlyTypes=true options.useJsonWireFormat = false; } else { // useJsonWireFormat implies stringEnums=true and useDate=string options.stringEnums = true; options.useDate = DateOption.STRING; } } if (options.nestJs) { options.initializeFieldsAsUndefined = false; } if (options.outputIndex) { options.exportCommonSymbols = false; } if (options.rpcBeforeRequest || options.rpcAfterResponse || options.rpcErrorHandler) { const includesGeneric = options.outputServices.includes(ServiceOption.GENERIC); options.outputServices = [ServiceOption.DEFAULT]; if (includesGeneric) { options.outputServices.push(ServiceOption.GENERIC); } } if (options.unrecognizedEnumValue) { // Make sure to cast number options to an actual number options.unrecognizedEnumValue = Number(options.unrecognizedEnumValue); } return options; } // A very naive parse function, eventually could/should use iots/runtypes function parseParameter(parameter) { const options = { M: {} }; parameter.split(",").forEach((param) => { // same as protoc-gen-go https://github.com/protocolbuffers/protobuf-go/blob/bf9455640daabb98c93b5b5e71628f3f813d57bb/compiler/protogen/protogen.go#L168-L171 const optionSeparatorPos = param.indexOf("="); const key = param.substring(0, optionSeparatorPos); const value = parseParamValue(param.substring(optionSeparatorPos + 1)); if (key.charAt(0) === "M") { if (typeof value !== "string") { console.warn(`ignoring invalid M option: '${param}'`); } else { const mKey = key.substring(1); if (options.M[mKey]) { console.warn(`received conflicting M options: '${param}' will override 'M${mKey}=${options.M[mKey]}'`); } if (param.endsWith(".ts")) { console.warn(`received M option '${param}' ending in '.ts' this is usually a mistake`); } options.M[mKey] = value; } } else if (options[key]) { options[key] = [options[key], value]; } else { options[key] = value; } }); return options; } function parseParamValue(value) { return value === "true" ? true : value === "false" ? false : value; } function getTsPoetOpts(options, tsProtoVersion, protocVersion, fileName) { const { importSuffix, esModuleInterop } = options; const pbjs = "protobufjs/minimal" + importSuffix; return { // Comment block at the top of every source file, since these comments require specific // syntax incompatible with ts-poet, we will hard-code the string and prepend to the // generator output. prefix: `// Code generated by protoc-gen-ts_proto. DO NOT EDIT.${options.annotateFilesWithVersion ? ` // versions: // protoc-gen-ts_proto ${tsProtoVersion} // protoc ${protocVersion}` : ""} ${fileName ? `// source: ${fileName}` : ""} /* eslint-disable */`, dprintOptions: { preferSingleLine: true, lineWidth: 120 }, forceRequireImport: esModuleInterop ? [] : ["long"], forceDefaultImport: esModuleInterop ? [pbjs] : [], forceModuleImport: esModuleInterop ? [] : [pbjs], }; } function addTypeToMessages(options) { return ((options.outputTypeAnnotations || options.outputTypeRegistry) && options.outputTypeAnnotations !== "static-only"); }