@aicblock/nserve 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 dpapejs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # @aicblock/nserve
2
+
3
+ ![npm](https://img.shields.io/npm/v/@aicblock/nserve)
4
+ ![npm](https://img.shields.io/npm/dm/@aicblock/nserve)
5
+ ![NPM](https://img.shields.io/npm/l/@aicblock/nserve)
6
+
7
+ #### Description
8
+
9
+ 🛠️ Description NodeJS Server-side development CLI
10
+
11
+ #### 快速搭建第一个 Nserve 项目
12
+
13
+ #### 使用 NPM:
14
+
15
+ ```sh
16
+ $ npm create nserve@latest
17
+ ```
18
+
19
+ #### 使用 Yarn:
20
+
21
+ ```sh
22
+ $ yarn create nserve@latest
23
+ ```
24
+
25
+ #### 使用 PNPM:
26
+
27
+ ```sh
28
+ $ pnpm create nserve@latest
29
+ ```
@@ -0,0 +1,2 @@
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);
@@ -0,0 +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});
package/lib/index.d.ts ADDED
@@ -0,0 +1,178 @@
1
+ import { build, transformSync } from 'esbuild';
2
+ export declare const nbuild: {
3
+ transformSync: typeof transformSync;
4
+ build: typeof build;
5
+ };
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
+ };
14
+ declare const _default: {
15
+ DefineNserveConfig: typeof DefineNserveConfig;
16
+ DefineGenRouter: (param: DefineGenRouterConfig) => {
17
+ prefix: string;
18
+ service: (RouterOption & {
19
+ handler: string;
20
+ })[];
21
+ handler: string;
22
+ };
23
+ };
24
+ export default _default;
25
+
26
+ interface MiddlewareConfigOption {
27
+ /**
28
+ * 中间件库名
29
+ * Middleware library name
30
+ */
31
+ libName: string
32
+ /**
33
+ * 中间件函数名
34
+ * Middleware function name
35
+ */
36
+ funcName: string
37
+ /**
38
+ * 是否为 AMD 模块
39
+ * Whether it is an AMD module
40
+ */
41
+ amd?: boolean
42
+ /**
43
+ * 是否为 CMD 模块
44
+ * Whether it is a CMD module
45
+ */
46
+ cmd?: boolean
47
+ }
48
+ interface GenerateConfigOption {
49
+ /**
50
+ * 生成的配置文件目录
51
+ * Generated config file directory
52
+ */
53
+ genDir?: string
54
+ /**
55
+ * 路由配置文件目录
56
+ * Router config file directory
57
+ */
58
+ routerDir?: string
59
+ /**
60
+ * 模型配置文件目录
61
+ * Model config file directory
62
+ */
63
+ modelDir?: string
64
+
65
+ /**
66
+ * 中间件配置
67
+ * Middleware configuration
68
+ */
69
+ middleware?: MiddlewareConfigOption[]
70
+ }
71
+ interface Config {
72
+ /**
73
+ * Whether to generate a tracing file
74
+ */
75
+ sourceMap?: boolean
76
+ /**
77
+ * 外部依赖
78
+ * External dependencies
79
+ */
80
+ external?: string[]
81
+ /**
82
+ * esbuild插件配置
83
+ * Plug-in configuration
84
+ */
85
+ plugins?: Plugin[]
86
+ /**
87
+ * 源码目录
88
+ * Source dir
89
+ */
90
+ sourceDir?: string
91
+ /**
92
+ * 服务启动入口,只要编译不需要配置
93
+ * Application entry file
94
+ */
95
+ entry?: string
96
+ /**
97
+ * Whether to build a test environment
98
+ */
99
+ testing?: boolean
100
+ /**
101
+ * webpack build output directory name
102
+ */
103
+ outputDir?: string
104
+ /**
105
+ * Before lifecycle
106
+ */
107
+ lifecycleBefore?: (config: Config) => Config
108
+ /**
109
+ * Whether to generate a config file
110
+ */
111
+ generateConfig?: GenerateConfigOption
112
+ /**
113
+ * 自定义 YAML 配置
114
+ * Custom YAML configuration
115
+ */
116
+ yamlConfig?: Record<string, any>
117
+ }
118
+
119
+ /**
120
+ * 任意对象
121
+ */
122
+ interface IAnyObject {
123
+ [key: string]: any
124
+ }
125
+
126
+ type RouterMethod =
127
+ | 'GET'
128
+ | 'POST'
129
+ | 'PUT'
130
+ | 'DELETE'
131
+ | 'PATCH'
132
+ | 'OPTIONS'
133
+ | 'HEAD'
134
+ | 'CONNECT'
135
+ | 'TRACE'
136
+
137
+ interface DataTypeProperty {
138
+ // 数据类型
139
+ type: 'string' | 'number' | 'boolean' | 'object' | 'array'
140
+ // 数据类型名称
141
+ name: string
142
+ // 数据类型描述
143
+ description?: string
144
+ // 对象属性定义
145
+ properties?: DataTypeProperty[]
146
+ // 数组项类型定义
147
+ item?: DataTypeProperty[]
148
+ }
149
+ // 数据类型定义
150
+ interface DataType {
151
+ name: string
152
+ properties: DataTypeProperty[]
153
+ }
154
+
155
+ // 路由选项定义
156
+ interface RouterOption {
157
+ // 路由路径
158
+ path: string
159
+ // 路由处理函数
160
+ name: string
161
+ // 路由方法
162
+ method?: RouterMethod
163
+ // 路由文档备注
164
+ docRemark?: string
165
+ // 路由请求数据类型定义
166
+ requestDataType?: IAnyObject
167
+ // 路由响应数据类型定义
168
+ responseDataType?: IAnyObject
169
+ }
170
+
171
+ // 路由配置定义
172
+ interface DefineGenRouterConfig {
173
+ servicePath: string
174
+ serviceHandler: string
175
+ routers: RouterOption[]
176
+ }
177
+
178
+ type EXEC_COMMAND = 'serve' | 'build' | 'gen'
package/lib/index.js ADDED
@@ -0,0 +1 @@
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});
package/lib/runtime.js ADDED
@@ -0,0 +1,14 @@
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(`
2
+ export async function ServiceLogic(req: Request, res: Response) {
3
+ try {
4
+ SuccessResponse(res)
5
+ } catch (error) {
6
+ ErrorResponse(res, error)
7
+ }
8
+ }
9
+ 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});
@@ -0,0 +1,9 @@
1
+ import type { Response } from 'express';
2
+ export declare function ErrorResponse(res: Response, err: any, code?: number): void;
3
+ export declare function SuccessResponse<T>(res: Response, data?: T, message?: string): void;
4
+ export declare const LoadConfig: (config_path: string) => void;
5
+ declare const _default: {
6
+ ErrorResponse: typeof ErrorResponse;
7
+ SuccessResponse: typeof SuccessResponse;
8
+ };
9
+ export default _default;
@@ -0,0 +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});
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@aicblock/nserve",
3
+ "version": "1.0.0",
4
+ "description": "🛠️ Description NodeJS Server-side development CLI",
5
+ "main": "lib/index.js",
6
+ "scripts": {
7
+ "dev": "ts-node ./script/dev.ts",
8
+ "package": "ts-node ./script/build.ts",
9
+ "prepare": "husky install",
10
+ "test": "jest --coverage"
11
+ },
12
+ "keywords": [
13
+ "serve-cli",
14
+ "node-server"
15
+ ],
16
+ "bin": {
17
+ "nserve": "lib/commander.js"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://gitee.com/aiclouddigit/nserve.git"
22
+ },
23
+ "files": [
24
+ "lib"
25
+ ],
26
+ "author": "jieyang;damon yang",
27
+ "license": "MIT",
28
+ "devDependencies": {
29
+ "@commitlint/cli": "19.3.0",
30
+ "@commitlint/config-conventional": "19.2.2",
31
+ "@dpapejs/node-utils": "^0.1.0",
32
+ "@types/express": "^5.0.6",
33
+ "@types/jest": "^29.5.12",
34
+ "@types/js-yaml": "^4.0.9",
35
+ "@types/node": "^16.4.10",
36
+ "husky": "9.0.11",
37
+ "jest": "29.7.0",
38
+ "ts-jest": "29.1.5",
39
+ "ts-node": "^10.9.2",
40
+ "typescript": "5.5.3"
41
+ },
42
+ "husky": {
43
+ "hooks": {
44
+ "commit-msg": "commitlint -E HUSKY_GIT_PARAMS,"
45
+ }
46
+ },
47
+ "dependencies": {
48
+ "@dpapejs/emysql": "1.2.7",
49
+ "commander": "14.0.2",
50
+ "esbuild": "0.27.2",
51
+ "express": "5.2.1",
52
+ "js-yaml": "4.1.1",
53
+ "yaml": "2.8.2"
54
+ }
55
+ }