UNPKG

yapi-to-typescript

Version:

根据 YApi 的接口定义生成 TypeScript/JavaScript 的接口类型及其请求函数代码。

285 lines (221 loc) 13.2 kB
#!/usr/bin/env node "use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; exports.__esModule = true; exports.run = run; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _taggedTemplateLiteralLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteralLoose")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var TSNode = _interopRequireWildcard(require("ts-node")); var _consola = _interopRequireDefault(require("consola")); var _fsExtra = _interopRequireDefault(require("fs-extra")); var _ora = _interopRequireDefault(require("ora")); var _path = _interopRequireDefault(require("path")); var _prompts = _interopRequireDefault(require("prompts")); var _yargs = _interopRequireDefault(require("yargs")); var _vtils = require("vtils"); var _Generator = require("./Generator"); var _templateObject, _templateObject2; TSNode.register({ // 不加载本地的 tsconfig.json skipProject: true, // 仅转译,不做类型检查 transpileOnly: true, // 自定义编译选项 compilerOptions: { strict: false, target: 'es2017', module: 'commonjs', moduleResolution: 'node', declaration: false, removeComments: false, esModuleInterop: true, allowSyntheticDefaultImports: true, importHelpers: false, // 转换 js,支持在 ytt.config.js 里使用最新语法 allowJs: true, lib: ['es2017'] } }); function run(_x, _x2) { return _run.apply(this, arguments); } /* istanbul ignore next */ function _run() { _run = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(cmd, options) { var useCustomConfigFile, cwd, configTSFile, configJSFile, configFile, configFileExist, configTSFileExist, configJSFileExist, answers, outputConfigFile, outputConfigFileType, _answers, _config2, _config2$hooks, config, generator, spinner, _hooks, delayNotice, output, _spinner, _generator, _config, _config$hooks; return _regenerator.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: useCustomConfigFile = false; if (options != null && options.configFile) { _context.next = 18; break; } cwd = process.cwd(); configTSFile = _path.default.join(cwd, 'ytt.config.ts'); configJSFile = _path.default.join(cwd, 'ytt.config.js'); _context.next = 7; return _fsExtra.default.pathExists(configTSFile); case 7: configTSFileExist = _context.sent; _context.t0 = !configTSFileExist; if (!_context.t0) { _context.next = 13; break; } _context.next = 12; return _fsExtra.default.pathExists(configJSFile); case 12: _context.t0 = _context.sent; case 13: configJSFileExist = _context.t0; configFileExist = configTSFileExist || configJSFileExist; configFile = configTSFileExist ? configTSFile : configJSFile; _context.next = 24; break; case 18: useCustomConfigFile = true; configFile = options.configFile; cwd = _path.default.dirname(configFile); _context.next = 23; return _fsExtra.default.pathExists(configFile); case 23: configFileExist = _context.sent; case 24: if (!(cmd === 'help')) { _context.next = 28; break; } console.log("\n" + (0, _vtils.dedent)(_templateObject || (_templateObject = (0, _taggedTemplateLiteralLoose2.default)(["\n # \u7528\u6CD5\n \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6: ytt init\n \u751F\u6210\u4EE3\u7801: ytt\n \u67E5\u770B\u5E2E\u52A9: ytt help\n\n # GitHub\n https://github.com/fjc0k/yapi-to-typescript\n "]))) + "\n"); _context.next = 87; break; case 28: if (!(cmd === 'init')) { _context.next = 51; break; } if (!configFileExist) { _context.next = 36; break; } _consola.default.info("\u68C0\u6D4B\u5230\u914D\u7F6E\u6587\u4EF6: " + configFile); _context.next = 33; return (0, _prompts.default)({ message: '是否覆盖已有配置文件?', name: 'override', type: 'confirm' }); case 33: answers = _context.sent; if (answers.override) { _context.next = 36; break; } return _context.abrupt("return"); case 36: if (!useCustomConfigFile) { _context.next = 41; break; } outputConfigFile = configFile; outputConfigFileType = configFile.endsWith('.js') ? 'js' : 'ts'; _context.next = 46; break; case 41: _context.next = 43; return (0, _prompts.default)({ message: '选择配置文件类型?', name: 'configFileType', type: 'select', choices: [{ title: 'TypeScript(ytt.config.ts)', value: 'ts' }, { title: 'JavaScript(ytt.config.js)', value: 'js' }] }); case 43: _answers = _context.sent; outputConfigFile = _answers.configFileType === 'js' ? configJSFile : configTSFile; outputConfigFileType = _answers.configFileType; case 46: _context.next = 48; return _fsExtra.default.outputFile(outputConfigFile, (0, _vtils.dedent)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteralLoose2.default)(["\n import { defineConfig } from 'yapi-to-typescript'\n\n export default defineConfig([\n {\n serverUrl: 'http://foo.bar',\n typesOnly: false,\n target: '", "',\n reactHooks: {\n enabled: false,\n },\n prodEnvName: 'production',\n outputFilePath: 'src/api/index.", "',\n requestFunctionFilePath: 'src/api/request.", "',\n dataKey: 'data',\n projects: [\n {\n token: 'hello',\n categories: [\n {\n id: 0,\n getRequestFunctionName(interfaceInfo, changeCase) {\n // \u4EE5\u63A5\u53E3\u5168\u8DEF\u5F84\u751F\u6210\u8BF7\u6C42\u51FD\u6570\u540D\n return changeCase.camelCase(interfaceInfo.path)\n\n // \u82E5\u751F\u6210\u7684\u8BF7\u6C42\u51FD\u6570\u540D\u5B58\u5728\u8BED\u6CD5\u5173\u952E\u8BCD\u62A5\u9519\u3001\u6216\u60F3\u901A\u8FC7\u67D0\u4E2A\u5173\u952E\u8BCD\u89E6\u53D1 IDE \u81EA\u52A8\u5F15\u5165\u63D0\u793A\uFF0C\u53EF\u8003\u8651\u52A0\u524D\u7F00\uFF0C\u5982:\n // return changeCase.camelCase(`api_${interfaceInfo.path}`)\n\n // \u82E5\u751F\u6210\u7684\u8BF7\u6C42\u51FD\u6570\u540D\u6709\u91CD\u590D\u62A5\u9519\uFF0C\u53EF\u8003\u8651\u5C06\u63A5\u53E3\u8BF7\u6C42\u65B9\u5F0F\u7EB3\u5165\u751F\u6210\u6761\u4EF6\uFF0C\u5982:\n // return changeCase.camelCase(`${interfaceInfo.method}_${interfaceInfo.path}`)\n },\n },\n ],\n },\n ],\n },\n ])\n "], ["\n import { defineConfig } from 'yapi-to-typescript'\n\n export default defineConfig([\n {\n serverUrl: 'http://foo.bar',\n typesOnly: false,\n target: '", "',\n reactHooks: {\n enabled: false,\n },\n prodEnvName: 'production',\n outputFilePath: 'src/api/index.", "',\n requestFunctionFilePath: 'src/api/request.", "',\n dataKey: 'data',\n projects: [\n {\n token: 'hello',\n categories: [\n {\n id: 0,\n getRequestFunctionName(interfaceInfo, changeCase) {\n // \u4EE5\u63A5\u53E3\u5168\u8DEF\u5F84\u751F\u6210\u8BF7\u6C42\u51FD\u6570\u540D\n return changeCase.camelCase(interfaceInfo.path)\n\n // \u82E5\u751F\u6210\u7684\u8BF7\u6C42\u51FD\u6570\u540D\u5B58\u5728\u8BED\u6CD5\u5173\u952E\u8BCD\u62A5\u9519\u3001\u6216\u60F3\u901A\u8FC7\u67D0\u4E2A\u5173\u952E\u8BCD\u89E6\u53D1 IDE \u81EA\u52A8\u5F15\u5165\u63D0\u793A\uFF0C\u53EF\u8003\u8651\u52A0\u524D\u7F00\uFF0C\u5982:\n // return changeCase.camelCase(\\`api_\\${interfaceInfo.path}\\`)\n\n // \u82E5\u751F\u6210\u7684\u8BF7\u6C42\u51FD\u6570\u540D\u6709\u91CD\u590D\u62A5\u9519\uFF0C\u53EF\u8003\u8651\u5C06\u63A5\u53E3\u8BF7\u6C42\u65B9\u5F0F\u7EB3\u5165\u751F\u6210\u6761\u4EF6\uFF0C\u5982:\n // return changeCase.camelCase(\\`\\${interfaceInfo.method}_\\${interfaceInfo.path}\\`)\n },\n },\n ],\n },\n ],\n },\n ])\n "])), outputConfigFileType === 'js' ? 'javascript' : 'typescript', outputConfigFileType, outputConfigFileType)); case 48: _consola.default.success('写入配置文件完毕'); _context.next = 87; break; case 51: if (configFileExist) { _context.next = 53; break; } return _context.abrupt("return", _consola.default.error("\u627E\u4E0D\u5230\u914D\u7F6E\u6587\u4EF6: " + (useCustomConfigFile ? configFile : configTSFile + " \u6216 " + configJSFile))); case 53: _consola.default.success("\u627E\u5230\u914D\u7F6E\u6587\u4EF6: " + configFile); _context.prev = 54; config = require(configFile).default; generator = new _Generator.Generator(config, { cwd: cwd }); spinner = (0, _ora.default)('正在获取数据并生成代码...').start(); delayNotice = (0, _vtils.wait)(5000); delayNotice.then(function () { spinner.text = "\u6B63\u5728\u83B7\u53D6\u6570\u636E\u5E76\u751F\u6210\u4EE3\u7801... (\u82E5\u957F\u65F6\u95F4\u5904\u4E8E\u6B64\u72B6\u6001\uFF0C\u8BF7\u68C0\u67E5\u662F\u5426\u6709\u63A5\u53E3\u5B9A\u4E49\u7684\u6570\u636E\u8FC7\u5927\u5BFC\u81F4\u62C9\u53D6\u6216\u89E3\u6790\u7F13\u6162)"; }); _context.next = 62; return generator.prepare(); case 62: delayNotice.cancel(); _context.next = 65; return generator.generate(); case 65: output = _context.sent; spinner.stop(); _consola.default.success('获取数据并生成代码完毕'); _context.next = 70; return generator.write(output); case 70: _consola.default.success('写入文件完毕'); _context.next = 73; return generator.destroy(); case 73: _context.next = 75; return (_hooks = config.hooks) == null ? void 0 : _hooks.success == null ? void 0 : _hooks.success(); case 75: _context.next = 85; break; case 77: _context.prev = 77; _context.t1 = _context["catch"](54); (_spinner = spinner) == null ? void 0 : _spinner.stop(); _context.next = 82; return (_generator = generator) == null ? void 0 : _generator.destroy(); case 82: _context.next = 84; return (_config = config) == null ? void 0 : (_config$hooks = _config.hooks) == null ? void 0 : _config$hooks.fail == null ? void 0 : _config$hooks.fail(); case 84: /* istanbul ignore next */ _consola.default.error(_context.t1); case 85: _context.next = 87; return (_config2 = config) == null ? void 0 : (_config2$hooks = _config2.hooks) == null ? void 0 : _config2$hooks.complete == null ? void 0 : _config2$hooks.complete(); case 87: case "end": return _context.stop(); } } }, _callee, null, [[54, 77]]); })); return _run.apply(this, arguments); } if (require.main === module) { var argv = (0, _yargs.default)(process.argv).alias('c', 'config').argv; run(argv._[2], { configFile: argv.config ? _path.default.resolve(process.cwd(), argv.config) : undefined }); }