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)

147 lines (146 loc) 6.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateEnumToNumber = exports.generateEnumToJson = exports.generateEnumFromJson = exports.generateEnum = void 0; const ts_poet_1 = require("ts-poet"); const utils_1 = require("./utils"); const case_1 = require("./case"); const sourceInfo_1 = require("./sourceInfo"); const UNRECOGNIZED_ENUM_NAME = 'UNRECOGNIZED'; const UNRECOGNIZED_ENUM_VALUE = -1; // Output the `enum { Foo, A = 0, B = 1 }` function generateEnum(ctx, fullName, enumDesc, sourceInfo) { var _a; const { options } = ctx; const chunks = []; utils_1.maybeAddComment(sourceInfo, chunks, (_a = enumDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated); if (options.enumsAsLiterals) { chunks.push(ts_poet_1.code `export const ${ts_poet_1.def(fullName)} = {`); } else { chunks.push(ts_poet_1.code `export ${options.constEnums ? 'const ' : ''}enum ${ts_poet_1.def(fullName)} {`); } const delimiter = options.enumsAsLiterals ? ':' : '='; enumDesc.value.forEach((valueDesc, index) => { var _a; const info = sourceInfo.lookup(sourceInfo_1.Fields.enum.value, index); utils_1.maybeAddComment(info, chunks, (_a = valueDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated, `${valueDesc.name} - `); chunks.push(ts_poet_1.code `${valueDesc.name} ${delimiter} ${options.stringEnums ? `"${valueDesc.name}"` : valueDesc.number.toString()},`); }); if (options.unrecognizedEnum) chunks.push(ts_poet_1.code ` ${UNRECOGNIZED_ENUM_NAME} ${delimiter} ${options.stringEnums ? `"${UNRECOGNIZED_ENUM_NAME}"` : UNRECOGNIZED_ENUM_VALUE.toString()},`); if (options.enumsAsLiterals) { chunks.push(ts_poet_1.code `} as const`); chunks.push(ts_poet_1.code `\n`); chunks.push(ts_poet_1.code `export type ${ts_poet_1.def(fullName)} = typeof ${ts_poet_1.def(fullName)}[keyof typeof ${ts_poet_1.def(fullName)}]`); } else { chunks.push(ts_poet_1.code `}`); } if (options.outputJsonMethods || (options.stringEnums && options.outputEncodeMethods)) { chunks.push(ts_poet_1.code `\n`); chunks.push(generateEnumFromJson(ctx, fullName, enumDesc)); } if (options.outputJsonMethods) { chunks.push(ts_poet_1.code `\n`); chunks.push(generateEnumToJson(ctx, fullName, enumDesc)); } if (options.stringEnums && options.outputEncodeMethods) { chunks.push(ts_poet_1.code `\n`); chunks.push(generateEnumToNumber(ctx, fullName, enumDesc)); } return ts_poet_1.joinCode(chunks, { on: '\n' }); } exports.generateEnum = generateEnum; /** Generates a function with a big switch statement to decode JSON -> our enum. */ function generateEnumFromJson(ctx, fullName, enumDesc) { const { options, utils } = ctx; const chunks = []; const functionName = case_1.camelCase(fullName) + 'FromJSON'; chunks.push(ts_poet_1.code `export function ${ts_poet_1.def(functionName)}(object: any): ${fullName} {`); chunks.push(ts_poet_1.code `switch (object) {`); for (const valueDesc of enumDesc.value) { chunks.push(ts_poet_1.code ` case ${valueDesc.number}: case "${valueDesc.name}": return ${fullName}.${valueDesc.name}; `); } if (options.unrecognizedEnum) { chunks.push(ts_poet_1.code ` case ${UNRECOGNIZED_ENUM_VALUE}: case "${UNRECOGNIZED_ENUM_NAME}": default: return ${fullName}.${UNRECOGNIZED_ENUM_NAME}; `); } else { // We use globalThis to avoid conflicts on protobuf types named `Error`. chunks.push(ts_poet_1.code ` default: throw new ${utils.globalThis}.Error("Unrecognized enum value " + object + " for enum ${fullName}"); `); } chunks.push(ts_poet_1.code `}`); chunks.push(ts_poet_1.code `}`); return ts_poet_1.joinCode(chunks, { on: '\n' }); } exports.generateEnumFromJson = generateEnumFromJson; /** Generates a function with a big switch statement to encode our enum -> JSON. */ function generateEnumToJson(ctx, fullName, enumDesc) { const { options, utils } = ctx; const chunks = []; const functionName = case_1.camelCase(fullName) + 'ToJSON'; chunks.push(ts_poet_1.code `export function ${ts_poet_1.def(functionName)}(object: ${fullName}): string {`); chunks.push(ts_poet_1.code `switch (object) {`); for (const valueDesc of enumDesc.value) { chunks.push(ts_poet_1.code `case ${fullName}.${valueDesc.name}: return "${valueDesc.name}";`); } if (options.unrecognizedEnum) { chunks.push(ts_poet_1.code ` case ${fullName}.${UNRECOGNIZED_ENUM_NAME}: default: return "${UNRECOGNIZED_ENUM_NAME}"; `); } else { // We use globalThis to avoid conflicts on protobuf types named `Error`. chunks.push(ts_poet_1.code ` default: throw new ${utils.globalThis}.Error("Unrecognized enum value " + object + " for enum ${fullName}"); `); } chunks.push(ts_poet_1.code `}`); chunks.push(ts_poet_1.code `}`); return ts_poet_1.joinCode(chunks, { on: '\n' }); } exports.generateEnumToJson = generateEnumToJson; /** Generates a function with a big switch statement to encode our string enum -> int value. */ function generateEnumToNumber(ctx, fullName, enumDesc) { const { options, utils } = ctx; const chunks = []; const functionName = case_1.camelCase(fullName) + 'ToNumber'; chunks.push(ts_poet_1.code `export function ${ts_poet_1.def(functionName)}(object: ${fullName}): number {`); chunks.push(ts_poet_1.code `switch (object) {`); for (const valueDesc of enumDesc.value) { chunks.push(ts_poet_1.code `case ${fullName}.${valueDesc.name}: return ${valueDesc.number};`); } if (options.unrecognizedEnum) { chunks.push(ts_poet_1.code ` case ${fullName}.${UNRECOGNIZED_ENUM_NAME}: default: return ${UNRECOGNIZED_ENUM_VALUE}; `); } else { // We use globalThis to avoid conflicts on protobuf types named `Error`. chunks.push(ts_poet_1.code ` default: throw new ${utils.globalThis}.Error("Unrecognized enum value " + object + " for enum ${fullName}"); `); } chunks.push(ts_poet_1.code `}`); chunks.push(ts_poet_1.code `}`); return ts_poet_1.joinCode(chunks, { on: '\n' }); } exports.generateEnumToNumber = generateEnumToNumber;