UNPKG

proto-gen-dts

Version:
328 lines (260 loc) 12.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _stanUtils = require("stan-utils"); var _protobufjs = require("protobufjs"); var _util = require("./util"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var dtsTemplate = "<%= comment %>\ndeclare namespace <%= namespace %> {\n<%= content %>\n}"; var interfaceTemplate = "<%= comment %>\nexport interface <%= name %> {\n<%= content %>\n}"; var enumTemplate = "<%= comment %>\nexport enum <%= name %> {\n<%= content %>\n}"; var serviceTemplate = "<%= comment %>\nexport interface <%= name %>Service {\n<%= content %>\n}"; var serviceFNTemplate = "<%= comment %>\n<%= name %><R extends <%= requestType %>, O>(r: R, o?: O): Promise<<%= responseType %>>,"; var dtsExecutor = _stanUtils.lodash.template(dtsTemplate); var interfaceExecutor = _stanUtils.lodash.template(interfaceTemplate); var enumExecutor = _stanUtils.lodash.template(enumTemplate); var serviceExecutor = _stanUtils.lodash.template(serviceTemplate); var serviceFNExecutor = _stanUtils.lodash.template(serviceFNTemplate); /** * Parsed proto content to dts content * @description Nested message names will be spliced by _ * @param namespace {Namespace} * @param filename {string} * @param visitor {Visitor} * @returns dts content */ function parseNamespace(namespace, filename, visitor) { var _visitor$EmitTSNamesp; var moduleName = namespace.name; var parsedNestedList = []; // record generation history to prevent repeated generation var hasGenMap = { enums: new Map(), services: new Map(), interfaces: new Map() }; // construct the name of the message embedded in the message function replaceNamespacePrefix(name, field) { var _namespace$lookup; var _filename = (_namespace$lookup = namespace.lookup(name)) === null || _namespace$lookup === void 0 ? void 0 : _namespace$lookup.filename; // not current namespace types if (_filename !== filename) { var arr = name.split('.'); // other files, search from the GoogleProtoFilesRoot var lastNamespaceIndex = arr.findIndex(function (_, index) { return !(0, _util.isNamespace)((0, _util.getNamespaceRoot)(namespace).lookup(arr.slice(0, index + 1).join('.'))); }); if (!lastNamespaceIndex) { return name; } return [arr.slice(0, lastNamespaceIndex).join('.'), arr.slice(lastNamespaceIndex).join('_')].filter(String).join('.'); } if (field && !name.includes('.')) { if ((0, _util.isNamespace)(field.parent)) { return name; } name = "".concat((0, _util.getReflectionParentName)(field), "_").concat(name); } return name.replace(new RegExp("^".concat(moduleName, "_")), '').replace(/\./g, '_'); } // gen common function genComment(str) { if (!str) return ''; var lines = str.replace(/\r\n/g, '/n').split('\n'); return lines.map(function (v) { return "// ".concat(v); }).join('\n'); } // process interface function processType(name, nested) { var comment = genComment(nested.comment); var schema = { name: name, comment: comment, fieldList: nested.fieldsArray.reduce(function (acc, field) { var childrenNested = (0, _util.getParentLookup)({ field: field, root: namespace, type: field.type }); var endPrefix = field.repeated ? '[]' : ''; acc.push({ key: field.name, reflection: childrenNested, comment: genComment(field.comment), isRequired: (0, _util.getFieldIsRequired)(field), isArray: field.repeated, isMap: field instanceof _protobufjs.MapField, value: field instanceof _protobufjs.MapField ? "Record<".concat((0, _util.protoTypeToTSType)(field.keyType), ", ").concat(childrenNested ? replaceNamespacePrefix(field.type, childrenNested) : (0, _util.protoTypeToTSType)(field.type) || replaceNamespacePrefix(field.type), ">;") : "".concat(childrenNested ? replaceNamespacePrefix(field.type, childrenNested) : (0, _util.protoTypeToTSType)(field.type) || replaceNamespacePrefix(field.type)).concat(endPrefix, ";") }); return acc; }, []) }; function parse() { var content; if (visitor !== null && visitor !== void 0 && visitor.TSMessageDeclaration) { content = visitor.TSMessageDeclaration(schema, nested); } if (content === false) return ''; if (content) return content; return interfaceExecutor({ name: name, comment: comment, content: nested.fieldsArray.reduce(function (acc, field) { var childrenNested = (0, _util.getParentLookup)({ field: field, root: namespace, type: field.type }); if (field.comment) { acc.push(genComment(field.comment)); } var endPrefix = field.repeated ? '[]' : ''; var fieldContent = "".concat(field.name).concat((0, _util.getFieldIsRequired)(field) ? '' : '?', ": "); if (field instanceof _protobufjs.MapField) { fieldContent += "Record<".concat((0, _util.protoTypeToTSType)(field.keyType), ", ").concat(childrenNested ? replaceNamespacePrefix(field.type, childrenNested) : (0, _util.protoTypeToTSType)(field.type) || replaceNamespacePrefix(field.type), ">;"); } else { fieldContent += "".concat(childrenNested ? replaceNamespacePrefix(field.type, childrenNested) : (0, _util.protoTypeToTSType)(field.type) || replaceNamespacePrefix(field.type)).concat(endPrefix, ";"); } acc.push(fieldContent); return acc; }, []).join('\n') }); } parsedNestedList.push(parse()); return schema; } // process enum function processEnum(name, nested) { var comment = genComment(nested.comment); var schema = { name: name, comment: comment, fieldList: Object.keys(nested.values).map(function (key) { var _nested$comments; return { key: key, value: nested.values[key], comment: genComment((_nested$comments = nested.comments) === null || _nested$comments === void 0 ? void 0 : _nested$comments[key]) }; }) }; function parse() { var content; if (visitor !== null && visitor !== void 0 && visitor.TSEnumDeclaration) { content = visitor.TSEnumDeclaration(schema, nested); } if (content === false) return ''; if (content) return content; return enumExecutor({ name: name, comment: comment, content: Object.keys(nested.values).reduce(function (acc, field) { var _nested$comments2; if ((_nested$comments2 = nested.comments) !== null && _nested$comments2 !== void 0 && _nested$comments2[field]) { acc.push(genComment(nested.comments[field])); } acc.push("".concat(field, " = ").concat(nested.values[field], ",")); return acc; }, []).join('\n') }); } parsedNestedList.push(parse()); return schema; } // process service function processService(name, nested) { var comment = genComment(nested.comment); function handleFieldItemObj(field) { return { name: field.name, requestType: replaceNamespacePrefix(field.requestType), responseType: replaceNamespacePrefix(field.responseType), options: field.options, comment: genComment(field.comment) + ( // services options as remark field.options ? Object.keys(field.options).reduce(function (acc, k) { acc.push("// svr options: ".concat(k, " = ").concat(field.options[k])); return acc; }, ['\n']).join('\n') : '') }; } var schema = { name: name, comment: comment, fieldList: nested.methodsArray.map(handleFieldItemObj) }; function parse() { var content; if (visitor !== null && visitor !== void 0 && visitor.TSServiceDeclaration) { content = visitor.TSServiceDeclaration(schema, nested); } if (content === false) return ''; if (content) return content; return serviceExecutor({ name: name, comment: comment, content: nested.methodsArray.reduce(function (acc, field) { var content; if (visitor !== null && visitor !== void 0 && visitor.TSServiceItemDeclaration) { content = visitor.TSServiceItemDeclaration(handleFieldItemObj(field), field); } if (content === false) return acc; if (content) { acc.push(content); return acc; } acc.push(serviceFNExecutor({ name: field.name, requestType: replaceNamespacePrefix(field.requestType), responseType: replaceNamespacePrefix(field.responseType), comment: genComment(field.comment) + ( // services options as remark field.options ? Object.keys(field.options).reduce(function (acc, k) { acc.push("// svr options: ".concat(k, " = ").concat(field.options[k])); return acc; }, ['\n']).join('\n') : '') })); return acc; }, []).join('\n') }); } parsedNestedList.push(parse()); return schema; } // parse proto reflection obj function processNested(nested) { // it's not that the content in the current file is not generated // because the dependent modules will generate separate files if (nested.filename && nested.filename !== filename) return; var messageName = replaceNamespacePrefix(nested.name, nested); if (nested instanceof _protobufjs.Type) { if (hasGenMap.interfaces.has(messageName)) return; hasGenMap.interfaces.set(messageName, processType(messageName, nested)); // nested message eachNested(nested.nested); } else if (nested instanceof _protobufjs.Enum) { if (hasGenMap.enums.has(messageName)) return; hasGenMap.enums.set(messageName, processEnum(messageName, nested)); } else if (nested instanceof _protobufjs.Service) { if (hasGenMap.services.has(messageName)) return; hasGenMap.services.set(messageName, processService(messageName, nested)); // nested message eachNested(nested.nested); } else if (nested instanceof _protobufjs.Namespace) { var parsed = parseNamespace(nested, filename, visitor); parsedNestedList.push(parsed.replace('declare namespace', 'namespace')); } } function eachNested(nested) { Object.keys(nested || {}).forEach(function (type) { return processNested(nested[type]); }); } eachNested(namespace.nested); var comment = genComment(namespace.comment); visitor === null || visitor === void 0 ? void 0 : (_visitor$EmitTSNamesp = visitor.EmitTSNamespaceDeclaration) === null || _visitor$EmitTSNamesp === void 0 ? void 0 : _visitor$EmitTSNamesp.call(visitor, _objectSpread({ namespace: namespace, comment: comment, filename: filename, moduleName: moduleName }, hasGenMap)); return (0, _util.formatTS)(dtsExecutor({ namespace: moduleName, comment: comment, content: parsedNestedList.join('\n\n') })); } var _default = parseNamespace; exports.default = _default;