Skip to content

Commit bcb3d7c

Browse files
committed
chore: refact mergeDeep to class
1 parent 04c3ef6 commit bcb3d7c

File tree

7 files changed

+216
-78
lines changed

7 files changed

+216
-78
lines changed

package.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,13 @@
5959
],
6060
"dependencies": {
6161
"@changesets/cli": "^2.26.2"
62-
}
63-
}
62+
},
63+
"version": "1.0.0",
64+
"main": "commitlint.config.js",
65+
"directories": {
66+
"doc": "docs",
67+
"example": "example"
68+
},
69+
"keywords": [],
70+
"author": ""
71+
}

packages/app/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@
2626
"awesome-keywords"
2727
],
2828
"devDependencies": {
29+
"@types/koa": "^2.13.10",
2930
"@vitest/coverage-v8": "^1.0.1",
30-
"happy-dom": "^6.0.4",
31+
"supertest": "^6.3.3",
3132
"vitest": "^1.0.1"
3233
},
3334
"dependencies": {
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import supertest from 'supertest';
2+
import { describe, expect, it } from 'vitest';
3+
4+
import { createApp, AppServer } from '../index';
5+
6+
describe('app', async () => {
7+
const rpc: AppServer = await createApp({
8+
name: 'tomapp',
9+
base: import.meta.url,
10+
port: 3001,
11+
debug: false,
12+
mount: './f',
13+
});
14+
15+
rpc.fn('a', function (a) {
16+
// console.dir(rpc.fn);
17+
// console.dir(this);
18+
// this.render('user', { user: { name: 'alfred' } });
19+
return { a: a };
20+
});
21+
22+
rpc.fn('/a', function (a) {
23+
return { a: a };
24+
});
25+
26+
rpc.fn('/b', function (a) {
27+
if (this.method === 'POST') {
28+
return { a: a, method: 'post' };
29+
}
30+
if (this.method === 'GET') {
31+
return { a: a, method: 'get' };
32+
}
33+
});
34+
35+
rpc.fn('com.yourcompany.a', function (a: string) {
36+
return { a: a };
37+
});
38+
39+
rpc.fn('com.yourcompany.b', function (a: string) {
40+
return `${this.path} , ${a} `;
41+
});
42+
43+
rpc.add({
44+
'/add': function (a: string, b: string) {
45+
return { a: a };
46+
},
47+
});
48+
49+
const request = supertest(rpc.callback());
50+
51+
it('should start === rpc.callback', async () => {
52+
const request2 = supertest(rpc.start(30001));
53+
const res = await request2.get('/api/a?$p=["hello"]');
54+
expect(res.type).toEqual('application/json');
55+
expect(res.status).toEqual(200);
56+
expect(res.body).toEqual({ a: 'hello' });
57+
});
58+
59+
it('should access /a', async () => {
60+
const res = await request.get('/api/a?$p=["hello"]');
61+
expect(res.type).toEqual('application/json');
62+
expect(res.status).toEqual(200);
63+
expect(res.body).toEqual({ a: 'hello' });
64+
});
65+
66+
it('should access no routers[key]', async () => {
67+
// if (!['POST', 'PUT', 'PATCH'].includes(ctx.method) && !ctx.query.$p) {
68+
const res = await request.get('/api/a123');
69+
expect(res.type).toEqual('text/plain');
70+
expect(res.status).toEqual(200);
71+
expect(res.text).toEqual('not match $p param, no process');
72+
});
73+
74+
it('should access no routers[key]', async () => {
75+
const res = await request.get('/api/a123?$p=["hello"]');
76+
expect(res.type).toEqual('text/plain');
77+
expect(res.status).toEqual(200);
78+
expect(res.text).toEqual('[fn plugin] no fn repsonse, please check your fn if exist');
79+
});
80+
81+
it('should access /add', async () => {
82+
const res = await request.get('/api/add?$p=["hello"]');
83+
expect(res.type).toEqual('application/json');
84+
expect(res.status).toEqual(200);
85+
expect(res.body).toEqual({ a: 'hello' });
86+
});
87+
88+
it('should access GET /b', async () => {
89+
const res = await request.get('/api/b?$p=["hello1"]');
90+
expect(res.type).toEqual('application/json');
91+
expect(res.status).toEqual(200);
92+
expect(res.body).toEqual({ a: 'hello1', method: 'get' });
93+
});
94+
95+
it('should access POST /b', async () => {
96+
const res = await request.post('/api/b').send(['hello']).set('Accept', 'application/json');
97+
98+
expect(res.type).toEqual('application/json');
99+
expect(res.status).toEqual(200);
100+
expect(res.body).toEqual({ a: 'hello', method: 'post' });
101+
});
102+
103+
it('should access com.yourcompany.b', async () => {
104+
const res = await request.get('/api/com/yourcompany/b?$p=["hello"]');
105+
expect(res.type).toEqual('text/plain');
106+
expect(res.status).toEqual(200);
107+
expect(res.text).toEqual('/com/yourcompany/b , hello ');
108+
});
109+
});
Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
import { describe, expect, it } from 'vitest';
1+
import { describe, expect, it, vi } from 'vitest';
22

3-
// import mount from '../mount';
4-
5-
describe('lib', () => {
3+
describe('app', async () => {
64
it('should render lib', () => {
7-
// expect(lib()).toBe('lib');
5+
expect('lib').toBe('lib');
6+
});
7+
8+
it('mock console.dir', () => {
9+
const spy = vi.spyOn(console, 'dir');
10+
console.dir('2323');
11+
expect(spy).toHaveBeenCalled();
812
});
913
});

packages/app/src/index.ts

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import { createServer, combine } from '@tomrpc/core';
1+
import { createServer, combine, RpcServer } from '@tomrpc/core';
2+
import type { IIndexServerConfig } from '@tomrpc/core';
23
// import mount from '@tomrpc/mount';
4+
import exp from 'constants';
35
import debug from 'debug';
46

57
import { init } from './init';
@@ -46,55 +48,59 @@ interface IJwt {
4648
unless?: any;
4749
getToken;
4850
}
49-
interface IConfig {
50-
name: string | 'tomapp';
51+
interface IAppConfig1 {
52+
name?: string | 'tomapp';
5153
base?: string;
5254
port?: number | 3000;
5355
debug?: boolean | false;
5456
mount?: string;
55-
buildin: {
57+
buildin?: {
5658
serve?: IServe;
5759
cors?: ICors;
5860
view?: IView;
5961
jwt?: IJwt;
6062
};
6163
}
62-
export async function createApp(cfg: IConfig) {
63-
const rpc = createServer(
64-
mergeDeep(
65-
{
66-
base: import.meta.url,
67-
},
68-
cfg
69-
)
70-
);
7164

72-
if (cfg.buildin.cors) {
73-
const cors = new Cors(cfg.buildin.cors);
74-
rpc.plugin(cors);
75-
}
65+
type IAppConfig = IAppConfig1 & IIndexServerConfig;
7666

77-
if (cfg.buildin.serve) {
78-
const serve = new Serve(cfg.buildin.serve);
79-
rpc.plugin(serve);
80-
}
67+
export class AppServer extends RpcServer {
68+
constructor(cfg?: IAppConfig) {
69+
super(cfg);
70+
71+
if (cfg?.buildin?.cors) {
72+
const cors = new Cors(cfg?.buildin?.cors);
73+
this.plugin(cors);
74+
}
75+
76+
if (cfg?.buildin?.serve) {
77+
const serve = new Serve(cfg?.buildin?.serve);
78+
this.plugin(serve);
79+
}
8180

82-
if (cfg.buildin.jwt) {
83-
const jwt = new Jwt(cfg.buildin.jwt);
84-
rpc.plugin(jwt);
81+
if (cfg?.buildin?.jwt) {
82+
const jwt = new Jwt(cfg?.buildin?.jwt);
83+
this.plugin(jwt);
84+
}
8585
}
8686

87-
return mergeDeep(rpc, {
88-
jwt: function (cb) {
89-
// const mw = combine([cb]);
90-
// console.dir(rpc.config);
91-
// rpc.init.push(mw);
92-
},
93-
render: function (path, cb) {
94-
// console.dir('render');
95-
const view = new View(cfg.buildin.view);
87+
public render(path, cb): void {
88+
// console.dir('render');
89+
if (this.config?.buildin?.view) {
90+
const view = new View(this.config?.buildin?.view);
9691
const mw = combine([view.proxy(), cb]);
97-
rpc.app.use(mw);
98-
},
99-
});
92+
this.app.use(mw);
93+
}
94+
}
95+
}
96+
97+
export function createApp(cfg?: IAppConfig): AppServer {
98+
return new AppServer(
99+
mergeDeep(
100+
{
101+
base: import.meta.url,
102+
},
103+
cfg || {}
104+
)
105+
);
100106
}

packages/core/src/index.ts

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import debug from 'debug';
22
import compose from 'koa-compose';
33

44
import { Fn, IFnConfig } from './fn';
5-
import { RpcServer, IRpcServerConfig } from './server';
5+
import { BaseRpcServer, IRpcServerConfig } from './server';
66
import { mergeDeep } from './utils';
77

88
export * from './plugin';
@@ -14,31 +14,41 @@ export * from './utils';
1414
const log = debug('@tomrpc/core/index');
1515
export const combine = compose;
1616

17-
interface IServerConfig {
17+
export interface IServerConfig {
1818
base?: string;
1919
fn?: IFnConfig;
2020
}
2121

22-
type IIndexServerConfig = IRpcServerConfig & IServerConfig;
22+
export type IIndexServerConfig = IRpcServerConfig & IServerConfig;
23+
24+
export class RpcServer extends BaseRpcServer {
25+
private fnPlugin;
26+
public base;
27+
public before;
28+
public after;
29+
30+
constructor(cfg?: IIndexServerConfig) {
31+
super(cfg);
32+
this.fnPlugin = new Fn(mergeDeep({}, cfg.fn));
33+
this.plugin(this.fnPlugin);
34+
35+
this.base = '.';
36+
this.init = this['config']['hooks']['init'];
37+
this.before = this['config']['hooks']['before'];
38+
this.load = this['config']['hooks']['load'];
39+
this.after = this['config']['hooks']['after'];
40+
}
41+
42+
public fn(key, fun) {
43+
log('use rpc.fn add fn =' + key);
44+
this.fnPlugin.fn(key, fun);
45+
}
46+
public add(items) {
47+
log('use rpc.add add fn =' + items);
48+
this.fnPlugin.add(items);
49+
}
50+
}
2351

2452
export function createServer(cfg?: IIndexServerConfig) {
25-
const rpc = new RpcServer(mergeDeep({ fn: {} }, cfg));
26-
const fn = new Fn(mergeDeep({}, cfg.fn));
27-
rpc.plugin(fn);
28-
29-
return mergeDeep(rpc, {
30-
base: '.',
31-
init: rpc['config']['hooks']['init'],
32-
before: rpc['config']['hooks']['before'],
33-
load: rpc['config']['hooks']['load'],
34-
after: rpc['config']['hooks']['after'],
35-
fn: function (key, fun) {
36-
log('use rpc.fn add fn =' + key);
37-
fn.fn(key, fun);
38-
},
39-
add: function (items) {
40-
log('use rpc.add add fn =' + items);
41-
fn.add(items);
42-
},
43-
});
53+
return new RpcServer(mergeDeep({ fn: {} }, cfg));
4454
}

0 commit comments

Comments
 (0)