koatty_cli
Advanced tools
Comparing version
{ | ||
// 使用 IntelliSense 了解相关属性。 | ||
// 悬停以查看现有属性的描述。 | ||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": "Koatty Cli Project", | ||
"type": "node", | ||
"request": "launch", | ||
"mode": "auto", | ||
"program": "${workspaceFolder}/test/index.js", | ||
"envFile": "/Users/richen/Workspace/.env", | ||
"args": [ | ||
// "controller", "-t", "grpc", "hello", | ||
// "new", "hello", | ||
// "service", "-i", "hello", | ||
// "middleware", "hello", | ||
// "model", "test" | ||
"dto", | ||
"test" | ||
// "proto", "test", | ||
], | ||
"cwd": "${workspaceFolder}/test" | ||
} | ||
] | ||
} | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"type": "node", | ||
"request": "launch", | ||
"name": "Debug CLI", | ||
"skipFiles": ["<node_internals>/**"], | ||
"program": "${workspaceFolder}/src/index.js", | ||
// "args": ["new", "test-project"], | ||
// "args": ["controller", "user"], | ||
// "args": ["controller", "-t", "websocket", "user1"], | ||
// "args": ["proto", "user2"], | ||
// "args": ["controller", "-t", "grpc", "user2"], | ||
"args": ["graphql", "user3"], | ||
// "args": ["controller", "-t", "graphql", "user3"], | ||
} | ||
] | ||
} |
125
CHANGELOG.md
@@ -5,15 +5,15 @@ # Changelog | ||
### [3.11.2](https://github.com/koatty/koatty_cli/compare/v3.11.1...v3.11.2) (2024-03-14) | ||
## [](https://github.com/koatty/koatty_cli/compare/v3.11.3...v) (2025-03-16) | ||
### [3.11.3](https://github.com/koatty/koatty_cli/compare/v3.11.2...v3.11.3) (2025-03-16) | ||
### Bug Fixes | ||
* repo url ([bd3f770](https://github.com/koatty/koatty_cli/commit/bd3f7706663fc626d5487273d2cc4ffd3662c632)) | ||
### [3.11.1](https://github.com/koatty/koatty_cli/compare/v3.11.0...v3.11.1) (2024-01-07) | ||
### Features | ||
* interface ([bca375c](https://github.com/koatty/koatty_cli/commit/bca375c5e5b46db3df4dca5f54d7670a7682bfb9)) | ||
* 添加调试配置、Babel 和 Jest 配置文件及相关依赖 ([5489ea2](https://github.com/koatty/koatty_cli/commit/5489ea2f43c5901e7d669827a1e161a2bef03e0b)) | ||
* 增加 GraphQL 模块创建功能及相关配置调整 ([48d8d5b](https://github.com/koatty/koatty_cli/commit/48d8d5baf28cf675a09b67bc00d6541592275381)) | ||
* 增加对 GraphQL 控制器类型的支持及相关处理逻辑 ([8e1206d](https://github.com/koatty/koatty_cli/commit/8e1206de7ab655a1ca0b74cd3a5bf78f37e35f9c)) | ||
* graphql parser ([94a9c7b](https://github.com/koatty/koatty_cli/commit/94a9c7ba3c0ecb53bf8d616cc1c3a818fe8bcaaf)) | ||
* init ([20c93f2](https://github.com/koatty/koatty_cli/commit/20c93f260eaeb620bdec2863f917b5411c449d56)) | ||
* schema文件解析 ([d0f70b0](https://github.com/koatty/koatty_cli/commit/d0f70b0f69fbac249ab6d0107d752644bd830ce4)) | ||
@@ -23,101 +23,16 @@ | ||
* version ([3b5a62c](https://github.com/koatty/koatty_cli/commit/3b5a62c806d7c6a942e5cc0865ca3a5300f5c16f)) | ||
* version ([46b6881](https://github.com/koatty/koatty_cli/commit/46b688121e0f636351af1992671849c7daaa866b)) | ||
* 修正 GraphQL Schema 文件路径及相关模板替换逻辑 ([5355cfb](https://github.com/koatty/koatty_cli/commit/5355cfb8d2a27a6679741ddcb585d32ae75b23a8)) | ||
* 修正格式化文件及字符串处理函数中的语法错误 ([57a208a](https://github.com/koatty/koatty_cli/commit/57a208aabe7445243bd8111cc6732fd82bf040a3)) | ||
* 修正GraphQL类型检查逻辑 ([15354c5](https://github.com/koatty/koatty_cli/commit/15354c5a36362711d4eb3beb51e093b5abe26b1f)) | ||
* 优化 GraphQL 和 Proto 文件路径处理逻辑及相关配置调整 ([a911554](https://github.com/koatty/koatty_cli/commit/a911554ce27baafd071c818cfbdf78549bfc9d6a)) | ||
* bug ([c0acb88](https://github.com/koatty/koatty_cli/commit/c0acb88c78817d24c894b709a9bf7b6f87ccf514)) | ||
* enhance command line interface with detailed documentation and new commands for creating various modules ([59d0695](https://github.com/koatty/koatty_cli/commit/59d0695656a716bbe5708e8f7b20d381df6573bc)) | ||
* f ([5c66f1f](https://github.com/koatty/koatty_cli/commit/5c66f1f3dc0df30285877199bf7921f273a1f96a)) | ||
* rename ([4207170](https://github.com/koatty/koatty_cli/commit/42071700a43ebe9cc702f7658fd0fc672e3bfa34)) | ||
* test case ([91e1f8f](https://github.com/koatty/koatty_cli/commit/91e1f8f86b03e02d3ea4d32e370ff53c1df4ec1d)) | ||
* update GraphQL controller argument and HTTP method mapping logic ([1e35b5b](https://github.com/koatty/koatty_cli/commit/1e35b5b12881be4acc4cd1058f7f7b7f825edf58)) | ||
## [3.11.0](https://github.com/koatty/koatty_cli/compare/v3.10.3...v3.11.0) (2024-01-03) | ||
### Refactor | ||
### Bug Fixes | ||
* use version template ([5681ccf](https://github.com/koatty/koatty_cli/commit/5681ccf30d1d368d5bbcfe62df2d87b58fb59d09)) | ||
### [3.10.3](https://github.com/koatty/koatty_cli/compare/v3.10.2...v3.10.3) (2023-12-28) | ||
### Bug Fixes | ||
* entity ([255f540](https://github.com/koatty/koatty_cli/commit/255f540d926961ad6d4f9a230b0d4da380aa9dc9)) | ||
### [3.10.2](https://github.com/koatty/koatty_cli/compare/v3.10.1...v3.10.2) (2023-12-24) | ||
### Bug Fixes | ||
* github镜像 ([ebb60ee](https://github.com/koatty/koatty_cli/commit/ebb60ee16642b0e203179cf7f282bff121434b1b)) | ||
* github镜像 ([17440c3](https://github.com/koatty/koatty_cli/commit/17440c3c9f65ba018e1966467b7e451c069b3c0f)) | ||
### [3.10.1](https://github.com/koatty/koatty_cli/compare/v3.10.0...v3.10.1) (2023-12-06) | ||
### Bug Fixes | ||
* add entity ([07200c4](https://github.com/koatty/koatty_cli/commit/07200c49e4158ead26b756469adccc6793c562f6)) | ||
* add entity ([6cb8f1c](https://github.com/koatty/koatty_cli/commit/6cb8f1c9c899895b7a70ecbc89bea4f6c478f30b)) | ||
## [3.10.0](https://github.com/koatty/koatty_cli/compare/v3.9.4...v3.10.0) (2023-11-10) | ||
### Bug Fixes | ||
* add exception ([db5d435](https://github.com/koatty/koatty_cli/commit/db5d4351674a4dc929fa06b54ace3a69a3ec8c38)) | ||
### [3.9.4](https://github.com/koatty/koatty_cli/compare/v3.9.3...v3.9.4) (2023-09-11) | ||
### Bug Fixes | ||
* subpath ([e2ab67d](https://github.com/koatty/koatty_cli/commit/e2ab67dafd651baebe46ea5019ac3d7a8d5b2028)) | ||
### [3.9.3](https://github.com/koatty/koatty_cli/compare/v3.9.2...v3.9.3) (2023-09-11) | ||
### Bug Fixes | ||
* 支持service接口 ([086afe6](https://github.com/koatty/koatty_cli/commit/086afe639a1d0fb2374b41396b856c1b0d32268e)) | ||
### [3.9.2](https://github.com/koatty/koatty_cli/compare/v3.7.3...v3.9.2) (2023-08-17) | ||
### Bug Fixes | ||
* args ([bae059f](https://github.com/koatty/koatty_cli/commit/bae059ffce51331473d55e03df52241197d8a8ec)) | ||
* license ([3784d94](https://github.com/koatty/koatty_cli/commit/3784d949f3dda69a3c6e4cdc8cee92b094a589ee)) | ||
### [3.7.3](https://github.com/koatty/koatty_cli/compare/v3.7.2...v3.7.3) (2023-01-13) | ||
### Bug Fixes | ||
* rm .git ([a2e0144](https://github.com/koatty/koatty_cli/commit/a2e0144d04f0e96f63b2a53a0adc02be05d15993)) | ||
### [3.7.2](https://github.com/koatty/koatty_cli/compare/v3.7.1...v3.7.2) (2023-01-06) | ||
### Bug Fixes | ||
* 修复proto扩展名错误 ([a32ebe6](https://github.com/koatty/koatty_cli/commit/a32ebe6cbba5d3d77a6a7b86d0ad41494aea00b0)) | ||
* 修复proto文件命名 ([3189a4d](https://github.com/koatty/koatty_cli/commit/3189a4d9203f910bda671bb68b06dfec1ccec509)) | ||
### [3.7.1](https://github.com/koatty/koatty_cli/compare/v3.7.0...v3.7.1) (2022-11-18) | ||
### Bug Fixes | ||
* change logo ([d1ed827](https://github.com/koatty/koatty_cli/commit/d1ed827cc4603cd410081907155e4c0fc726881e)) | ||
## [3.7.0](https://github.com/koatty/koatty_cli/compare/v3.6.2...v3.7.0) (2022-11-05) | ||
### Bug Fixes | ||
* 支持proto更新 ([a767e84](https://github.com/koatty/koatty_cli/commit/a767e8428d753cea507af40c62bb5067ab26ca8a)) | ||
### [3.6.2](https://github.com/koatty/koatty_cli/compare/v3.6.1...v3.6.2) (2022-03-08) | ||
### 3.6.1 (2022-03-04) | ||
## [3.6.0](https://github.com/koatty/koatty_cli/compare/v3.5.3...v3.6.0) (2022-03-04) | ||
### [3.5.3](https://github.com/thinkkoa/koatty_cli/compare/v3.5.2...v3.5.3) (2021-12-18) | ||
### 3.5.2 (2021-12-13) | ||
* 更新 ESLint 配置和依赖项 ([d1db75c](https://github.com/koatty/koatty_cli/commit/d1db75c7fac5b5624dbba08df984b9a23683f098)) |
{ | ||
"name": "koatty_cli", | ||
"version": "3.11.2", | ||
"version": "3.12.0", | ||
"description": "Koatty command line tool.", | ||
@@ -42,6 +42,17 @@ "scripts": { | ||
"devDependencies": { | ||
"@babel/core": "^7.26.9", | ||
"@babel/preset-env": "^7.26.9", | ||
"@commitlint/cli": "^18.x.x", | ||
"@commitlint/config-conventional": "^18.x.x", | ||
"chai": "^5.2.0", | ||
"conventional-changelog-cli": "^4.x.x", | ||
"eslint": "^8.x.x", | ||
"eslint-plugin-jest": "^25.x.x", | ||
"eslint-plugin-jest": "^27.x.x", | ||
"husky": "^4.x.x", | ||
"jest": "^29.x.x", | ||
"standard-version": "^9.x.x" | ||
"jest-html-reporters": "^3.x.x", | ||
"openapi-types": "^12.1.3", | ||
"reflect-metadata": "^0.x.x", | ||
"standard-version": "^9.x.x", | ||
"supertest": "^7.0.0" | ||
}, | ||
@@ -52,11 +63,13 @@ "dependencies": { | ||
"commander": "^3.0.2", | ||
"del": "^6.1.1", | ||
"del": "^6.0.0", | ||
"isomorphic-git": "^1.25.0", | ||
"koatty_graphql": "^1.0.2", | ||
"koatty_lib": "^1.3.4", | ||
"koatty_proto": "^1.1.12", | ||
"mustache": "^4.2.0", | ||
"ncp": "^2.0.0", | ||
"prettier": "^3.5.3", | ||
"replace": "^1.2.2", | ||
"tslib": "^2.6.2", | ||
"update-notifier": "^5.1.0" | ||
} | ||
} | ||
} |
@@ -0,0 +0,0 @@ # koatty_cli |
@@ -6,3 +6,3 @@ /* | ||
* @Date: 2020-12-22 17:29:34 | ||
* @LastEditTime: 2024-03-14 10:59:09 | ||
* @LastEditTime: 2025-03-12 17:59:58 | ||
*/ | ||
@@ -18,5 +18,15 @@ | ||
GRPC_IMPORT: "//_IMPORT_LIST Important! Do not delete this line", | ||
GRPC_METHOD: "//_METHOD_LIST Important! Do not delete this line", | ||
CTL_IMPORT: "//_IMPORT_LIST Important! Do not delete this line", | ||
CTL_METHOD: "//_METHOD_LIST Important! Do not delete this line", | ||
staticMap: new Map(Object.entries({ | ||
proto: "/resource/proto", | ||
graphql: "/resource/graphql", | ||
})), | ||
subfixMap: new Map(Object.entries({ | ||
proto: ".proto", | ||
graphql: ".graphql", | ||
})), | ||
LOGO: ` | ||
@@ -23,0 +33,0 @@ |
@@ -6,47 +6,38 @@ /* | ||
* @Date: 2020-12-22 17:51:07 | ||
* @LastEditTime: 2024-01-10 13:59:31 | ||
* @LastEditTime: 2025-03-16 11:31:06 | ||
*/ | ||
const path = require('path'); | ||
const replace = require('replace'); | ||
const string = require('../utils/sting'); | ||
const log = require('../utils/log'); | ||
const ufs = require('../utils/fs'); | ||
const { LOGO, CLI_TEMPLATE_URL, CLI_TEMPLATE_NAME, GRPC_IMPORT, GRPC_METHOD } = require('./config'); | ||
const { writeAndFormatFile } = require('../utils/format'); | ||
const { LOGO, CLI_TEMPLATE_URL, CLI_TEMPLATE_NAME } = require('./config'); | ||
const template = require('../utils/template'); | ||
const { parseProto, parseMethods, parseFields, parseValues } = require('koatty_proto'); | ||
const { regex } = require('replace/bin/shared-options'); | ||
const { processVer } = require('../utils/version'); | ||
const { isKoattyApp } = require("../utils/path"); | ||
const { createController } = require("../processor/controller"); | ||
const { createMiddleware } = require("../processor/middleware"); | ||
const { createModel } = require("../processor/model"); | ||
const { createPlugin } = require("../processor/model"); | ||
const { createService } = require("../processor/service"); | ||
const { createDefault } = require("../processor/default"); | ||
const cwd = process.cwd(); | ||
let templatePath = ''; | ||
// const templatePath = path.dirname(__dirname) + '/template'; | ||
/** | ||
* check app | ||
* @param {String} path [] | ||
* @return {Boolean} [] | ||
*/ | ||
const isKoattyApp = function (path) { | ||
if (ufs.isExist(path + '.koattysrc')) { | ||
return true; | ||
} | ||
return false; | ||
}; | ||
/** | ||
* | ||
* | ||
* @returns {*} | ||
* Create a new module in Koatty project. | ||
* | ||
* @param {string} name - The name of the module to create | ||
* @param {string} type - Module type ('controller', 'middleware', 'model', 'plugin', 'service') | ||
* @param {Object} opt - Additional options for module creation | ||
* @returns {Promise<void>} | ||
* | ||
* @description | ||
* This function creates a new module in a Koatty project based on templates. | ||
* It validates the project directory, loads templates, and creates the module files. | ||
* Supports different module types including controllers, middlewares, models, | ||
* plugins and services. | ||
* | ||
* @throws {Error} If template loading fails or module creation encounters an error | ||
*/ | ||
const getAppPath = function () { | ||
return path.normalize(cwd + '/src/'); | ||
} | ||
/** | ||
* create module | ||
* | ||
* @param {*} name | ||
* @param {*} type | ||
* @param {*} opt | ||
* @returns {Promise<any>} | ||
*/ | ||
module.exports = async function (name, type, opt) { | ||
@@ -79,18 +70,18 @@ log.info('\n Welcome to use Koatty!'); | ||
case 'controller': | ||
args = createController(name, type, opt); | ||
args = createController(name, type, opt, templatePath); | ||
break; | ||
case 'middleware': | ||
args = createMiddleware(name, type, opt); | ||
args = createMiddleware(name, type, opt, templatePath); | ||
break; | ||
case 'model': | ||
args = createModel(name, type, opt); | ||
args = createModel(name, type, opt, templatePath); | ||
break; | ||
case 'plugin': | ||
args = createPlugin(name, type, opt); | ||
args = createPlugin(name, type, opt, templatePath); | ||
break; | ||
case 'service': | ||
args = createService(name, type, opt); | ||
args = createService(name, type, opt, templatePath); | ||
break; | ||
default: | ||
args = createDefault(name, type, opt); | ||
args = createDefault(name, type, opt, templatePath); | ||
break; | ||
@@ -120,3 +111,3 @@ } | ||
targetDir.push(dir); | ||
await ufs.writeFile(key, element); | ||
await writeAndFormatFile(key, element); | ||
} | ||
@@ -147,389 +138,1 @@ } | ||
/** | ||
* 路径参数处理 | ||
* | ||
* @param {*} name | ||
* @param {*} type | ||
* @returns {*} | ||
*/ | ||
function parseArgs(name, type) { | ||
let destPath = path.resolve(`${getAppPath()}/${type}/`); | ||
const sourcePath = path.resolve(templatePath, `${type}.template`); | ||
if (!ufs.isExist(sourcePath)) { | ||
log.error(`Type ${type} is not supported currently.`); | ||
return; | ||
} | ||
let subModule = '', sourceName = ''; | ||
const subNames = name.split('/'); | ||
if (subNames.length > 1) { | ||
subModule = subNames[0]; | ||
sourceName = subNames[1]; | ||
destPath = `${destPath}/${subModule.toLowerCase()}`; | ||
} else { | ||
sourceName = subNames[0]; | ||
} | ||
let subFix = ".ts" | ||
let newName = `${string.toPascal(sourceName)}${string.toPascal(type)}`; | ||
let camelName = `${sourceName}${string.toPascal(type)}`; | ||
if (type == "proto") { | ||
subFix = ".proto" | ||
newName = `${string.toPascal(sourceName)}`; | ||
camelName = `${string.toPascal(sourceName)}`; | ||
} | ||
const destFile = path.resolve(destPath, `${newName}${subFix}`); | ||
// replace map | ||
const replaceMap = { | ||
'_SUB_PATH': subModule ? '../..' : '..', | ||
'_NEW': sourceName, | ||
'_CLASS_NAME': newName, | ||
'_CAMEL_NAME': camelName | ||
}; | ||
//if target file is exist, ignore it | ||
if (ufs.isExist(destFile) && type != "controller") { | ||
log.error('Module existed' + ' : ' + destFile); | ||
return; | ||
} | ||
const destMap = { | ||
[sourcePath]: destFile, | ||
}; | ||
return { sourceName, sourcePath, newName, subModule, destMap, replaceMap, destPath, destFile }; | ||
} | ||
/** | ||
* 处理gRPC控制器 | ||
* | ||
* @param {*} args | ||
* @returns {*} | ||
*/ | ||
function parseGrpcArgs(args) { | ||
// 根据控制器名自动寻找proto文件 | ||
const pascalName = string.toPascal(args.sourceName); | ||
const protoFile = `${getAppPath()}/proto/${pascalName}.proto` | ||
if (!ufs.isExist(protoFile)) { | ||
throw Error(`proto file : ${protoFile} does not exist. Please use the 'koatty proto ${args.sourceName}' command to create.`); | ||
} | ||
const source = ufs.readFile(protoFile) | ||
const res = parseProto(source); | ||
const methods = parseMethods(res); | ||
if (!Object.hasOwnProperty.call(methods, pascalName)) { | ||
throw Error('The proto file does not contain the service' + ' : ' + pascalName); | ||
} | ||
const service = methods[pascalName]; | ||
const methodArr = []; | ||
const dtoArr = []; | ||
const importArr = []; | ||
let methodStr = ufs.readFile(path.resolve(templatePath, `controller_grpc_method.template`)); | ||
let importStr = ufs.readFile(path.resolve(templatePath, `controller_grpc_import.template`)); | ||
let exCtlContent = ""; | ||
if (ufs.isExist(args.destFile)) { | ||
exCtlContent = ufs.readFile(args.destFile); | ||
} | ||
Object.keys(service).map(key => { | ||
if (Object.hasOwnProperty.call(service, key)) { | ||
const it = service[key]; | ||
if (it && !exCtlContent.includes(`${it.name}(`)) { | ||
let method = methodStr.replace(/_METHOD_NAME/g, it.name); | ||
let requestType = 'any'; | ||
if (it.requestType != "") { | ||
requestType = `${it.requestType}Dto`; | ||
if (!exCtlContent.includes(requestType)) { | ||
dtoArr.push(requestType); | ||
} | ||
} | ||
let responseType = 'any'; | ||
if (it.responseType != 'any') { | ||
responseType = `${it.responseType}Dto`; | ||
if (!exCtlContent.includes(responseType)) { | ||
dtoArr.push(responseType); | ||
} | ||
} | ||
method = method.replace(/_REQUEST_TYPE/g, requestType); | ||
method = method.replace(/_RESPONSE_TYPE/g, responseType); | ||
method = method.replace(/_RESPONSE_RETURN/g, it.responseType == 'any' ? '{}' : `new ${responseType}();`); | ||
methodArr.push(method); | ||
} | ||
} | ||
}); | ||
for (const it of dtoArr) { | ||
importArr.push(importStr.replace(/_DTO_NAME/g, it).replace(/_SUB_PATH/g, args.subModule ? '../..' : '..')) | ||
} | ||
args.createMap = {}; | ||
if (exCtlContent.length == 0) { | ||
exCtlContent = ufs.readFile(path.resolve(templatePath, `controller_grpc.template`)); | ||
} | ||
if (importArr.length > 0) { | ||
importArr.push(GRPC_IMPORT); | ||
exCtlContent = exCtlContent.replace(new RegExp(GRPC_IMPORT, "g"), importArr.join("\n")); | ||
} | ||
if (methodArr.length > 0) { | ||
methodArr.push(GRPC_METHOD); | ||
exCtlContent = exCtlContent.replace(new RegExp(GRPC_METHOD, "g"), methodArr.join("\n")); | ||
} | ||
args.createMap[args.destFile] = exCtlContent; | ||
const destPath = path.resolve(`${getAppPath()}/dto/`); | ||
// enum | ||
const values = parseValues(res); | ||
const enumContent = ufs.readFile(path.resolve(templatePath, `enum.template`)); | ||
let enumImports = ""; | ||
Object.keys(values).map(key => { | ||
if (Object.hasOwnProperty.call(values, key)) { | ||
const it = values[key]; | ||
if (it) { | ||
const name = `${destPath}/${it.name}.ts`; | ||
let props = [...(it.fields || [])]; | ||
enumImports = `${enumImports}import { ${it.name} } from "./${it.name}";\n`; | ||
if (!ufs.isExist(name)) { | ||
args.createMap[name] = enumContent.replace(/_CLASS_NAME/g, it.name).replace(/\/\/_FIELDS/g, props.join("\n\n")); | ||
} | ||
} | ||
} | ||
}); | ||
// request & reply | ||
const fields = parseFields(res); | ||
const dtoContent = ufs.readFile(path.resolve(templatePath, `dto.template`)); | ||
Object.keys(fields).map(key => { | ||
if (Object.hasOwnProperty.call(fields, key)) { | ||
const it = fields[key]; | ||
if (it) { | ||
const name = `${destPath}/${it.name}Dto.ts`; | ||
let props = [...(it.fields || [])]; | ||
props = props.map(elem => { | ||
if (elem != '') { | ||
return ` @IsDefined()\n ${elem}`; | ||
} | ||
return ''; | ||
}); | ||
if (!ufs.isExist(name)) { | ||
args.createMap[name] = dtoContent.replace(/_CLASS_NAME/g, `${it.name}Dto`) | ||
.replace(/\/\/_FIELDS/g, props.join("\n\n") | ||
.replace(/\/\/_ENUM_IMPORT/g, enumImports)); | ||
} | ||
} | ||
} | ||
}); | ||
return args; | ||
} | ||
/** | ||
* | ||
* | ||
* @param {*} name | ||
* @param {*} type | ||
* @param {*} opt | ||
* @returns {*} | ||
*/ | ||
function createController(name, type, opt) { | ||
const args = parseArgs(name, type); | ||
if (!args) { | ||
process.exit(0); | ||
} | ||
const protocol = opt.type || 'http'; | ||
if (protocol === "grpc") { | ||
parseGrpcArgs(args); | ||
args.destMap = {}; | ||
if (args.subModule) { | ||
args.replaceMap['_NEW'] = `/${string.toPascal(args.subModule)}/${string.toPascal(args.sourceName)}`; | ||
} else { | ||
args.replaceMap['_NEW'] = `/${string.toPascal(args.sourceName)}`; | ||
} | ||
return args; | ||
} else if (protocol === "websocket") { | ||
const sourcePath = path.resolve(templatePath, `controller_ws.template`); | ||
args.destMap[sourcePath] = args.destMap[args.sourcePath]; | ||
args.destMap[args.sourcePath] = ""; | ||
} | ||
if (args.subModule) { | ||
args.replaceMap['_NEW'] = `/${args.subModule}/${args.sourceName}`; | ||
} else { | ||
args.replaceMap['_NEW'] = `/${args.sourceName}`; | ||
} | ||
return args; | ||
} | ||
/** | ||
* | ||
* | ||
* @param {*} name | ||
* @param {*} type | ||
* @param {*} opt | ||
* @returns {*} | ||
*/ | ||
function createMiddleware(name, type, opt) { | ||
const args = parseArgs(name, type); | ||
if (!args) { | ||
process.exit(0); | ||
} | ||
args.callBack = function () { | ||
log.log(); | ||
log.log('please modify /app/config/middlewate.ts file:'); | ||
log.log(); | ||
log.log(`list: [..., "${args.newName}"] //加载中间件`); | ||
log.log('config: { //中间件配置 '); | ||
log.log(` "${args.newName}":{ //todo }`); | ||
log.log('}'); | ||
log.log(); | ||
}; | ||
return args; | ||
} | ||
/** | ||
* | ||
* | ||
* @param {*} name | ||
* @param {*} type | ||
* @param {*} opt | ||
* @returns {*} | ||
*/ | ||
function createPlugin(name, type, opt) { | ||
const args = parseArgs(name, type); | ||
if (!args) { | ||
process.exit(0); | ||
} | ||
args.callBack = function () { | ||
log.log(); | ||
log.log('please modify /app/config/plugin.ts file:'); | ||
log.log(); | ||
log.log(`list: [..., "${args.newName}"] //加载的插件列表,执行顺序按照数组元素顺序`); | ||
log.log('config: { //插件配置 '); | ||
log.log(` "${args.newName}":{ //todo }`); | ||
log.log('}'); | ||
log.log(); | ||
}; | ||
return args; | ||
} | ||
/** | ||
* | ||
* | ||
* @param {*} name | ||
* @param {*} type | ||
* @param {*} opt | ||
* @returns {*} | ||
*/ | ||
function createModel(name, type, opt) { | ||
const args = parseArgs(name, type); | ||
if (!args) { | ||
process.exit(0); | ||
} | ||
const orm = opt.orm || 'typeorm'; | ||
if (orm === 'typeorm') { | ||
const sourcePath = path.resolve(templatePath, `model.${orm}.template`); | ||
args.destMap[sourcePath] = args.destMap[args.sourcePath]; | ||
args.destMap[args.sourcePath] = ""; | ||
const entityPath = path.resolve(templatePath, `entity.${orm}.template`); | ||
const entityName = `${string.toPascal(args.sourceName)}Entity`; | ||
const entityFile = `${entityName}.ts`; | ||
const entityDest = path.resolve(`${args.destPath}/entity`, entityFile); | ||
if (!ufs.isExist(entityDest)) { | ||
args.destMap[entityPath] = entityDest; | ||
} | ||
args.replaceMap['_ENTITY_NAME'] = entityName; | ||
const pluginPath = path.resolve(templatePath, `plugin.${orm}.template`); | ||
const pluginName = `${string.toPascal(orm)}Plugin`; | ||
const pluginFile = `${pluginName}.ts`; | ||
const destPath = path.resolve(`${getAppPath()}/plugin/${pluginFile}`); | ||
if (!ufs.isExist(destPath)) { | ||
args.destMap[pluginPath] = destPath; | ||
} | ||
args.callBack = function () { | ||
log.log(); | ||
log.warning('to used the koatty_typeorm plugin:'); | ||
log.log(); | ||
log.log('https://github.com/Koatty/koatty_typeorm'); | ||
log.log(); | ||
log.log('please modify /app/config/plugin.ts file:'); | ||
log.log(); | ||
log.log(`list: [..., "TypeormPlugin"]`); | ||
log.log('config: { //插件配置 '); | ||
log.log(` "TypeormPlugin":{ //todo }`); | ||
log.log('}'); | ||
log.log(); | ||
}; | ||
} | ||
if (!ufs.isExist(args.sourcePath)) { | ||
log.error(`Type ${type} is not supported currently.`); | ||
process.exit(0); | ||
} | ||
return args; | ||
} | ||
/** | ||
* | ||
* | ||
* @param {*} name | ||
* @param {*} type | ||
* @param {*} opt | ||
* @returns {*} | ||
*/ | ||
function createService(name, type, opt) { | ||
const args = parseArgs(name, type); | ||
if (!args) { | ||
process.exit(0); | ||
} | ||
let sourcePath = path.resolve(templatePath, `service.template`); | ||
const serviceName = `${args.newName}.ts`; | ||
let serviceDest = path.resolve(`${args.destPath}`, serviceName); | ||
if (opt.interface == true) { | ||
args.replaceMap['_SUB_PATH'] = args.subModule ? '../../..' : '../..'; | ||
serviceDest = path.resolve(`${args.destPath}/impl`, serviceName); | ||
sourcePath = path.resolve(templatePath, `service.impl.template`); | ||
args.destMap[args.sourcePath] = ""; | ||
const tplPath = path.resolve(templatePath, `service.interface.template`); | ||
const newName = `I${args.newName}.ts`; | ||
const destPath = path.resolve(args.destPath, newName); | ||
if (!ufs.isExist(destPath)) { | ||
args.destMap[tplPath] = destPath; | ||
} | ||
} | ||
if (!ufs.isExist(serviceDest)) { | ||
args.destMap[sourcePath] = serviceDest; | ||
} | ||
return args; | ||
} | ||
/** | ||
* | ||
* | ||
* @param {*} name | ||
* @param {*} type | ||
* @param {*} opt | ||
* @returns {*} | ||
*/ | ||
function createDefault(name, type, opt) { | ||
const args = parseArgs(name, type); | ||
if (!args) { | ||
process.exit(0); | ||
} | ||
return args; | ||
} | ||
@@ -6,3 +6,3 @@ /* | ||
* @Date: 2020-12-08 15:08:37 | ||
* @LastEditTime: 2024-01-04 05:41:47 | ||
* @LastEditTime: 2025-03-16 11:27:09 | ||
*/ | ||
@@ -15,2 +15,3 @@ | ||
const ufs = require('../utils/fs'); | ||
const { writeAndFormatFile } = require('../utils/format'); | ||
const template = require('../utils/template'); | ||
@@ -48,3 +49,22 @@ | ||
const create = async (projectName, options) => { | ||
/** | ||
* Create a new Koatty project with specified template. | ||
* | ||
* @param {string} projectName - The name of the project to create | ||
* @param {object} options - Project creation options | ||
* @param {string} options.template - Template type ('project'|'middleware'|'plugin') | ||
* @returns {Promise<void>} | ||
* | ||
* @description | ||
* Creates a new project by: | ||
* 1. Checking if project name already exists | ||
* 2. Loading template from remote repository | ||
* 3. Copying template files to project directory | ||
* 4. Replacing placeholder values with project specific values | ||
* 5. Creating project configuration file | ||
* 6. Removing git directory | ||
* | ||
* After creation, displays instructions for project setup and running. | ||
*/ | ||
module.exports = async (projectName, options) => { | ||
log.info('\n Welcome to use Koatty!'); | ||
@@ -102,3 +122,3 @@ log.info(LOGO); | ||
ufs.writeFile(`${projectDir}/.koattysrc`, JSON.stringify({ | ||
await writeAndFormatFile(`${projectDir}/.koattysrc`, JSON.stringify({ | ||
projectName, | ||
@@ -133,2 +153,1 @@ })); | ||
module.exports = create; |
169
src/index.js
@@ -11,6 +11,11 @@ #!/usr/bin/env node | ||
const camelias = str => str.replace(/-(\w)/g, (_, c) => (c ? c.toUpperCase() : '')); | ||
const camelias = (str) => str.replace(/-(\w)/g, (_, c) => (c ? c.toUpperCase() : '')); | ||
// commander passes the Command object itself as options, | ||
// extract only actual options into a fresh object. | ||
/** | ||
* Clean and transform command line options into a camelCase object. | ||
* | ||
* @param {Command} cmd - Commander.js command object containing parsed options | ||
* @returns {Object} Object with camelCase keys from long option names and their values | ||
* @private | ||
*/ | ||
const cleanArgs = (cmd) => { | ||
@@ -29,6 +34,23 @@ const args = {}; | ||
/** | ||
* Set program version from package.json and define usage format | ||
* for command line interface. | ||
* | ||
* @version {string} pkg.version - The version number from package.json | ||
* @usage [command] <options ...> - The command format pattern | ||
*/ | ||
program.version(pkg.version).usage('[command] <options ...>'); | ||
// create project | ||
/** | ||
* Command to create a new Koatty project | ||
* | ||
* @param {string} projectName - The name of the project to create | ||
* @param {Object} cmdObj - Command options | ||
* @param {string} [cmdObj.template] - Template type to use: project|middleware|plugin | ||
* | ||
* @example | ||
* ```bash | ||
* koatty new myproject -t project | ||
* ``` | ||
*/ | ||
program | ||
@@ -42,7 +64,17 @@ .command('new <projectName>') | ||
// create controller | ||
/** | ||
* Create a new controller class command. | ||
* | ||
* @command controller <controllerName> | ||
* @description Creates a new controller class with specified name and type | ||
* @param {string} controllerName - The name of the controller to create | ||
* @option {string} -t, --type - Controller type (http|grpc|websocket|graphql), defaults to http | ||
* @example | ||
* koatty controller UserController | ||
* koatty controller UserController --type grpc | ||
*/ | ||
program | ||
.command('controller <controllerName>') | ||
.description('create controller class') | ||
.option('-t, --type <type>', 'create controller\'s type, http|grpc|websocket, default is http controller.') | ||
.option('-t, --type <type>', 'create controller\'s type, http|grpc|websocket|graphql, default is http controller.') | ||
.action((controllerName, cmdObj) => { | ||
@@ -52,3 +84,12 @@ create_module(controllerName, 'controller', cleanArgs(cmdObj)); | ||
// create middleware | ||
/** | ||
* Register command to create middleware class | ||
* @command middleware <middlewareName> | ||
* @description Create a new middleware class with specified name | ||
* @param {string} middlewareName The name of middleware to create | ||
* @example | ||
* ```bash | ||
* koatty middleware TestMiddleware | ||
* ``` | ||
*/ | ||
program | ||
@@ -61,4 +102,15 @@ .command('middleware <middlewareName>') | ||
// create service | ||
/** | ||
* Creates a service class command | ||
* | ||
* @command service <serviceName> | ||
* @description Create a new service class with optional interface | ||
* @param {string} serviceName - The name of the service to create | ||
* @option {boolean} -i, --interface - Whether to create service's interface, defaults to false | ||
* @example | ||
* ```bash | ||
* koatty service user | ||
* koatty service user --interface | ||
* ``` | ||
*/ | ||
program | ||
@@ -75,3 +127,14 @@ .command('service <serviceName>') | ||
// create plugin | ||
/** | ||
* Create a plugin command that generates a new plugin class | ||
* | ||
* @command plugin <pluginName> | ||
* @description Create a new plugin class with specified name | ||
* @param {string} pluginName - The name of the plugin to create | ||
* @action Calls create_module function with plugin type | ||
* @example | ||
* ```bash | ||
* koatty plugin TestPlugin | ||
* ``` | ||
*/ | ||
program | ||
@@ -84,4 +147,14 @@ .command('plugin <pluginName>') | ||
// create aspect | ||
/** | ||
* Create a new aspect class command | ||
* | ||
* @command aspect <aspectName> | ||
* @description Create a new aspect class with specified name | ||
* @param {string} aspectName - The name of the aspect to create | ||
* @action Calls create_module function with aspect type | ||
* @example | ||
* ```bash | ||
* koatty aspect TestAspect | ||
* ``` | ||
*/ | ||
program | ||
@@ -94,3 +167,14 @@ .command('aspect <aspectName>') | ||
// create dto class | ||
/** | ||
* Create a new dto class command | ||
* | ||
* @command dto <dtoName> | ||
* @description Create a new dto class with specified name | ||
* @param {string} dtoName - The name of the dto to create | ||
* @action Calls create_module function with dto type | ||
* @example | ||
* ```bash | ||
* koatty dto UserDto | ||
* ``` | ||
*/ | ||
program | ||
@@ -103,3 +187,14 @@ .command('dto <dtoName>') | ||
// create exception class | ||
/** | ||
* Create a new exception class command | ||
* | ||
* @command exception <dtoName> | ||
* @description Create a new exception class with specified name | ||
* @param {string} dtoName - The name of the exception to create | ||
* @action Calls create_module function with exception type | ||
* @example | ||
* ```bash | ||
* koatty exception UserException | ||
* ``` | ||
*/ | ||
program | ||
@@ -112,3 +207,14 @@ .command('exception <dtoName>') | ||
// create protobuf file | ||
/** | ||
* Create a new proto file command | ||
* | ||
* @command proto <protoName> | ||
* @description Create a new proto file with specified name | ||
* @param {string} protoName - The name of the proto to create | ||
* @action Calls create_module function with proto type | ||
* @example | ||
* ```bash | ||
* koatty proto user | ||
* ``` | ||
*/ | ||
program | ||
@@ -121,8 +227,35 @@ .command('proto <protoName>') | ||
/** | ||
* Command to create a GraphQL schema | ||
* @param {string} protoName - The name of the GraphQL schema to create | ||
* @description Creates a new GraphQL schema module with the specified name | ||
* @example | ||
* ```bash | ||
* koatty graphql user | ||
* ``` | ||
*/ | ||
program | ||
.command('graphql <protoName>') | ||
.description('create graphql schema') | ||
.action((protoName) => { | ||
create_module(protoName, 'graphql', undefined); | ||
}); | ||
// create model | ||
/** | ||
* Create a model class command | ||
* | ||
* @command model <modelName> | ||
* @description Creates a new model class with specified name | ||
* @param {string} modelName - The name of the model to create | ||
* @option {string} -o, --orm - Specify ORM module to use (defaults to typeorm) | ||
* @example | ||
* ```bash | ||
* koatty model User | ||
* koatty model User --orm thinkorm | ||
* ``` | ||
*/ | ||
program | ||
.command('model <modelName>') | ||
.description('create model class') | ||
.option('-o, --orm <orm>', 'used orm module (thinkorm, typeorm), default is typeorm') | ||
.option('-o, --orm <orm>', 'Specify ORM module to use, defaults to typeorm') | ||
.action((modelName, cmdObj) => { | ||
@@ -129,0 +262,0 @@ create_module(modelName, 'model', cleanArgs(cmdObj)); |
@@ -5,3 +5,3 @@ /* | ||
* @LastEditors: Please set LastEditors | ||
* @LastEditTime: 2022-11-04 14:48:30 | ||
* @LastEditTime: 2025-03-11 16:12:50 | ||
* @License: BSD (3-Clause) | ||
@@ -13,3 +13,2 @@ * @Copyright (c) - <richenlin(at)gmail.com> | ||
const path = require('path'); | ||
const log = require('../utils/log'); | ||
const lib = require('koatty_lib'); | ||
@@ -16,0 +15,0 @@ |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -27,3 +27,3 @@ /* | ||
} | ||
return this.toCamelCase(str).replace(/\w/i, $0 => $0.toUpperCase()); | ||
return this.toCamelCase(str).replace(/\w/i, ($0) => $0.toUpperCase()); | ||
}; | ||
@@ -40,3 +40,3 @@ | ||
} | ||
return str.replace(/[A-Z]/g, $0 => `-${$0.toLowerCase()}`); | ||
return str.replace(/[A-Z]/g, ($0) => `-${$0.toLowerCase()}`); | ||
}; |
@@ -96,3 +96,3 @@ /* | ||
log.info(`Update template [${templateName}] success!`); | ||
}).catch(err => { | ||
}).catch(() => { | ||
flag = true; | ||
@@ -99,0 +99,0 @@ // log.error(`Update template [${templateName}] fail: ${err.stack}`); |
@@ -6,3 +6,3 @@ /* | ||
* @Date: 2024-01-04 05:26:15 | ||
* @LastEditTime: 2024-01-07 12:24:25 | ||
* @LastEditTime: 2025-03-11 15:46:20 | ||
* @License: BSD (3-Clause) | ||
@@ -17,3 +17,3 @@ * @Copyright (c): <richenlin(at)gmail.com> | ||
// 从3.11.x版本开始,用分支管理 | ||
if (lib.toNumber(currentVer) >= 3.11) { | ||
if (lib.toNumber(currentVer) >= 3.11 && !url.includes("component")) { | ||
return url.replace("#main", "#" + currentVer + ".x") | ||
@@ -20,0 +20,0 @@ } |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
64693
26.93%28
47.37%1625
49.91%13
18.18%15
275%1
Infinity%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
Updated