Skip to content

Commit 9788624

Browse files
authored
feat: 新增grs命令通过routerSchema生成请求接口api (#20)
Co-authored-by: cmtlyt <cmtlyt@163.com>
1 parent 6c121f8 commit 9788624

File tree

15 files changed

+467
-109
lines changed

15 files changed

+467
-109
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@
7878
"pathe": "^2.0.3",
7979
"pkg-types": "^2.1.0",
8080
"rimraf": "^6.0.1",
81-
"scule": "^1.3.0"
81+
"scule": "^1.3.0",
82+
"untyped": "^2.0.0"
8283
},
8384
"lint-staged": {
8485
"*.{js,ts}": [

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bootstrap.ts

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/cli.ts

Lines changed: 16 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,19 @@
11
#!/usr/bin/env node
22

3-
import type { DevOptions } from './types';
4-
import fs from 'node:fs';
53
import { defineCommand, runMain } from 'citty';
6-
import { resolve } from 'pathe';
74
import { version } from '../package.json';
8-
import { bootstrap } from './bootstrap';
9-
import { build as buildApp } from './build';
10-
import { runProd } from './run-prod';
11-
import { getStorage, setStorage } from './storage';
12-
import { consola, getPkgInfo, parseConfig } from './utils';
13-
14-
function debounce<F extends (...args: any[]) => any>(fn: F, delay = 200) {
15-
let timer: NodeJS.Timeout;
16-
return ((...args: any[]) => {
17-
clearTimeout(timer);
18-
timer = setTimeout(() => fn(...args), delay);
19-
}) as F;
20-
}
21-
22-
function errorHandler(e: Error) {
23-
consola.error(e);
24-
}
25-
26-
async function restart(options: DevOptions) {
27-
try {
28-
const oldServer = getStorage('server');
29-
oldServer.closeAllConnections();
30-
oldServer.close();
31-
const { app, router } = await bootstrap();
32-
setStorage('server', app.listen(options.port));
33-
return { app, router };
34-
}
35-
catch (e: any) {
36-
errorHandler(e);
37-
return {};
38-
}
39-
}
40-
41-
const watchHandler = debounce(async (options: DevOptions) => {
42-
consola.start('Watching for changes...');
43-
await restart(options);
44-
consola.success('Restarted');
45-
});
46-
47-
async function devHandler(options: DevOptions) {
48-
const { pkgPath, sourceDir } = options;
49-
fs.watchFile(resolve(pkgPath, 'main.ts'), () => watchHandler(options));
50-
fs.watch(sourceDir, { recursive: true }, async (_, filename) => {
51-
if (filename?.endsWith('module.d.ts'))
52-
return;
53-
watchHandler(options);
54-
});
55-
}
5+
import { bootstrapCli } from './cli/bootstrap';
6+
import { build as buildApp } from './cli/build';
7+
import { generateRequestScriptCli } from './cli/generate-request-script';
8+
import { runProd } from './cli/run-prod';
569

5710
const dev = defineCommand({
5811
meta: {
5912
name: 'dev',
6013
description: 'Start development server',
6114
},
6215
async run() {
63-
const { port, sourceDir } = await parseConfig();
64-
const { pkgPath } = await getPkgInfo();
65-
const devOptions = { pkgPath, sourceDir, port, isCli: true };
66-
setStorage('devOptions', devOptions);
67-
const { app } = await bootstrap();
68-
await devHandler(devOptions);
69-
setStorage('server', app.listen(port, () => {
70-
consola.box('live server', `http://localhost:${port}`);
71-
}));
16+
await bootstrapCli();
7217
},
7318
});
7419

@@ -92,13 +37,23 @@ const run = defineCommand({
9237
},
9338
});
9439

40+
const generateRequestScript = defineCommand({
41+
meta: {
42+
name: 'generateRequestScript',
43+
description: 'Generate request script',
44+
},
45+
async run() {
46+
await generateRequestScriptCli();
47+
},
48+
});
49+
9550
const main = defineCommand({
9651
meta: {
9752
name: 'tee',
9853
version,
9954
description: '@cmtlyt/tee cli',
10055
},
101-
subCommands: { dev, build, run },
56+
subCommands: { dev, build, run, grs: generateRequestScript },
10257
});
10358

10459
runMain(main);

src/cli/bootstrap.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import type { DevOptions, GenerateTypeOptions, TeeKoa } from '../types';
2+
import fs from 'node:fs';
3+
import KoaRouter from '@koa/router';
4+
import Koa from 'koa';
5+
import { resolve } from 'pathe';
6+
import { getStorage, setStorage } from '../storage';
7+
import { consola, getPkgInfo, loadModule, parseConfig, parseOptions, runSourceMain } from '../utils';
8+
9+
export async function bootstrap(_options?: GenerateTypeOptions) {
10+
const options = await parseOptions(_options);
11+
12+
const app = new Koa() as TeeKoa.Application;
13+
const router = new KoaRouter();
14+
15+
setStorage('app', app);
16+
setStorage('router', router);
17+
18+
const { typeDeclarations, sourcePath } = await loadModule(app, router, options);
19+
20+
app.middlewares ||= {};
21+
22+
const devOptions = getStorage('devOptions');
23+
if (devOptions?.isCli) {
24+
await runSourceMain(devOptions);
25+
}
26+
27+
app.use(router.routes()).use(router.allowedMethods());
28+
29+
if (!getStorage('isProd', false)) {
30+
fs.writeFileSync(resolve(sourcePath, 'module.d.ts'), typeDeclarations, 'utf-8');
31+
}
32+
33+
return { app, router };
34+
}
35+
36+
function debounce<F extends (...args: any[]) => any>(fn: F, delay = 200) {
37+
let timer: NodeJS.Timeout;
38+
return ((...args: any[]) => {
39+
clearTimeout(timer);
40+
timer = setTimeout(() => fn(...args), delay);
41+
}) as F;
42+
}
43+
44+
function errorHandler(e: Error) {
45+
consola.error(e);
46+
}
47+
48+
async function restart(options: DevOptions) {
49+
try {
50+
const oldServer = getStorage('server');
51+
oldServer.closeAllConnections();
52+
oldServer.close();
53+
const { app, router } = await bootstrap();
54+
setStorage('server', app.listen(options.port));
55+
return { app, router };
56+
}
57+
catch (e: any) {
58+
errorHandler(e);
59+
return {};
60+
}
61+
}
62+
63+
const watchHandler = debounce(async (options: DevOptions) => {
64+
consola.start('Watching for changes...');
65+
await restart(options);
66+
consola.success('Restarted');
67+
});
68+
69+
async function devHandler(options: DevOptions) {
70+
const { pkgPath, sourceDir } = options;
71+
fs.watchFile(resolve(pkgPath, 'main.ts'), () => watchHandler(options));
72+
fs.watch(sourceDir, { recursive: true }, async (_, filename) => {
73+
if (filename?.endsWith('module.d.ts'))
74+
return;
75+
watchHandler(options);
76+
});
77+
}
78+
79+
export async function bootstrapCli() {
80+
const { port, sourceDir } = await parseConfig();
81+
const { pkgPath } = await getPkgInfo();
82+
const devOptions = { pkgPath, sourceDir, port, isCli: true };
83+
setStorage('devOptions', devOptions);
84+
const { app } = await bootstrap();
85+
await devHandler(devOptions);
86+
setStorage('server', app.listen(port, () => {
87+
consola.box('live server', `http://localhost:${port}`);
88+
}));
89+
}

src/build.ts renamed to src/cli/build.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import type { BuildConfig, FileInfoMap, ModuleType } from './types';
1+
import type { BuildConfig, FileInfoMap, ModuleType } from '../types';
22
import { existsSync } from 'node:fs';
33
import { build as esbuild } from 'esbuild';
44
import { basename, resolve } from 'pathe';
55
import { rimraf } from 'rimraf';
6-
import { defu, getFileInfoMap, getPkgInfo, parseConfig } from './utils';
6+
import { defu, getFileInfoMap, getPkgInfo, parseConfig } from '../utils';
77

88
interface BuildOptions extends BuildConfig {
99
sourceDir?: string;

0 commit comments

Comments
 (0)