@aicblock/nserve 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,11 +4,15 @@
4
4
  ![npm](https://img.shields.io/npm/dm/@aicblock/nserve)
5
5
  ![NPM](https://img.shields.io/npm/l/@aicblock/nserve)
6
6
 
7
- #### Description
7
+ # NServe 用户使用文档
8
8
 
9
- 🛠️ Description NodeJS Server-side development CLI
9
+ ## 1. 项目简介
10
10
 
11
- #### 快速搭建第一个 Nserve 项目
11
+ NServe 是一个 Node.js 服务器端开发 CLI 工具,旨在简化 Node.js 服务器应用的开发、构建和部署流程。它提供了代码生成、热重载开发服务器和项目构建等功能,帮助开发者快速搭建和维护 Node.js 服务器应用。
12
+
13
+ ## 2. 快速开始
14
+
15
+ 您可以使用以下命令创建一个新的 NServe 项目:
12
16
 
13
17
  #### 使用 NPM:
14
18
 
@@ -25,5 +29,302 @@ $ yarn create nserve@latest
25
29
  #### 使用 PNPM:
26
30
 
27
31
  ```sh
28
- $ pnpm create nserve@latest
32
+ $ pnpm create nserve@latest
33
+ ```
34
+
35
+ ## 3. 核心功能
36
+
37
+ ### 3.1 命令行接口
38
+
39
+ NServe 提供了三个主要命令:
40
+
41
+ - `nserve serve` - 启动开发服务器
42
+ - `nserve build` - 构建项目
43
+ - `nserve gen` - 根据配置文件生成代码
44
+
45
+ ### 3.2 代码生成
46
+
47
+ - **路由生成**:根据配置文件自动生成 Express 路由
48
+ - **模型生成**:从 SQL CREATE TABLE 语句生成数据模型
49
+
50
+ ### 3.3 开发服务器
51
+
52
+ - 支持 TypeScript 实时编译
53
+ - 热重载功能
54
+ - 支持环境变量配置
55
+
56
+ ### 3.4 项目构建
57
+
58
+ - 使用 esbuild 进行快速构建
59
+ - 支持生产环境优化
60
+ - 生成可执行的 JavaScript 代码
61
+
62
+ ## 4. 配置文件
63
+
64
+ ### 4.1 基本配置
65
+
66
+ 在项目根目录创建 `nserve.config.ts` 文件:
67
+
68
+ ```typescript
69
+ import { DefineNserveConfig } from '@aicblock/nserve'
70
+
71
+ export default DefineNserveConfig({
72
+ entry: 'app.ts', // 应用入口文件
73
+ outputDir: 'dist', // 构建输出目录
74
+ sourceDir: 'src', // 源代码目录
75
+ testing: false, // 是否为测试模式
76
+ yamlConfig: {}, // YAML 配置文件内容
77
+ plugins: [], // 自定义插件
78
+ external: [], // 外部依赖
79
+ generateConfig: {
80
+ genDir: 'nserve-config', // 生成配置目录
81
+ routerDir: 'router', // 路由配置目录
82
+ modelDir: 'model', // 模型配置目录
83
+ codePrettier: {
84
+ semi: false, // 是否使用分号
85
+ singleQuote: true, // 是否使用单引号
86
+ trailingComma: 'none' // 尾随逗号配置
87
+ },
88
+ middleware: {} // 中间件配置
89
+ }
90
+ })
91
+ ```
92
+
93
+ ### 4.2 路由配置
94
+
95
+ 在 `nserve-config/router` 目录下创建路由配置文件,例如 `user.ts`:
96
+
97
+ ```typescript
98
+ import { DefineGenRouter } from '@aicblock/nserve'
99
+
100
+ export default DefineGenRouter({
101
+ servicePath: '/api/user', // 路由前缀
102
+ serviceHandler: 'user', // 处理逻辑目录
103
+ routers: [
104
+ {
105
+ path: '/list', // 路由路径
106
+ method: 'GET', // HTTP 方法
107
+ name: 'list', // 处理函数名
108
+ middleware: [] // 路由级中间件
109
+ },
110
+ {
111
+ path: '/create',
112
+ method: 'POST',
113
+ name: 'create',
114
+ session: {
115
+ /* session 配置 */
116
+ }
117
+ }
118
+ ],
119
+ middleware: ['auth'] // 全局中间件
120
+ })
121
+ ```
122
+
123
+ ### 4.3 模型配置
124
+
125
+ 在 `nserve-config/model` 目录下创建 SQL 文件,例如 `user.sql`:
126
+
127
+ ```sql
128
+ CREATE TABLE `user` (
129
+ `id` INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID',
130
+ `username` VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',
131
+ `password` VARCHAR(255) NOT NULL COMMENT '密码',
132
+ `email` VARCHAR(100) NOT NULL UNIQUE COMMENT '邮箱',
133
+ `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
134
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
135
+ ```
136
+
137
+ ## 5. 命令使用
138
+
139
+ ### 5.1 启动开发服务器
140
+
141
+ ```bash
142
+ nserve serve
143
+ ```
144
+
145
+ 选项:
146
+
147
+ - `--mode <mode>` - 指定运行模式(development/production)
148
+ - `--config <path>` - 指定配置文件路径
149
+
150
+ ### 5.2 构建项目
151
+
152
+ ```bash
153
+ nserve build
154
+ ```
155
+
156
+ 选项:
157
+
158
+ - `--mode <mode>` - 指定构建模式(development/production)
159
+ - `--config <path>` - 指定配置文件路径
160
+
161
+ ### 5.3 生成代码
162
+
163
+ ```bash
164
+ nserve gen
165
+ ```
166
+
167
+ 选项:
168
+
169
+ - `--config <path>` - 指定配置文件路径
170
+
171
+ ## 6. 项目结构
172
+
173
+ ```
174
+ project/
175
+ ├── src/ # 源代码目录
176
+ │ ├── handler/ # 路由处理器
177
+ │ ├── logic/ # 业务逻辑
178
+ │ ├── model/ # 数据模型
179
+ │ └── app.ts # 应用入口
180
+ ├── nserve-config/ # 生成配置目录
181
+ │ ├── router/ # 路由配置
182
+ │ └── model/ # 模型 SQL 文件
183
+ ├── nserve.config.ts # NServe 配置文件
184
+ └── package.json # 项目配置
185
+ └── tsconfig.json # TypeScript 配置文件
29
186
  ```
187
+
188
+ ## 7. 路由生成流程
189
+
190
+ 1. 创建路由配置文件 `nserve-config/router/*.ts`
191
+ 2. 运行 `nserve gen` 命令
192
+ 3. NServe 会自动生成:
193
+ - 路由处理器文件 `src/handler/*.handler.ts`
194
+ - 业务逻辑模板文件 `src/logic/*/*.logic.ts`
195
+ - 路由注册文件 `src/handler/router.ts`
196
+
197
+ ## 8. 模型生成流程
198
+
199
+ 1. 创建 SQL 文件 `nserve-config/model/*.sql`
200
+ 2. 运行 `nserve gen` 命令
201
+ 3. NServe 会自动生成:
202
+ - 数据模型文件 `src/model/*.ts`
203
+ - 模型索引文件 `src/model/index.ts`
204
+
205
+ ## 9. 环境变量
206
+
207
+ NServe 支持 `.env` 文件和环境特定的配置文件(如 `.env.development`、`.env.production`)。
208
+
209
+ 示例 `.env` 文件:
210
+
211
+ ```
212
+ # yamlConfig 配置
213
+ YAML_CONFIG.APP_CONFIG.PORT=3000
214
+ YAML_CONFIG.MYSQL_CONF.host=localhost
215
+ YAML_CONFIG.MYSQL_CONF.port=3306
216
+ YAML_CONFIG.MYSQL_CONF.user=root
217
+ YAML_CONFIG.MYSQL_CONF.password=password
218
+ YAML_CONFIG.MYSQL_CONF.database=test
219
+
220
+ # NServe 配置
221
+ AICBLOCK_NSERVE_APP_ENTRY=app.ts
222
+ ```
223
+
224
+ ## 10. 中间件配置
225
+
226
+ 在 `nserve.config.ts` 中配置全局中间件:
227
+
228
+ ```typescript
229
+ export default DefineNserveConfig({
230
+ generateConfig: {
231
+ middleware: {
232
+ auth: {
233
+ libName: '@/middleware/auth',
234
+ funcName: 'authMiddleware'
235
+ }
236
+ }
237
+ }
238
+ })
239
+ ```
240
+
241
+ 在路由配置中使用中间件:
242
+
243
+ ```typescript
244
+ export default DefineGenRouter({
245
+ routers: [
246
+ {
247
+ path: '/protected',
248
+ method: 'GET',
249
+ name: 'protected',
250
+ middleware: ['auth']
251
+ }
252
+ ]
253
+ })
254
+ ```
255
+
256
+ ## 11. 高级功能
257
+
258
+ ### 11.1 自定义插件
259
+
260
+ NServe 支持自定义 esbuild 插件:
261
+
262
+ ```typescript
263
+ export default DefineNserveConfig({
264
+ plugins: [
265
+ {
266
+ name: 'custom-plugin',
267
+ setup(build) {
268
+ // 插件逻辑
269
+ }
270
+ }
271
+ ]
272
+ })
273
+ ```
274
+
275
+ ### 11.2 类型定义
276
+
277
+ NServe 提供了完整的 TypeScript 类型定义,可以在项目中直接使用:
278
+
279
+ ```typescript
280
+ import type { Config, DefineGenRouterConfig } from '@aicblock/nserve'
281
+ ```
282
+
283
+ ## 12. 最佳实践
284
+
285
+ ### 12.1 项目组织
286
+
287
+ - 将路由和业务逻辑分离
288
+ - 使用模型层抽象数据库操作
289
+ - 为不同功能模块创建独立的路由配置文件
290
+
291
+ ### 12.2 开发流程
292
+
293
+ 1. 创建项目结构
294
+ 2. 配置 `nserve.config.ts`
295
+ 3. 编写路由配置文件
296
+ 4. 编写 SQL 模型文件
297
+ 5. 运行 `nserve gen` 生成代码框架
298
+ 6. 实现业务逻辑
299
+ 7. 使用 `nserve serve` 启动开发服务器进行测试
300
+ 8. 使用 `nserve build` 构建生产版本
301
+
302
+ ## 13. 常见问题
303
+
304
+ ### 13.1 端口被占用
305
+
306
+ 如果开发服务器端口被占用,可以在 `.env` 文件中修改 PORT 配置:
307
+
308
+ ```
309
+ PORT=3001
310
+ ```
311
+
312
+ ### 13.2 热重载不生效
313
+
314
+ 确保:
315
+
316
+ - 源代码目录配置正确
317
+ - 入口文件存在且配置正确
318
+ - 没有语法错误
319
+
320
+ ### 13.3 构建失败
321
+
322
+ 检查:
323
+
324
+ - TypeScript 语法错误
325
+ - 依赖是否安装正确
326
+ - 配置文件是否正确
327
+
328
+ ## 15. 贡献
329
+
330
+ 欢迎提交 Issue 和 Pull Request 来改进 NServe。
package/lib/commander.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var f=Object.create;var l=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var y=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty;var b=(e,n,t,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of m(n))!h.call(e,r)&&r!==t&&l(e,r,{get:()=>n[r],enumerable:!(s=g(n,r))||s.enumerable});return e};var O=(e,n,t)=>(t=e!=null?f(y(e)):{},b(n||!e||!e.__esModule?l(t,"default",{value:e,enumerable:!0}):t,e));var S=require("esbuild");var R=O(require("js-yaml"));function i(e,n="INFO"){let t=(d,u="green")=>`\x1B[${{green:"32m",red:"31m",blue:"34m",orange:"30m"}[u]}${d}\x1B[0m`,r={INFO:"blue",WARNING:"orange",ERROR:"red",SUCCESS:"green"}[n],p=t(n,r);console.log(`[${p}] - ${e}`)}var a=require("./runtime"),o=require("commander"),c=process.argv;c[2]===void 0&&c.push("serve");o.program.version("1.0.0");o.program.on("command:*",function(){let e=o.program.args[0];if(["serve","build","gen"].includes(e)){(0,a.execRun)(e);return}i("See --help for a list of available commands."),i(`Invalid command: ${e}`,"ERROR"),process.exit(0)});o.program.on("--help",function(){console.log("Commands:"),console.log(" serve Start Run the dev server"),console.log(" build Build the project"),console.log(" gen Generate code based on the configuration file")});o.program.parse(c);
2
+ "use strict";var d=Object.create;var l=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var y=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty;var b=(e,n,t,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of m(n))!h.call(e,r)&&r!==t&&l(e,r,{get:()=>n[r],enumerable:!(s=g(n,r))||s.enumerable});return e};var O=(e,n,t)=>(t=e!=null?d(y(e)):{},b(n||!e||!e.__esModule?l(t,"default",{value:e,enumerable:!0}):t,e));var R=require("esbuild");var S=O(require("js-yaml"));function i(e,n="INFO"){let t=(p,f="green")=>`\x1B[${{green:"32m",red:"31m",blue:"34m",orange:"30m"}[f]}${p}\x1B[0m`,r={INFO:"blue",WARNING:"orange",ERROR:"red",SUCCESS:"green"}[n],u=t(n,r);console.log(`[${u}] - ${e}`)}var a=require("./runtime"),o=require("commander"),c=process.argv;c[2]===void 0&&c.push("serve");o.program.version("1.0.2");o.program.on("command:*",function(){let e=o.program.args[0];if(["serve","build","gen"].includes(e)){(0,a.execRun)(e);return}i("See --help for a list of available commands."),i(`Invalid command: ${e}`,"ERROR"),process.exit(0)});o.program.on("--help",function(){console.log("Commands:"),console.log(" serve Start Run the dev server"),console.log(" build Build the project"),console.log(" gen Generate code based on the configuration file")});o.program.parse(c);
package/lib/core/run.js CHANGED
@@ -1 +1 @@
1
- "use strict";var K=Object.create;var O=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var W=Object.getPrototypeOf,B=Object.prototype.hasOwnProperty;var U=(e,t)=>{for(var r in t)O(e,r,{get:t[r],enumerable:!0})},I=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of k(t))!B.call(e,n)&&n!==r&&O(e,n,{get:()=>t[n],enumerable:!(o=V(t,n))||o.enumerable});return e};var v=(e,t,r)=>(r=e!=null?K(W(e)):{},I(t||!e||!e.__esModule?O(r,"default",{value:e,enumerable:!0}):r,e)),G=e=>I(O({},"__esModule",{value:!0}),e);var Q={};U(Q,{getRunVMData:()=>L});module.exports=G(Q);var S=require("esbuild");var q=require("esbuild"),i=require("fs"),E=require("path");var P=v(require("js-yaml"));function R(e,t="INFO"){let r=(c,s="green")=>`\x1B[${{green:"32m",red:"31m",blue:"34m",orange:"30m"}[s]}${c}\x1B[0m`,n={INFO:"blue",WARNING:"orange",ERROR:"red",SUCCESS:"green"}[t],l=r(t,n);console.log(`[${l}] - ${e}`)}function T(e){let t=(r,o)=>{try{let n=(0,i.readdirSync)(r);if(n.length===0){(0,i.rmdirSync)(r),o&&o();return}let l=n.length,c=0,s=f=>{f===l&&((0,i.rmdirSync)(r),o&&o())};n.forEach(f=>{let a=(0,E.join)(r,f);if((0,i.statSync)(a).isDirectory()){t(a,()=>{s(c+=1)});return}(0,i.unlinkSync)(a),s(c+=1)})}catch(n){o&&o(n)}};return new Promise((r,o)=>{if(!e||!(0,i.existsSync)(e)){r();return}if(!(0,i.statSync)(e).isDirectory()){o("The directory path to be deleted is not a directory path");return}t(e,n=>{n?o(n):r()})})}async function N(e,t,r={}){let{createDir:o=!0,indent:n=2,noRefs:l=!0,lineWidth:c=80,skipInvalid:s=!1,quotingType:f='"',forceQuotes:a=!1,encoding:g="utf8",...h}=r;try{let d;if(typeof e=="string")try{d=JSON.parse(e)}catch(y){throw new Error(`\u65E0\u6548\u7684 JSON \u5B57\u7B26\u4E32: ${y instanceof Error?y.message:String(y)}`)}else if(typeof e=="object"&&e!==null)d=e;else throw new Error("jsonData \u5FC5\u987B\u662F\u6709\u6548\u7684 JSON \u5B57\u7B26\u4E32\u3001\u5BF9\u8C61\u6216\u6570\u7EC4");let u=P.default.dump(d,{indent:n,noRefs:l,skipInvalid:s,lineWidth:c,quotingType:f,forceQuotes:a,...h,styles:{"!!null":"canonical",...h.styles}});if(o){let y=(0,E.dirname)(t);try{(0,i.accessSync)(y)}catch{(0,i.mkdirSync)(y,{recursive:!0}),console.log(`\u5DF2\u521B\u5EFA\u76EE\u5F55: ${y}`)}}(0,i.writeFileSync)(t,u,{encoding:g});let b=Buffer.byteLength(u,g);return console.log(`YAML \u6587\u4EF6\u5DF2\u6210\u529F\u751F\u6210: ${t}`),console.log(`\u6587\u4EF6\u5927\u5C0F: ${b} \u5B57\u8282`),{content:u,filePath:t,fileSize:b}}catch(d){throw console.error("\u8F6C\u6362\u6216\u4FDD\u5B58\u5931\u8D25:",d instanceof Error?d.message:String(d)),d}}var p=require("path"),j=v(require("os")),m=require("fs"),C=require("child_process"),w=v(require("vm"));function L(e){try{let t=process.env.AICBLOCK_NSERVE_RUN_CWD,r=(0,m.readFileSync)(e,"utf-8"),o=(0,S.transformSync)(r,{format:"cjs",loader:"ts"}),n={module:{paths:[(0,p.join)(t,"node_modules")],exports:{default:void 0}},require,__dirname:t,global,__filename:e,process},l=new w.default.Script(o.code);return w.default.createContext(n),l.runInContext(n),n.module.exports.default||n.module.exports}catch(t){console.error(t),process.exit(0)}}function A(e,t){let r=Date.now(),o=()=>`${Date.now()-r}ms`;try{(0,S.build)(e).then(({errors:n})=>{if(n.length===0){t&&t(),R(`Compile successfully.[${o()}]`,"SUCCESS");return}R(JSON.stringify(n),"ERROR")})}catch(n){R(JSON.stringify(n),"ERROR")}}var M=e=>{let t=e.compilerOptions?.paths||{},r=Object.keys(t);return{name:"alias",setup(o){o.onLoad({filter:/\.ts$/},async n=>{let l=await m.promises.readFile(n.path,"utf8"),c="ts";if(r.length===0)return{contents:l,loader:c};let s=l;return r.forEach(a=>{let g=a.replace(/\*$/,""),h=new RegExp(`from[\\s]{1,}[\\'\\"]${g}((?!\\n[\\'\\"]).)*[\\'\\"]`,"g"),d=(t[a]&&t[a][0]).replace(/\*$/,"");s.replace(h,u=>`from '${u.replace("from","").replace(/['"]/g,"")}'`)}),{contents:s,loader:c}})}}};function Y(e){return new Promise(t=>{let r;j.default.type().startsWith("Windows")?r=`tasklist /FI "PID eq ${e}" /NH`:r=`kill -0 ${e} 2>/dev/null`,(0,C.exec)(r,(o,n,l)=>{o?t(!1):j.default.type().startsWith("Windows")?t(n.includes(e.toString())):t(l==="")})})}var z=(e,t,r,o)=>{let n=()=>{let c=process.platform==="win32"?"node.cmd":"node";return(0,C.spawnSync)(c,[e],{stdio:"inherit",cwd:r}).pid};(0,m.watch)(t,{recursive:!0},(()=>{let c,s=n();return()=>{c&&clearTimeout(c),c=setTimeout(()=>{Y(s).then(f=>{try{f&&process.kill(s),o&&o().then(()=>s=n())}catch(a){R("Fial","ERROR"),console.log(a)}})},500)}})())},H=()=>{try{let e=process.env.AICBLOCK_NSERVE_RUN_CWD,t=process.env.AICBLOCK_NSERVE_RUN_CONFIG_PATH,r=process.env.AICBLOCK_NSERVE_RUN_MODE,o=L(t),{entry:n,testing:l,outputDir:c,sourceDir:s,plugins:f,external:a,yamlConfig:g}=o;if(!s||!(0,m.existsSync)((0,p.join)(e,s)))throw Error("[ERROR] The compilation directory is not configured or does not exist");let h=(0,p.join)(e,s,n);if((!n||typeof n!="string"||!(0,m.existsSync)(h))&&r==="serve")throw Error(`[ERROR] The run file does not exist. Please check the config:[${h}]`);let d=!l,u=(0,p.join)(e,c||"dist");r==="build"&&(0,m.existsSync)(u)&&T(u);let b=(0,p.join)(e,"tsconfig.json"),y=(0,m.readFileSync)(b,"utf-8"),$=JSON.parse(y),_={entryPoints:[h],minify:d,outdir:u,plugins:[M($),...f||[]],bundle:!0,platform:"node",format:"cjs",external:a},F=()=>new Promise(x=>{A(_,()=>{g&&N(g,(0,p.join)(u,"config.yaml")),x(void 0)})});A(_,()=>{if(r==="build"||!n)return;g&&N(g,(0,p.join)(u,"config.yaml"));let x=(0,p.basename)(n),D=x.substring(0,x.length-3)+".js",J=(0,p.join)(u,D);z(J,(0,p.join)(e,s||"src"),u,F)})}catch(e){console.error("[ERROR_STACK]",e);let t=e?.message||"[FN::esbuild::exec]";R(t,"ERROR"),process.exit(0)}};H();0&&(module.exports={getRunVMData});
1
+ "use strict";var J=Object.create;var _=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var G=Object.getPrototypeOf,W=Object.prototype.hasOwnProperty;var B=(t,n,r,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of k(n))!W.call(t,e)&&e!==r&&_(t,e,{get:()=>n[e],enumerable:!(o=K(n,e))||o.enumerable});return t};var S=(t,n,r)=>(r=t!=null?J(G(t)):{},B(n||!t||!t.__esModule?_(r,"default",{value:t,enumerable:!0}):r,t));var T=require("esbuild");var I=require("esbuild"),s=require("fs"),b=require("path"),C=S(require("vm")),L=S(require("js-yaml"));function R(t,n="INFO"){let r=(c,i="green")=>`\x1B[${{green:"32m",red:"31m",blue:"34m",orange:"30m"}[i]}${c}\x1B[0m`,e={INFO:"blue",WARNING:"orange",ERROR:"red",SUCCESS:"green"}[n],l=r(n,e);console.log(`[${l}] - ${t}`)}function P(t){let n=(r,o)=>{try{let e=(0,s.readdirSync)(r);if(e.length===0){(0,s.rmdirSync)(r),o&&o();return}let l=e.length,c=0,i=f=>{f===l&&((0,s.rmdirSync)(r),o&&o())};e.forEach(f=>{let a=(0,b.join)(r,f);if((0,s.statSync)(a).isDirectory()){n(a,()=>{i(c+=1)});return}(0,s.unlinkSync)(a),i(c+=1)})}catch(e){o&&o(e)}};return new Promise((r,o)=>{if(!t||!(0,s.existsSync)(t)){r();return}if(!(0,s.statSync)(t).isDirectory()){o("The directory path to be deleted is not a directory path");return}n(t,e=>{e?o(e):r()})})}function w(t,n){try{let r=(0,s.readFileSync)(t,"utf-8"),o=(0,I.transformSync)(r,{format:"cjs",loader:"ts",platform:"node",target:"node18"}),e={module:{paths:[(0,b.join)(n,"node_modules")],exports:{default:void 0}},require,__dirname:n,global,__filename,process},l=new C.default.Script(o.code);return C.default.createContext(e),l.runInContext(e),e.module.exports.default||e.module.exports}catch(r){console.error(r),process.exit(0)}}async function v(t,n,r={}){let{createDir:o=!0,indent:e=2,noRefs:l=!0,lineWidth:c=80,skipInvalid:i=!1,quotingType:f='"',forceQuotes:a=!1,encoding:g="utf8",...h}=r;try{let p;if(typeof t=="string")try{p=JSON.parse(t)}catch(y){throw new Error(`\u65E0\u6548\u7684 JSON \u5B57\u7B26\u4E32: ${y instanceof Error?y.message:String(y)}`)}else if(typeof t=="object"&&t!==null)p=t;else throw new Error("jsonData \u5FC5\u987B\u662F\u6709\u6548\u7684 JSON \u5B57\u7B26\u4E32\u3001\u5BF9\u8C61\u6216\u6570\u7EC4");let u=L.default.dump(p,{indent:e,noRefs:l,skipInvalid:i,lineWidth:c,quotingType:f,forceQuotes:a,...h,styles:{"!!null":"canonical",...h.styles}});if(o){let y=(0,b.dirname)(n);try{(0,s.accessSync)(y)}catch{(0,s.mkdirSync)(y,{recursive:!0}),console.log(`\u5DF2\u521B\u5EFA\u76EE\u5F55: ${y}`)}}(0,s.writeFileSync)(n,u,{encoding:g});let O=Buffer.byteLength(u,g);return console.log(`YAML \u6587\u4EF6\u5DF2\u6210\u529F\u751F\u6210: ${n}`),console.log(`\u6587\u4EF6\u5927\u5C0F: ${O} \u5B57\u8282`),{content:u,filePath:n,fileSize:O}}catch(p){throw console.error("\u8F6C\u6362\u6216\u4FDD\u5B58\u5931\u8D25:",p instanceof Error?p.message:String(p)),p}}var d=require("path"),N=S(require("os")),m=require("fs"),x=require("child_process");function A(t,n){let r=Date.now(),o=()=>`${Date.now()-r}ms`;try{(0,T.build)(t).then(({errors:e})=>{if(e.length===0){n&&n(),R(`Compile successfully.[${o()}]`,"SUCCESS");return}R(JSON.stringify(e),"ERROR")})}catch(e){R(JSON.stringify(e),"ERROR")}}var U=t=>{let n=t.compilerOptions?.paths||{},r=Object.keys(n);return{name:"alias",setup(o){o.onLoad({filter:/\.ts$/},async e=>{let l=await m.promises.readFile(e.path,"utf8"),c="ts";if(r.length===0)return{contents:l,loader:c};let i=l;return r.forEach(a=>{let g=a.replace(/\*$/,""),h=new RegExp(`from[\\s]{1,}[\\'\\"]${g}((?!\\n[\\'\\"]).)*[\\'\\"]`,"g"),p=(n[a]&&n[a][0]).replace(/\*$/,"");i.replace(h,u=>`from '${u.replace("from","").replace(/['"]/g,"")}'`)}),{contents:i,loader:c}})}}};function Y(t){return new Promise(n=>{let r;N.default.type().startsWith("Windows")?r=`tasklist /FI "PID eq ${t}" /NH`:r=`kill -0 ${t} 2>/dev/null`,(0,x.exec)(r,(o,e,l)=>{o?n(!1):N.default.type().startsWith("Windows")?n(e.includes(t.toString())):n(l==="")})})}var M=(t,n,r,o)=>{let e=()=>{let c=process.platform==="win32"?"node.cmd":"node";return(0,x.spawnSync)(c,[t],{stdio:"inherit",cwd:r}).pid};(0,m.watch)(n,{recursive:!0},(()=>{let c,i=e();return()=>{c&&clearTimeout(c),c=setTimeout(()=>{Y(i).then(f=>{try{f&&process.kill(i),o&&o().then(()=>i=e())}catch(a){R("Fial","ERROR"),console.log(a)}})},500)}})())},q=()=>{try{let t=process.env.AICBLOCK_NSERVE_RUN_CWD,n=process.env.AICBLOCK_NSERVE_RUN_CONFIG_PATH,r=process.env.AICBLOCK_NSERVE_RUN_MODE,o=w(n,process.env.AICBLOCK_NSERVE_RUN_CWD),{entry:e,testing:l,outputDir:c,sourceDir:i,plugins:f,external:a,yamlConfig:g}=o;if(!i||!(0,m.existsSync)((0,d.join)(t,i)))throw Error("[ERROR] The compilation directory is not configured or does not exist");let h=(0,d.join)(t,i,e);if((!e||typeof e!="string"||!(0,m.existsSync)(h))&&r==="serve")throw Error(`[ERROR] The run file does not exist. Please check the config:[${h}]`);let p=!l,u=(0,d.join)(t,c||"dist");r==="build"&&(0,m.existsSync)(u)&&P(u);let O=(0,d.join)(t,"tsconfig.json"),y=(0,m.readFileSync)(O,"utf-8"),F=JSON.parse(y),j={entryPoints:[h],minify:p,outdir:u,plugins:[U(F),...f||[]],bundle:!0,platform:"node",format:"cjs",external:a},$=()=>new Promise(E=>{A(j,()=>{g&&v(g,(0,d.join)(u,"config.yaml")),E(void 0)})});A(j,()=>{if(g&&v(g,(0,d.join)(u,"config.yaml")),r==="build"||!e)return;let E=(0,d.basename)(e),D=E.substring(0,E.length-3)+".js",V=(0,d.join)(u,D);M(V,(0,d.join)(t,i||"src"),u,$)})}catch(t){console.error("[ERROR_STACK]",t);let n=t?.message||"[FN::esbuild::exec]";R(n,"ERROR"),process.exit(0)}};q();
package/lib/index.d.ts CHANGED
@@ -4,25 +4,30 @@ export declare const nbuild: {
4
4
  build: typeof build;
5
5
  };
6
6
  export declare function DefineNserveConfig(options?: Config): Config | undefined;
7
- export declare const DefineGenRouter: (param: DefineGenRouterConfig) => {
8
- prefix: string;
9
- service: (RouterOption & {
10
- handler: string;
11
- })[];
12
- handler: string;
13
- };
7
+ export declare const DefineGenRouter: (param: DefineGenRouterConfig) => GenRouterConfig;
14
8
  declare const _default: {
15
9
  DefineNserveConfig: typeof DefineNserveConfig;
16
- DefineGenRouter: (param: DefineGenRouterConfig) => {
17
- prefix: string;
18
- service: (RouterOption & {
19
- handler: string;
20
- })[];
21
- handler: string;
22
- };
10
+ DefineGenRouter: (param: DefineGenRouterConfig) => GenRouterConfig;
23
11
  };
24
12
  export default _default;
25
13
 
14
+ interface CodePrettierConfigOption {
15
+ /**
16
+ * 是否添加分号
17
+ * Whether to add semicolons
18
+ */
19
+ semi?: boolean
20
+ /**
21
+ * 是否使用单引号
22
+ * Whether to use single quotes
23
+ */
24
+ singleQuote?: boolean
25
+ /**
26
+ * 是否使用尾逗号
27
+ * Whether to use trailing commas
28
+ */
29
+ trailingComma?: 'none' | 'es5' | 'all'
30
+ }
26
31
  interface MiddlewareConfigOption {
27
32
  /**
28
33
  * 中间件库名
@@ -33,7 +38,7 @@ interface MiddlewareConfigOption {
33
38
  * 中间件函数名
34
39
  * Middleware function name
35
40
  */
36
- funcName: string
41
+ funcName?: string
37
42
  /**
38
43
  * 是否为 AMD 模块
39
44
  * Whether it is an AMD module
@@ -66,7 +71,12 @@ interface GenerateConfigOption {
66
71
  * 中间件配置
67
72
  * Middleware configuration
68
73
  */
69
- middleware?: MiddlewareConfigOption[]
74
+ middleware?: Record<string, MiddlewareConfigOption>
75
+ /**
76
+ * 代码格式化配置
77
+ * Code prettier configuration
78
+ */
79
+ codePrettier?: CodePrettierConfigOption
70
80
  }
71
81
  interface Config {
72
82
  /**
@@ -134,22 +144,42 @@ type RouterMethod =
134
144
  | 'CONNECT'
135
145
  | 'TRACE'
136
146
 
147
+ // 数据类型属性定义
148
+ type PropertyType = 'string' | 'number' | 'boolean' | 'object' | 'array'
149
+
137
150
  interface DataTypeProperty {
138
151
  // 数据类型
139
- type: 'string' | 'number' | 'boolean' | 'object' | 'array'
152
+ type?: PropertyType | { type: 'custom'; name: string }
140
153
  // 数据类型名称
141
- name: string
154
+ name?: string
142
155
  // 数据类型描述
143
156
  description?: string
144
157
  // 对象属性定义
145
- properties?: DataTypeProperty[]
146
- // 数组项类型定义
147
- item?: DataTypeProperty[]
158
+ properties?: Record<string, DataTypeProperty>
159
+ // 是否必填
160
+ required?: boolean
148
161
  }
149
- // 数据类型定义
150
- interface DataType {
162
+
163
+ // 泛型参数定义
164
+ interface GenericityParam {
165
+ name: string
166
+ typeParams: string[]
167
+ }
168
+
169
+ // 数据类型选项定义
170
+ interface DataTypeOption {
171
+ // 数据类型名称
151
172
  name: string
152
- properties: DataTypeProperty[]
173
+ // 数据类型
174
+ type?: PropertyType | string
175
+ // 数据类型描述
176
+ description?: string
177
+ // 数据类型属性定义
178
+ properties?: Record<string, DataTypeProperty>
179
+ // 数据类型继承
180
+ extends?: string | string[]
181
+ // 数据类型泛型定义
182
+ genericity?: string | GenericityParam
153
183
  }
154
184
 
155
185
  // 路由选项定义
@@ -163,16 +193,72 @@ interface RouterOption {
163
193
  // 路由文档备注
164
194
  docRemark?: string
165
195
  // 路由请求数据类型定义
166
- requestDataType?: IAnyObject
196
+ requestDataType?: DataTypeOption
167
197
  // 路由响应数据类型定义
168
- responseDataType?: IAnyObject
198
+ responseDataType?: DataTypeOption
199
+ // 路由中间件
200
+ middleware?: RouterMiddleware
201
+ }
202
+
203
+ /**
204
+ * 路由中间件选项定义
205
+ */
206
+ interface RouterMiddlewareOption {
207
+ name: string
208
+ value?: Array<string | boolean | number> | (string | boolean | number)
169
209
  }
170
210
 
211
+ /**
212
+ * 路由中间件类型定义
213
+ */
214
+ type RouterMiddleware =
215
+ | string
216
+ | string[]
217
+ | RouterMiddlewareOption
218
+ | RouterMiddlewareOption[]
219
+
171
220
  // 路由配置定义
172
221
  interface DefineGenRouterConfig {
222
+ /**
223
+ * 服务路径
224
+ */
173
225
  servicePath: string
226
+ /**
227
+ * 服务处理函数
228
+ */
174
229
  serviceHandler: string
230
+ /**
231
+ * 路由定义
232
+ */
175
233
  routers: RouterOption[]
234
+ /**
235
+ * 路由全局中间件
236
+ */
237
+ middleware?: RouterMiddleware
238
+ }
239
+ type GenRouterConfigService = RouterOption & {
240
+ /**
241
+ * 路由处理函数
242
+ */
243
+ handler: string
244
+ }
245
+ interface GenRouterConfig {
246
+ /**
247
+ * 路由前缀
248
+ */
249
+ prefix: string
250
+ /**
251
+ * 路由处理函数
252
+ */
253
+ handler: string
254
+ /**
255
+ * 路由服务定义
256
+ */
257
+ service: GenRouterConfigService[]
258
+ /**
259
+ * 路由全局中间件
260
+ */
261
+ middleware?: RouterMiddleware
176
262
  }
177
263
 
178
264
  type EXEC_COMMAND = 'serve' | 'build' | 'gen'
package/lib/index.js CHANGED
@@ -1 +1,3 @@
1
- "use strict";var N=Object.create;var m=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var L=Object.getPrototypeOf,I=Object.prototype.hasOwnProperty;var _=(e,t)=>{for(var r in t)m(e,r,{get:t[r],enumerable:!0})},b=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of A(t))!I.call(e,n)&&n!==r&&m(e,n,{get:()=>t[n],enumerable:!(s=j(t,n))||s.enumerable});return e};var T=(e,t,r)=>(r=e!=null?N(L(e)):{},b(t||!e||!e.__esModule?m(r,"default",{value:e,enumerable:!0}):r,e)),D=e=>b(m({},"__esModule",{value:!0}),e);var J={};_(J,{DefineGenRouter:()=>C,DefineNserveConfig:()=>v,default:()=>G,nbuild:()=>F});module.exports=D(J);var h=require("esbuild");var w=require("esbuild"),l=require("fs"),y=require("path");var P=T(require("js-yaml"));function E(e,t="INFO"){let r=(o,p="green")=>`\x1B[${{green:"32m",red:"31m",blue:"34m",orange:"30m"}[p]}${o}\x1B[0m`,n={INFO:"blue",WARNING:"orange",ERROR:"red",SUCCESS:"green"}[t],i=r(t,n);console.log(`[${i}] - ${e}`)}function R(e,t){let r=(n,i)=>{if(Object.prototype.toString.call(n)!=="[object Object]"||Object.prototype.toString.call(i)!=="[object Object]")return console.warn("[STACK_LOG] AICBLOCK_UTIL: \u53C2\u6570\u9519\u8BEF"),{};let o={},p=Object.keys(n);return Object.keys(i).filter(c=>!p.includes(c)).forEach(c=>Object.assign(o,{[c]:i[c]})),Object.keys(n).forEach(c=>{let f=i[c],d=n[c];if(f!==void 0&&Object.prototype.toString.call(f)==="[object Object]"&&Object.prototype.toString.call(d)==="[object Object]"){Object.assign(o,{[c]:r(d,f)});return}Object.assign(o,{[c]:f!==void 0?f:d})}),o};return(Array.isArray(t)?t:[t]).reduce((n,i)=>r(n,i),e)}function B(e,t){let r=e.findIndex(n=>n===t);if(r<0||e.length-1===r)return;let s=e[r+1];if(s.indexOf("--")!==0)return s}function K(e){return e===void 0||e===""||e===null}function V(e){let t={};return e.split(/(\r\n)|[\r\n]/).filter(s=>!K(s)).forEach(s=>{let n=s.split("="),i=(n[0]||"").trim(),o=(n[1]||"").trim();i.split("")[0]!=="#"&&i!==""&&(t[i]=o)}),t}function S(e,t){let r={},s={},n=(0,y.join)(e,".env"),i=process.env.AICBLOCK_NSERVE_RUN_ARGV||"[]",o=B(JSON.parse(i),"--mode"),u=(0,y.join)(e,`.env.${o!==void 0&&o||(t==="build"?"production":"development")}`),c={},f=[n,u],d=a=>{if(!(0,l.existsSync)(a))return;let g=(0,l.readFileSync)(a,"utf-8"),O=V(g);Object.assign(c,O)};return f.forEach(d),Object.keys(c).forEach(a=>{let g=c[a];if(a.indexOf("AICBLOCK_NSERVE_APP_")===0){r[a]=g;return}let O=t==="serve"?a.replace(/^(APPTEST_)/,""):a;s[O]=g}),{system:r,app:s}}var $=e=>{let{servicePath:t,serviceHandler:r,routers:s}=e,n=s.map(i=>{let{name:o}=i;return Object.assign(i,{handler:o})});return{prefix:t,service:n,handler:r}},x=$;var F={transformSync:h.transformSync,build:h.build};function v(e){try{let t=process.env.AICBLOCK_NSERVE_RUN_CWD,r=process.env.AICBLOCK_NSERVE_RUN_MODE,s={},n=S(t,r);n.system.AICBLOCK_NSERVE_APP_ENTRY&&Object.assign(s,{entry:n.system.AICBLOCK_NSERVE_APP_ENTRY});let i=p=>{let u=n.app&&n.app[p];process.env[p]=u};Object.keys(n.app||{}).forEach(i);let o=R({outputDir:"dist",entry:"app.ts",sourceDir:"src"},{...e,envs:n,...s});return o.lifecycleBefore&&typeof o.lifecycleBefore=="function"&&(o=R(o||{},o.lifecycleBefore(o)||{})),o}catch(t){E("defineNserveConfig fial::","ERROR"),console.error(t)}}var C=x,G={DefineNserveConfig:v,DefineGenRouter:C};0&&(module.exports={DefineGenRouter,DefineNserveConfig,nbuild});
1
+ "use strict";var T=Object.create;var h=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var D=Object.getPrototypeOf,G=Object.prototype.hasOwnProperty;var F=(e,t)=>{for(var r in t)h(e,r,{get:t[r],enumerable:!0})},x=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of w(t))!G.call(e,n)&&n!==r&&h(e,n,{get:()=>t[n],enumerable:!(s=P(t,n))||s.enumerable});return e};var V=(e,t,r)=>(r=e!=null?T(D(e)):{},x(t||!e||!e.__esModule?h(r,"default",{value:e,enumerable:!0}):r,e)),B=e=>x(h({},"__esModule",{value:!0}),e);var Q={};F(Q,{DefineGenRouter:()=>L,DefineNserveConfig:()=>j,default:()=>z,nbuild:()=>q});module.exports=B(Q);var b=require("esbuild");var K=require("esbuild"),f=require("fs"),m=require("path");var $=V(require("js-yaml"));function v(e,t="INFO"){let r=(c,u="green")=>`\x1B[${{green:"32m",red:"31m",blue:"34m",orange:"30m"}[u]}${c}\x1B[0m`,n={INFO:"blue",WARNING:"orange",ERROR:"red",SUCCESS:"green"}[t],o=r(t,n);console.log(`[${o}] - ${e}`)}function O(e,t){let r=(n,o)=>{if(Object.prototype.toString.call(n)!=="[object Object]"||Object.prototype.toString.call(o)!=="[object Object]")return console.warn("[STACK_LOG] AICBLOCK_UTIL: \u53C2\u6570\u9519\u8BEF"),{};let c={},u=Object.keys(n);return Object.keys(o).filter(l=>!u.includes(l)).forEach(l=>Object.assign(c,{[l]:o[l]})),Object.keys(n).forEach(l=>{let i=o[l],p=n[l];if(i!==void 0&&Object.prototype.toString.call(i)==="[object Object]"&&Object.prototype.toString.call(p)==="[object Object]"){Object.assign(c,{[l]:r(p,i)});return}Object.assign(c,{[l]:i!==void 0?i:p})}),c};return(Array.isArray(t)?t:[t]).reduce((n,o)=>r(n,o),e)}function Y(e,t){let r=e.findIndex(n=>n===t);if(r<0||e.length-1===r)return;let s=e[r+1];if(s.indexOf("--")!==0)return s}function J(e){return e===void 0||e===""||e===null}function M(e){let t={};return e.split(/(\r\n)|[\r\n]/).filter(s=>!J(s)).forEach(s=>{let n=s.split("="),o=(n[0]||"").trim(),c=(n[1]||"").trim();o.split("")[0]!=="#"&&o!==""&&(t[o]=c)}),t}function k(e){let t=Number(e);if(!isNaN(t)&&e.trim()!=="")return t;let r=e.toLowerCase();if(r==="true")return!0;if(r==="false")return!1;if(r==="null")return null;if(r!=="undefined")return e}function U(e,t="."){let r=e.trim().split(`
2
+ `),s={};return r.filter(n=>n.indexOf("YAML_CONFIG"+t)===0).forEach(n=>{if(!n.trim())return;let[o,c]=n.split("=");if(!o||c===void 0)return;let u=o.trim(),a=c.trim(),l=u.split(t),i=s;for(let p=0;p<l.length;p++){let d=l[p];p===l.length-1?i[d]=k(a):((!i[d]||typeof i[d]!="object")&&(i[d]={}),i=i[d])}}),s}function S(e,t){let r={},s={},n={},o=(0,m.join)(e,".env"),c=process.env.AICBLOCK_NSERVE_RUN_ARGV||"[]",u=Y(JSON.parse(c),"--mode"),a=u!==void 0&&u||(t==="build"?"production":"development"),l=(0,m.join)(e,`.env.${a}`),i={},p=[o,l],d=(0,m.join)(e,".env.local");(0,f.existsSync)(d)&&p.push(d);let C=(0,m.join)(e,`.env.${a}.local`);(0,f.existsSync)(C)&&p.push(C);let R=[],_=g=>{if(!(0,f.existsSync)(g))return;let y=(0,f.readFileSync)(g,"utf-8"),E=M(y);R.push(y),Object.assign(i,E)};p.forEach(_);let A=["YAML_CONFIG."];return Object.keys(i).forEach(g=>{if(A.some(I=>g.indexOf(I)===0))return;let y=i[g];if(g.indexOf("AICBLOCK_NSERVE_APP_")===0){r[g]=y;return}let E=t==="serve"?g.replace(/^(APPTEST_)/,""):g;s[E]=y}),R.join("").indexOf("YAML_CONFIG.")>=0&&Object.assign(n,U(R.join(`
3
+ `))),{system:r,app:s,yamlConfig:n}}var W=e=>{let{servicePath:t,serviceHandler:r,routers:s,middleware:n}=e,o=s.map(c=>{let{name:u}=c;return Object.assign(c,{handler:u})});return{prefix:t,service:o,handler:r,middleware:n}},N=W;var q={transformSync:b.transformSync,build:b.build};function j(e){try{let t=process.env.AICBLOCK_NSERVE_RUN_CWD,r=process.env.AICBLOCK_NSERVE_RUN_MODE,s={},n=S(t,r),{app:o,system:c}=n;n.system.AICBLOCK_NSERVE_APP_ENTRY&&Object.assign(s,{entry:n.system.AICBLOCK_NSERVE_APP_ENTRY}),Object.keys(n.yamlConfig||{}).length>0&&Object.assign(s,{yamlConfig:n.yamlConfig.YAML_CONFIG});let u=l=>{let i=o&&o[l];i&&(process.env[l]=i)};Object.keys(o||{}).forEach(u);let a=O({outputDir:"dist",entry:"app.ts",sourceDir:"src"},{...e,envs:{system:c}});return Object.keys(n.yamlConfig||{}).length>0&&(a=O(a||{},{yamlConfig:n.yamlConfig.YAML_CONFIG})),a.lifecycleBefore&&typeof a.lifecycleBefore=="function"&&(a=O(a||{},a.lifecycleBefore(a)||{})),a}catch(t){v("defineNserveConfig fial::","ERROR"),console.error(t)}}var L=N,z={DefineNserveConfig:j,DefineGenRouter:L};0&&(module.exports={DefineGenRouter,DefineNserveConfig,nbuild});
package/lib/runtime.js CHANGED
@@ -1,14 +1,31 @@
1
- "use strict";var ae=Object.create;var _=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var pe=Object.getPrototypeOf,fe=Object.prototype.hasOwnProperty;var me=(e,t)=>{for(var n in t)_(e,n,{get:t[n],enumerable:!0})},K=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ue(t))!fe.call(e,o)&&o!==n&&_(e,o,{get:()=>t[o],enumerable:!(r=le(t,o))||r.enumerable});return e};var q=(e,t,n)=>(n=e!=null?ae(pe(e)):{},K(t||!e||!e.__esModule?_(n,"default",{value:e,enumerable:!0}):n,e)),de=e=>K(_({},"__esModule",{value:!0}),e);var _e={};me(_e,{default:()=>Ie,execRun:()=>te});module.exports=de(_e);var I=require("path");var W=require("esbuild"),R=require("fs"),U=require("path"),D=q(require("vm")),ge=q(require("js-yaml"));function O(e,t="INFO"){let n=(i,s="green")=>`\x1B[${{green:"32m",red:"31m",blue:"34m",orange:"30m"}[s]}${i}\x1B[0m`,o={INFO:"blue",WARNING:"orange",ERROR:"red",SUCCESS:"green"}[t],a=n(t,o);console.log(`[${a}] - ${e}`)}function v(e,t){let n=e.findIndex(o=>o===t);if(n<0||e.length-1===n)return;let r=e[n+1];if(r.indexOf("--")!==0)return r}function L(e,t){try{let n=(0,R.readFileSync)(e,"utf-8"),r=(0,W.transformSync)(n,{format:"cjs",loader:"ts",platform:"node",target:"node18"}),o={module:{paths:[(0,U.join)(t,"node_modules")],exports:{default:void 0}},require,__dirname:t,global,__filename,process},a=new D.default.Script(r.code);return D.default.createContext(o),a.runInContext(o),o.module.exports.default||o.module.exports}catch(n){console.error(n),process.exit(0)}}var j=require("fs"),ee=require("child_process");var f=require("fs"),T=require("path");function k(e){return!e||typeof e!="string"?e:e.replace(/([A-Z])/g," $1").trim().split(/\s+/).join("-").toLowerCase()}function M(e){return!e||typeof e!="string"?e:e.charAt(0).toUpperCase()+e.slice(1)}var J=require("console"),he=(e,t,n,r="@")=>{let o=(0,T.join)(t,n,"handler"),a=(0,T.join)(t,n,"logic");!(0,f.existsSync)(o)&&(0,f.mkdirSync)(o,{recursive:!0}),!(0,f.existsSync)(a)&&(0,f.mkdirSync)(a,{recursive:!0});let i={genDir:"nserve-config",routerDir:"router",modelDir:"model"},{genDir:s,routerDir:p}=Object.assign({},i,e),g=(0,T.join)(t,s),u=(0,T.join)(g,p||"");if(!(0,f.existsSync)(u)){console.log("[ERROR] API\u63CF\u8FF0\u6587\u4EF6\u4E0D\u5B58\u5728::",u);return}if(!(0,f.statSync)(u).isDirectory()){console.log("[ERROR] API\u63CF\u8FF0\u6587\u4EF6\u4E0D\u662F\u76EE\u5F55");return}let m=(0,f.readdirSync)(u).filter(N=>N.endsWith(".ts")||N.endsWith(".js"));if(m.length===0){console.log("[ERROR] API\u63CF\u8FF0\u6587\u4EF6\u76EE\u5F55\u4E0B\u6CA1\u6709\u63CF\u8FF0\u751F\u6210\u6587\u4EF6");return}let c=[],d=[];m.forEach(N=>{let S=L((0,T.join)(u,N),__dirname);if(!S)return;let $=N.replace(".ts",".handler"),B=M(N.replace(".ts","Server")),ne=(0,T.join)(o,[$,".ts"].join("")),oe=[r,"handler",$].join("/");c.push(`import ${B} from '${oe}'`),d.push(B);let x=[],G=[],A=(0,T.join)(a,S.handler);!(0,f.existsSync)(A)&&(0,f.mkdirSync)(A,{recursive:!0});let P=["import { Request, Response } from 'express'","import { ErrorResponse, SuccessResponse } from '@aicblock/nserve/lib/tools'"];S.service?.forEach(E=>{let se=E.method?.toLowerCase()||"get",Y=k(E.handler),V=M(E.handler),w=[];E.session&&(x.push("import session from 'express-session'"),w.push(`session(${JSON.stringify(E.session)})`));let ie=[r,"logic",S.handler,Y].join("/");x.push(`import ${V} from '${ie}.logic'`),G.push(`Router.${se}('${E.path}',${w.join(",")}${w.length>0?",":""}${V})`),(0,J.log)("[INFO] gen router::",E,!!E.docRemark),E.docRemark&&P.concat(`// ${E.docRemark}`);let ce=P.concat(`
1
+ "use strict";var Ne=Object.create;var Y=Object.defineProperty;var xe=Object.getOwnPropertyDescriptor;var Ae=Object.getOwnPropertyNames;var Le=Object.getPrototypeOf,je=Object.prototype.hasOwnProperty;var we=(e,r)=>{for(var o in r)Y(e,o,{get:r[o],enumerable:!0})},fe=(e,r,o,c)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of Ae(r))!je.call(e,i)&&i!==o&&Y(e,i,{get:()=>r[i],enumerable:!(c=xe(r,i))||c.enumerable});return e};var de=(e,r,o)=>(o=e!=null?Ne(Le(e)):{},fe(r||!e||!e.__esModule?Y(o,"default",{value:e,enumerable:!0}):o,e)),De=e=>fe(Y({},"__esModule",{value:!0}),e);var Je={};we(Je,{default:()=>We,execRun:()=>_e});module.exports=De(Je);var q=require("path");var me=require("esbuild"),$=require("fs"),ee=require("path"),Z=de(require("vm")),Ue=de(require("js-yaml"));function S(e,r="INFO"){let o=(l,u="green")=>`\x1B[${{green:"32m",red:"31m",blue:"34m",orange:"30m"}[u]}${l}\x1B[0m`,i={INFO:"blue",WARNING:"orange",ERROR:"red",SUCCESS:"green"}[r],d=o(r,i);console.log(`[${d}] - ${e}`)}function te(e,r){let o=e.findIndex(i=>i===r);if(o<0||e.length-1===o)return;let c=e[o+1];if(c.indexOf("--")!==0)return c}function F(e,r){try{let o=(0,$.readFileSync)(e,"utf-8"),c=(0,me.transformSync)(o,{format:"cjs",loader:"ts",platform:"node",target:"node18"}),i={module:{paths:[(0,ee.join)(r,"node_modules")],exports:{default:void 0}},require,__dirname:r,global,__filename,process},d=new Z.default.Script(c.code);return Z.default.createContext(i),d.runInContext(i),i.module.exports.default||i.module.exports}catch(o){console.error(o),process.exit(0)}}var re=require("fs"),Te=require("child_process");var g=require("fs"),b=require("path");function ge(e){return!e||typeof e!="string"?e:e.replace(/([A-Z])/g," $1").trim().split(/\s+/).join("-").toLowerCase()}function P(e){return!e||typeof e!="string"?e:e.split(/[\-\_]/g).map(o=>o.charAt(0).toUpperCase()+o.slice(1)).join("")}var ve=e=>{let r=[],o=new Map,c=new Map;function i(n){if(!c.has(n))return c.set(n,1),n;let t=c.get(n)+1;return c.set(n,t),`${n}${t}`}function d(n,t,a){let s=[];if(t.type==="array"){if(t.properties&&Object.keys(t.properties).length>0){let p=t.name||i(`${a||"Anonymous"}_${n}_Item`),y=l(p,t.properties,t.description);return y&&(o.set(p,y),s.push(p)),{type:`${p}[]`,generatedInterfaces:s}}return{type:"any[]",generatedInterfaces:s}}if(t.type==="object"&&t.properties){let p=t.name||i(`${a||"Anonymous"}_${n}`),y=l(p,t.properties,t.description);return y&&(o.set(p,y),s.push(p)),{type:p,generatedInterfaces:s}}return typeof t.type=="object"?{type:t.type.name,generatedInterfaces:s}:{type:t.type||"string",generatedInterfaces:s}}function l(n,t,a){let s=[];return a&&s.push(`// ${a}`),Object.entries(t).forEach(([p,y])=>{let h=d(p,y,n),O=y.description?` // ${y.description}`:"",A=` ${p}${y.required===!1?"?":""}: ${h.type};`;s.push(O?`${O}
2
+ ${A}`:A)}),s.length===0?`interface ${n} {}`:`interface ${n} {
3
+ ${s.join(`
4
+ `)}
5
+ }`}function u(n){if(n.type!==void 0){let s=[];return n.description&&s.push(`// ${n.description}`),s.push(`type ${n.name} = ${n.type};`),s.join(`
6
+ `)}Object.entries(n.properties||{}).forEach(([s,p])=>{d(s,p,n.name)});let t="";if(n.genericity)if(typeof n.genericity=="string"){let s=m(n);s?t=` extends ${n.genericity}<${s}>`:t=` extends ${n.genericity}`}else{let{name:s,typeParams:p}=n.genericity;t=` extends ${s}<${p.join(", ")}>`}else n.extends&&(Array.isArray(n.extends)?t=` extends ${n.extends.join(", ")}`:t=` extends ${n.extends}`);if(n.genericity)return`interface ${n.name}${t} {}`;let a=[];return Object.entries(n.properties||{}).forEach(([s,p])=>{let y=d(s,p,n.name),h=p.description?` // ${p.description}`:"",O=` ${s}${p.required===!1?"?":""}: ${y.type};`;a.push(h?`${h}
7
+ ${O}`:O)}),`interface ${n.name}${t} {
8
+ ${a.join(`
9
+ `)}
10
+ }`}function m(n){let t=n.properties?.list;if(t&&t.type==="array"&&t.name)return t.name;for(let[a,s]of Object.entries(n.properties||{}))if(s.type==="array"&&s.name)return s.name;return null}let E=u(e);return o.forEach(n=>{r.push(n)}),r.push(E),r.join(`
11
+
12
+ `)},ne=ve;var Me=(e,r,o,c="@")=>{let i=(0,b.join)(r,o,"handler"),d=(0,b.join)(r,o,"logic"),l=(0,b.join)(r,o,"types");!(0,g.existsSync)(i)&&(0,g.mkdirSync)(i,{recursive:!0}),!(0,g.existsSync)(d)&&(0,g.mkdirSync)(d,{recursive:!0}),!(0,g.existsSync)(l)&&(0,g.mkdirSync)(l,{recursive:!0});let m=Object.assign({},{genDir:"nserve-config",routerDir:"router",modelDir:"model"},e),{genDir:E,routerDir:n,middleware:t}=m,a=(0,b.join)(r,E),s=(0,b.join)(a,n||"");if(!(0,g.existsSync)(s)){console.log("[ERROR] API\u63CF\u8FF0\u6587\u4EF6\u4E0D\u5B58\u5728::",s);return}if(!(0,g.statSync)(s).isDirectory()){console.log("[ERROR] API\u63CF\u8FF0\u6587\u4EF6\u4E0D\u662F\u76EE\u5F55");return}let y=(0,g.readdirSync)(s).filter(N=>N.endsWith(".ts")||N.endsWith(".js"));if(y.length===0){console.log("[ERROR] API\u63CF\u8FF0\u6587\u4EF6\u76EE\u5F55\u4E0B\u6CA1\u6709\u63CF\u8FF0\u751F\u6210\u6587\u4EF6");return}let h=[],O=[];y.forEach(N=>{let oe=F((0,b.join)(s,N),__dirname);if(!oe)return;let x=oe,se=N.replace(".ts",".handler"),ie=P(N.replace(".ts",""))+"Server",be=(0,b.join)(i,[se,".ts"].join("")),Ie=[c,"handler",se].join("/");h.push(`import ${ie} from '${Ie}'`),O.push(ie);let k=[],ce=[],K=(0,b.join)(d,x.handler),W=(0,b.join)(l,x.handler);!(0,g.existsSync)(K)&&(0,g.mkdirSync)(K,{recursive:!0}),!(0,g.existsSync)(W)&&(0,g.mkdirSync)(W,{recursive:!0});let ae=["ErrorResponse","SuccessResponse"],J=["import type { Request, Response } from 'express'"],G={},M={};t&&Object.keys(t).forEach(f=>{let{libName:T,funcName:_}=t[f],j=_?`{${_} as ${f}}`:f;G[f]=`import ${j} from '${T}'`}),x.service?.forEach(f=>{let T=ge(f.handler),_=[];if(f.responseDataType&&_.push(ne(f.responseDataType)),f.requestDataType&&_.push(ne(f.requestDataType)),_.length>0){let L=(0,b.join)(W,`${T}.types.d.ts`);(0,g.writeFileSync)(L,_.join(`
13
+ `),"utf-8")}let j=f.method?.toLowerCase()||"get",H=P(f.handler),w=[];if(f.middleware&&m.middleware){let L=Array.isArray(f.middleware)?f.middleware:[f.middleware];if(!L.every(R=>{let I=typeof R=="string"?R:R.name;return!!G[I]}))throw new Error(`[ERROR] \u8DEF\u7531\u914D\u7F6E\u4E2D\u4F7F\u7528\u4E86\u4E0D\u5B58\u5728\u7684\u4E2D\u95F4\u4EF6::${L}`);let B=[];L.forEach(R=>{let I=typeof R=="string"?R:R.name;M[I]=G[I];let pe=(typeof R=="string"?void 0:Array.isArray(R.value)?R.value:[R.value])?.map(z=>typeof z=="string"?`'${z}'`:z),Se=pe?`${I}(${pe.join(",")})`:I;B.push(Se)}),w.push(...B)}let X=[c,"logic",x.handler,T].join("/");k.push(`import ${H} from '${X}.logic'`),ce.push(`Router.${j}('${f.path}',${w.join(",")}${w.length>0?",":""}${H})`),f.docRemark&&J.concat(`// ${f.docRemark}`);let D=[];if(f.requestDataType&&f.requestDataType.properties){let L=f.requestDataType,U=L.properties,B=Object.keys(U).reduce((R,I)=>{let ue=typeof U[I].type=="string"?U[I].type:"object";return R[I]={required:U[I].required===void 0||U[I].required===!0,type:ue},R},{});D.push(`const data = ${f.method==="GET"?"req.query":"req.body"} as ${L.name}`,`CheckFieldRequired(data, ${JSON.stringify(B)})`),ae.push("CheckFieldRequired")}J.push(`import { ${ae.join(",")} } from '@aicblock/nserve/lib/tools'`);let $e=J.concat(`
14
+ ${f.docRemark?`// ${f.docRemark}`:""}
2
15
  export async function ServiceLogic(req: Request, res: Response) {
3
16
  try {
4
- SuccessResponse(res)
17
+ // todo: \u63A5\u53E3\u670D\u52A1\u903B\u8F91\u5B9E\u73B0
18
+ ${D.join(`
19
+ `)}
20
+ SuccessResponse(res, true)
5
21
  } catch (error) {
6
22
  ErrorResponse(res, error)
7
23
  }
8
24
  }
9
25
  export default ServiceLogic
10
- `),F=(0,T.join)(A,`${Y}.logic.ts`);!(0,f.existsSync)(F)&&(0,f.writeFileSync)(F,ce.join(`
11
- `))});let re=["// Code generated by plugin. Templates Edited by aicblock cli. DO NOT EDIT.","import express from 'express'",...x,"const app = express()","const Router = express.Router()",`app.use('${S.prefix}', Router)`,...G,"export default app"];(0,f.writeFileSync)(ne,re.join(`
12
- `))});let y=(0,T.join)(o,"router.ts"),C=["// Code generated by plugin. Templates Edited by aicblock cli. DO NOT EDIT.",...c,"export default [",d.join(","),"]"];(0,f.writeFileSync)(y,C.join(`
13
- `)),console.log("[INFO] gen router file ",y)},Q=he;var h=require("fs"),b=require("path"),Ee=new Set(["INT","BIGINT","BIT","DECIMAL","DOUBLE","FLOAT","INTEGER","MEDIUMINT","NUMERIC","REAL","SMALLINT","TINYINT"]);function Re(e){let r=e.replace(/\/\*[\s\S]*?\*\//g,"").trim().replace(/--.*$/gm,"").replace(/\s+/g," "),o=r.match(/CREATE TABLE [`"]?([\w_]+)[`"]?\s*\(/i);if(!o)throw new Error("\u65E0\u6CD5\u89E3\u6790\u8868\u540D");let i={tableName:o[1],columns:[]},s=r.indexOf("("),p=r.lastIndexOf(")");if(s===-1||p===-1||p<=s)throw new Error("\u65E0\u6CD5\u627E\u5230\u5217\u5B9A\u4E49\u90E8\u5206");let g=r.substring(s+1,p);if(!g.trim())return i;let u=Te(g),l=new Set,m=new Set;return u.forEach(c=>{let d=c.trim();if(d.toUpperCase().startsWith("PRIMARY KEY")){let C=d.match(/PRIMARY KEY\s*\([`"]?([\w_]+)[`"]?\)/i);C&&l.add(C[1]);return}if(d.toUpperCase().startsWith("UNIQUE")){let C=d.match(/\([`"]?([\w_]+)[`"]?(?:\s+ASC|DESC)?\)/i);C&&m.add(C[1]);return}let y=Oe(d);y&&i.columns.push(y)}),i.columns.forEach(c=>{l.has(c.name)&&(c.primaryKey=!0),m.has(c.name)&&(c.unique=!0)}),i}function Te(e){let t=[],n="",r=!1,o=!1,a=0;for(let i=0;i<e.length;i++){let s=e[i],p=i+1<e.length?e[i+1]:"";s==="'"&&!o&&(r=!r),s==="-"&&p==="-"&&!r&&(o=!0),o&&(s===","||s===")")&&(o=!1),s==="("&&!r&&!o&&a++,s===")"&&!r&&!o&&a--,s===","&&!r&&!o&&a===0?(n.trim()&&t.push(n.trim()),n=""):n+=s}return n.trim()&&t.push(n.trim()),t}function Oe(e){if(e.toUpperCase().startsWith("PRIMARY KEY")||e.toUpperCase().startsWith("UNIQUE")||e.toUpperCase().startsWith("KEY"))return null;let t=/^[`"]?([\w_]+)[`"]?\s+([a-zA-Z]+)(?:\s*\(\s*(\d+)\s*\))?(?:\s+(?:CHARACTER\s+SET|CHARSET)\s+\w+)?(?:\s+COLLATE\s+\w+)?(?:\s+(NOT\s+NULL|NULL))?(?:\s+UNIQUE)?(?:\s+AUTO_INCREMENT)?(?:\s+DEFAULT\s+([\w'"-]+))?(?:\s+COMMENT\s+'([^']*)')?/i,n=e.match(t);if(!n)return null;let[,r,o,a,i,s,p]=n,g=o.toUpperCase(),u={name:r,dataType:g};if(a&&(u.length=parseInt(a,10)),i&&i.toUpperCase()==="NOT NULL"&&(u.notNull=!0),e.toUpperCase().includes("UNIQUE")&&(u.unique=!0),e.toUpperCase().includes("AUTO_INCREMENT")&&(u.autoIncrement=!0),s!==void 0&&s!==""&&s!=="NULL"){let l=s.trim();if((l.startsWith("'")&&l.endsWith("'")&&l.length>1||l.startsWith('"')&&l.endsWith('"')&&l.length>1)&&(l=l.substring(1,l.length-1)),Ee.has(g)){let m=Number(l);!isNaN(m)&&l!==""?u.defaultValue=m:l!==""&&(u.defaultValue=l)}else l!==""&&(u.defaultValue=l)}return p&&(u.comments=p),u}var ye=(e,t,n)=>{let r={genDir:"nserve-config",modelDir:"model"},{genDir:o,modelDir:a}=Object.assign({},r,e),i=(0,b.join)(t,o,a);if(!(0,h.existsSync)(i))throw new Error(`The SQL model directory does not exist::${i}`);let s=(0,h.readdirSync)(i).filter(p=>p.endsWith(".sql"));if(s.length===0)throw new Error(`The SQL model directory does not contain any SQL files::${i}`);s.forEach(p=>{let g=(0,b.join)(i,p),u=(0,h.readFileSync)(g,"utf-8");try{let l=Re(u),m=l.tableName,c=(0,b.join)(t,n,a);(0,h.existsSync)(c)||(0,h.mkdirSync)(c);let d=(0,b.join)(c,`${m}.ts`),y=["import { TableOption } from '@dpapejs/emysql'",`export default ${JSON.stringify(l,null,2)} as TableOption`];(0,h.writeFileSync)(d,y.join(`
14
- `),"utf-8"),O(`The model file ${m} has been generated::${d}`)}catch{throw new Error(`The SQL file ${p} is not a valid CREATE TABLE statement::${g}`)}})},H=ye;var X=require("child_process"),z=require("path"),Ce=(e,t,n)=>{try{let r=t||process.cwd();Q(e||{},r,n||"src"),H(e||{},r,n||"src");let o="npx prettier --no-semi --single-quote --write 'logic/**/*.ts' 'handler/**/*.ts' 'model/**/*.ts'",a=(0,z.join)(r,n||"src");console.log("[INFO] execRunGen::",a),(0,X.spawnSync)(o,{cwd:a,stdio:"inherit",shell:!0}),O("[INFO] execRunGen","SUCCESS")}catch(r){O("execRunGen fial::","ERROR"),console.error(r)}},Z=Ce;function Ne(e,t){O(`${t?`The [${t}] app has been `:""}Build DONE. [Build time:${Date.now()-e} ms]`,"SUCCESS")}function Se(e){O(e==="build"?"Build Fail.":"Serve process has exited.","ERROR")}function be(){let e=process.cwd(),t=v(process.argv,"--config"),n=(0,I.join)(e,"nserve.config.ts"),r=(0,I.join)(e,"nserve.config.js"),o=t?(0,I.join)(e,t):(0,j.existsSync)(n)?n:r;if(!(0,j.existsSync)(o))throw Error(`The configuration file does not exist. [${o}]`);return o}function te(e){try{let n=be(),r=process.cwd(),o=e,a=v(process.argv,"--mode"),i=JSON.stringify(process.argv),s={AICBLOCK_NSERVE_RUN_CWD:r,AICBLOCK_NSERVE_RUN_CONFIG_PATH:n,AICBLOCK_NSERVE_RUN_MODE:o,AICBLOCK_NSERVE_ENV_MODE:a,AICBLOCK_NSERVE_RUN_ARGV:i};Object.keys(s).forEach(c=>{let d=s[c];d!==void 0&&(process.env[c]=d)});let p=L(n,process.cwd());if(e==="gen"){Z(p.generateConfig||{},r,p.sourceDir||"src");return}let g=Date.now();var t=void 0;let u=process.platform==="win32"?"node.cmd":"node",m=(0,ee.spawn)(u,["./lib/core/run.js","--cmd"],{cwd:(0,I.join)(__dirname,"../"),stdio:e==="build"?"inherit":"pipe",env:Object.assign({},process.env,s)});m.stdout?.on("data",c=>{t&&t.stop(),console.log(c.toString("utf-8"))}),m.stdout?.on("error",c=>{t&&t.stop(),console.log(c.toString())}),m.stderr?.on("data",c=>{t&&t.stop(),console.log(c.toString("utf-8"))}),m.on("exit",c=>{t&&t.stop(),c===0&&e==="build"&&Ne(g,a),c!==0&&Se(e)})}catch(n){O("execRun fial::","ERROR"),console.error(n)}}var Ie=te;0&&(module.exports={execRun});
26
+ `),le=(0,b.join)(K,`${T}.logic.ts`);!(0,g.existsSync)(le)&&(0,g.writeFileSync)(le,$e.join(`
27
+ `),"utf-8")});let Q=[];x.middleware&&(Array.isArray(x.middleware)?x.middleware:[x.middleware]).forEach(T=>{let _=typeof T=="string"?T:T.name,j=G[_];if(!j||M[_])return;M[_]=j;let w=(typeof T=="string"?void 0:Array.isArray(T.value)?T.value:[T.value])?.map(D=>typeof D=="string"?`'${D}'`:D),X=w?`${_}(${w.join(",")})`:_;Q.push(X)}),Object.keys(M).forEach(f=>{k.push(M[f])});let Ce=["// Code generated by plugin. Templates Edited by aicblock cli. DO NOT EDIT.","import express from 'express'",...k,"const app = express()","const Router = express.Router()",Q.length>0?`Router.use(${Q.join(",")})`:"",`app.use('${x.prefix}', Router)`,...ce,"export default app"];(0,g.writeFileSync)(be,Ce.join(`
28
+ `))});let A=(0,b.join)(i,"router.ts"),V=["// Code generated by plugin. Templates Edited by aicblock cli. DO NOT EDIT.",...h,"export default [",O.join(","),"]"];(0,g.writeFileSync)(A,V.join(`
29
+ `)),console.log("[INFO] gen router file ",A)},ye=Me;var C=require("fs"),v=require("path");var Pe=new Set(["INT","BIGINT","BIT","DECIMAL","DOUBLE","FLOAT","INTEGER","MEDIUMINT","NUMERIC","REAL","SMALLINT","TINYINT"]);function qe(e){let c=e.replace(/\/\*[\s\S]*?\*\//g,"").trim().replace(/--.*$/gm,"").replace(/\s+/g," "),i=c.match(/CREATE TABLE [`"]?([\w_]+)[`"]?\s*\(/i);if(!i)throw new Error("\u65E0\u6CD5\u89E3\u6790\u8868\u540D");let l={tableName:i[1],columns:[]},u=c.indexOf("("),m=c.lastIndexOf(")");if(u===-1||m===-1||m<=u)throw new Error("\u65E0\u6CD5\u627E\u5230\u5217\u5B9A\u4E49\u90E8\u5206");let E=c.substring(u+1,m);if(!E.trim())return l;let n=Ge(E),t=new Set,a=new Set;return n.forEach(s=>{let p=s.trim();if(p.toUpperCase().startsWith("PRIMARY KEY")){let h=p.match(/PRIMARY KEY\s*\([`"]?([\w_]+)[`"]?\)/i);h&&t.add(h[1]);return}if(p.toUpperCase().startsWith("UNIQUE")){let h=p.match(/\([`"]?([\w_]+)[`"]?(?:\s+ASC|DESC)?\)/i);h&&a.add(h[1]);return}let y=Be(p);y&&l.columns.push(y)}),l.columns.forEach(s=>{t.has(s.name)&&(s.primaryKey=!0),a.has(s.name)&&(s.unique=!0)}),l}function Ge(e){let r=[],o="",c=!1,i=!1,d=0;for(let l=0;l<e.length;l++){let u=e[l],m=l+1<e.length?e[l+1]:"";u==="'"&&!i&&(c=!c),u==="-"&&m==="-"&&!c&&(i=!0),i&&(u===","||u===")")&&(i=!1),u==="("&&!c&&!i&&d++,u===")"&&!c&&!i&&d--,u===","&&!c&&!i&&d===0?(o.trim()&&r.push(o.trim()),o=""):o+=u}return o.trim()&&r.push(o.trim()),r}function Be(e){if(e.toUpperCase().startsWith("PRIMARY KEY")||e.toUpperCase().startsWith("UNIQUE")||e.toUpperCase().startsWith("KEY"))return null;let r=/^[`"]?([\w_]+)[`"]?\s+([a-zA-Z]+)(?:\s*\(\s*(\d+)\s*\))?(?:\s+(?:CHARACTER\s+SET|CHARSET)\s+\w+)?(?:\s+COLLATE\s+\w+)?(?:\s+(NOT\s+NULL|NULL))?(?:\s+UNIQUE)?(?:\s+AUTO_INCREMENT)?(?:\s+DEFAULT\s+([\w'"-]+))?(?:\s+COMMENT\s+'([^']*)')?/i,o=e.match(r);if(!o)return null;let[,c,i,d,l,u,m]=o,E=i.toUpperCase(),n={name:c,dataType:E};if(d&&(n.length=parseInt(d,10)),l&&l.toUpperCase()==="NOT NULL"&&(n.notNull=!0),e.toUpperCase().includes("UNIQUE")&&(n.unique=!0),e.toUpperCase().includes("AUTO_INCREMENT")&&(n.autoIncrement=!0),u!==void 0&&u!==""&&u!=="NULL"){let t=u.trim();if((t.startsWith("'")&&t.endsWith("'")&&t.length>1||t.startsWith('"')&&t.endsWith('"')&&t.length>1)&&(t=t.substring(1,t.length-1)),Pe.has(E)){let a=Number(t);!isNaN(a)&&t!==""?n.defaultValue=a:t!==""&&(n.defaultValue=t)}else t!==""&&(n.defaultValue=t)}return m&&(n.comments=m),n}var Ye=(e,r,o)=>{let c={genDir:"nserve-config",modelDir:"model"},{genDir:i,modelDir:d}=Object.assign({},c,e),l=(0,v.join)(r,i,d);if(!(0,C.existsSync)(l))return;let u=(0,C.readdirSync)(l).filter(s=>s.endsWith(".sql"));if(u.length===0)throw new Error(`The SQL model directory does not contain any SQL files::${l}`);let m=(0,v.join)(r,o,d);(0,C.existsSync)(m)||(0,C.mkdirSync)(m);let E=[],n=[];u.forEach(s=>{let p=(0,v.join)(l,s),y=(0,C.readFileSync)(p,"utf-8");try{let h=qe(y),O=h.tableName,A=(0,v.join)(m,`${O}.ts`),V=["import type { TableOption } from '@dpapejs/emysql'",`const table:TableOption = ${JSON.stringify(h,null,2)}`,"export default table"];(0,C.writeFileSync)(A,V.join(`
30
+ `),"utf-8");let N=P(O);n.push(N),E.push(`import ${N} from './${O}'`),S(`The model file ${O} has been generated::${A}`)}catch{throw new Error(`The SQL file ${s} is not a valid CREATE TABLE statement::${p}`)}});let t=(0,v.join)(m,"index.ts"),a=[...E,`export default [${n.join(", ")}]`];(0,C.writeFileSync)(t,a.join(`
31
+ `),"utf-8"),S(`The model index file has been generated::${t}`)},he=Ye;var Ee=require("child_process"),Re=require("path"),Fe=(e,r,o)=>{try{let c=r||process.cwd();ye(e||{},c,o||"src"),he(e||{},c,o||"src");let i={semi:!1,singleQuote:!0,trailingComma:"none"},{semi:d,singleQuote:l,trailingComma:u}=Object.assign({},i,e?.codePrettier||{}),m=["npx prettier"];d===!1&&m.push("--no-semi"),l===!0&&m.push("--single-quote"),u&&m.push(`--trailing-comma ${u}`);let E=["'logic/**/*.ts'","'handler/**/*.ts'","'model/**/*.ts'","'types/**/*.d.ts'"];m.push("--write",...E);let n=m.join(" "),t=(0,Re.join)(c,o||"src");console.log("[INFO] execRunGen::",t),console.log("[INFO] cmd::",n),(0,Ee.spawnSync)(n,{cwd:t,stdio:"inherit",shell:!0}),S("[INFO] execRunGen","SUCCESS")}catch(c){S("execRunGen fial::","ERROR"),console.error(c)}},Oe=Fe;function Ve(e,r){S(`${r?`The [${r}] app has been `:""}Build DONE. [Build time:${Date.now()-e} ms]`,"SUCCESS")}function ke(e){S(e==="build"?"Build Fail.":"Serve process has exited.","ERROR")}function Ke(){let e=process.cwd(),r=te(process.argv,"--config"),o=(0,q.join)(e,"nserve.config.ts"),c=(0,q.join)(e,"nserve.config.js"),i=r?(0,q.join)(e,r):(0,re.existsSync)(o)?o:c;if(!(0,re.existsSync)(i))throw Error(`The configuration file does not exist. [${i}]`);return i}function _e(e){try{let o=Ke(),c=process.cwd(),i=e,d=te(process.argv,"--mode"),l=JSON.stringify(process.argv),u={AICBLOCK_NSERVE_RUN_CWD:c,AICBLOCK_NSERVE_RUN_CONFIG_PATH:o,AICBLOCK_NSERVE_RUN_MODE:i,AICBLOCK_NSERVE_ENV_MODE:d,AICBLOCK_NSERVE_RUN_ARGV:l};if(Object.keys(u).forEach(a=>{let s=u[a];s!==void 0&&(process.env[a]=s)}),e==="gen"){let{generateConfig:a,sourceDir:s}=F(o,process.cwd());Oe(a||{},c,s||"src");return}let m=Date.now();var r=void 0;let E=process.platform==="win32"?"node.cmd":"node",t=(0,Te.spawn)(E,["./lib/core/run.js","--cmd"],{cwd:(0,q.join)(__dirname,"../"),stdio:e==="build"?"inherit":"pipe",env:Object.assign({},process.env,u)});t.stdout?.on("data",a=>{r&&r.stop(),console.log(a.toString("utf-8"))}),t.stdout?.on("error",a=>{r&&r.stop(),console.log(a.toString())}),t.stderr?.on("data",a=>{r&&r.stop(),console.log(a.toString("utf-8"))}),t.on("exit",a=>{r&&r.stop(),a===0&&e==="build"&&Ve(m,d),a!==0&&ke(e)})}catch(o){S("execRun fial::","ERROR"),console.error(o)}}var We=_e;0&&(module.exports={execRun});
@@ -2,8 +2,24 @@ import type { Response } from 'express';
2
2
  export declare function ErrorResponse(res: Response, err: any, code?: number): void;
3
3
  export declare function SuccessResponse<T>(res: Response, data?: T, message?: string): void;
4
4
  export declare const LoadConfig: (config_path: string) => void;
5
+ export declare const CheckFieldRequired: (data: Record<string, any>, config: Record<string, {
6
+ required: boolean;
7
+ type: "string" | "number" | "array" | "object";
8
+ }>, msg_temp?: {
9
+ required?: string;
10
+ array?: string;
11
+ object?: string;
12
+ }) => void;
5
13
  declare const _default: {
6
14
  ErrorResponse: typeof ErrorResponse;
7
15
  SuccessResponse: typeof SuccessResponse;
16
+ CheckFieldRequired: (data: Record<string, any>, config: Record<string, {
17
+ required: boolean;
18
+ type: "string" | "number" | "array" | "object";
19
+ }>, msg_temp?: {
20
+ required?: string;
21
+ array?: string;
22
+ object?: string;
23
+ }) => void;
8
24
  };
9
25
  export default _default;
@@ -1 +1 @@
1
- "use strict";var d=Object.create;var i=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var E=Object.getPrototypeOf,O=Object.prototype.hasOwnProperty;var A=(r,o)=>{for(var s in o)i(r,s,{get:o[s],enumerable:!0})},f=(r,o,s,e)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of x(o))!O.call(r,n)&&n!==s&&i(r,n,{get:()=>o[n],enumerable:!(e=h(o,n))||e.enumerable});return r};var T=(r,o,s)=>(s=r!=null?d(E(r)):{},f(o||!r||!r.__esModule?i(s,"default",{value:r,enumerable:!0}):s,r)),b=r=>f(i({},"__esModule",{value:!0}),r);var F={};A(F,{ErrorResponse:()=>y,LoadConfig:()=>_,SuccessResponse:()=>R,default:()=>w});module.exports=b(F);var t=require("fs"),m=T(require("yaml"));function l(r,o,s=200,e){let a=Object.assign({code:s,data:o,msg:e||"\u6210\u529F"});r.send(a)}function y(r,o,s=500){console.error("[ERROR] STACK_INFO",o);let e=o?.message||"\u670D\u52A1\u5F02\u5E38",n=/^(\[[\d]*\])/,c=e&&e.match(n)&&e.replace(/^(\[[\d]*\]\-)/,"")||e;l(r,null,s,c)}function R(r,o,s){l(r,o,200,s)}var S=r=>{try{if(!(0,t.existsSync)(r))throw Error(`The configuration file does not exist. [${r}]`);let o=(0,t.readFileSync)(r,"utf8");return m.default.parse(o)}catch(o){throw console.error(o),Error()}},_=r=>{try{if(console.info("[INFO] config path::",r),!(0,t.existsSync)(r))throw Error(`The configuration file does not exist. [${r}]`);let o=S(r);if(!o)return;let s=Array.isArray(o),e=n=>{Object.keys(n)?.forEach(c=>{let g=n[c];global[c]=Array.isArray(g)?g.reduce((p,u)=>Object.assign(p,u),{}):g})};s?o.forEach(e):e(o)}catch(o){throw console.error(o),Error("LOAD_CONFIG_PARAM_ERROR")}},w={ErrorResponse:y,SuccessResponse:R};0&&(module.exports={ErrorResponse,LoadConfig,SuccessResponse});
1
+ "use strict";var R=Object.create;var f=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,O=Object.prototype.hasOwnProperty;var q=(e,r)=>{for(var t in r)f(e,t,{get:r[t],enumerable:!0})},y=(e,r,t,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of E(r))!O.call(e,o)&&o!==t&&f(e,o,{get:()=>r[o],enumerable:!(s=T(r,o))||s.enumerable});return e};var w=(e,r,t)=>(t=e!=null?R(j(e)):{},y(r||!e||!e.__esModule?f(t,"default",{value:e,enumerable:!0}):t,e)),x=e=>y(f({},"__esModule",{value:!0}),e);var S={};q(S,{CheckFieldRequired:()=>b,ErrorResponse:()=>p,LoadConfig:()=>_,SuccessResponse:()=>h,default:()=>k});module.exports=x(S);var l=require("fs"),g=w(require("yaml"));function m(e,r,t=200,s){let i=Object.assign({code:t,data:r,msg:s||"\u6210\u529F"});e.send(i)}function p(e,r,t=500){console.error("[ERROR] STACK_INFO",r);let s=r?.message||"\u670D\u52A1\u5F02\u5E38",o=/^(\[[\d]*\])/,a=s&&s.match(o)&&s.replace(/^(\[[\d]*\]\-)/,"")||s;m(e,null,t,a)}function h(e,r,t){m(e,r,200,t)}var A=e=>{try{if(!(0,l.existsSync)(e))throw Error(`The configuration file does not exist. [${e}]`);let r=(0,l.readFileSync)(e,"utf8");return g.default.parse(r)}catch(r){throw console.error(r),Error()}},_=e=>{try{if(console.info("[INFO] config path::",e),!(0,l.existsSync)(e))throw Error(`The configuration file does not exist. [${e}]`);let r=A(e);if(!r)return;let t=Array.isArray(r),s=o=>{Object.keys(o)?.forEach(a=>{let n=o[a];global[a]=Array.isArray(n)?n.reduce((d,u)=>Object.assign(d,u),{}):n})};t?r.forEach(s):s(r)}catch(r){throw console.error(r),Error("LOAD_CONFIG_PARAM_ERROR")}},b=(e,r,t)=>{if(e==null)throw Error("The data is required.");if(r==null)throw Error("The config is required.");let o={...{required:"The field [${key}] is required.",array:"The field [${key}] must be an array with at least one element.",object:"The field [${key}] must be an object."},...t},i=(n,d)=>n.replace(/\$\{key\}/g,d);Object.keys(r).forEach(n=>{if(!r[n].required)return;let u=r[n].type,c=e[n];if(c==null)throw Error(i(o.required,n));if(u==="array"&&(!Array.isArray(c)||c.length===0))throw Error(i(o.array,n));if(u==="object"&&(Object.prototype.toString.call(c)!=="[object Object]"||Object.keys(c).length===0))throw Error(i(o.object,n))})},k={ErrorResponse:p,SuccessResponse:h,CheckFieldRequired:b};0&&(module.exports={CheckFieldRequired,ErrorResponse,LoadConfig,SuccessResponse});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aicblock/nserve",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "🛠️ Description NodeJS Server-side development CLI",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -13,6 +13,7 @@
13
13
  "serve-cli",
14
14
  "node-server"
15
15
  ],
16
+ "homepage": "http://nserve.aicblock.cn/",
16
17
  "bin": {
17
18
  "nserve": "lib/commander.js"
18
19
  },
@@ -50,6 +51,7 @@
50
51
  "esbuild": "0.27.2",
51
52
  "express": "5.2.1",
52
53
  "js-yaml": "4.1.1",
54
+ "prettier": "3.7.4",
53
55
  "yaml": "2.8.2"
54
56
  }
55
57
  }