Skip to content

Commit

Permalink
chore: refact mergeDeep to class
Browse files Browse the repository at this point in the history
  • Loading branch information
npmstudy committed Dec 12, 2023
1 parent 04c3ef6 commit bcb3d7c
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 78 deletions.
12 changes: 10 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,13 @@
],
"dependencies": {
"@changesets/cli": "^2.26.2"
}
}
},
"version": "1.0.0",
"main": "commitlint.config.js",
"directories": {
"doc": "docs",
"example": "example"
},
"keywords": [],
"author": ""
}
3 changes: 2 additions & 1 deletion packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
"awesome-keywords"
],
"devDependencies": {
"@types/koa": "^2.13.10",
"@vitest/coverage-v8": "^1.0.1",
"happy-dom": "^6.0.4",
"supertest": "^6.3.3",
"vitest": "^1.0.1"
},
"dependencies": {
Expand Down
109 changes: 109 additions & 0 deletions packages/app/src/__tests__/app.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import supertest from 'supertest';
import { describe, expect, it } from 'vitest';

import { createApp, AppServer } from '../index';

describe('app', async () => {
const rpc: AppServer = await createApp({
name: 'tomapp',
base: import.meta.url,
port: 3001,
debug: false,
mount: './f',
});

rpc.fn('a', function (a) {
// console.dir(rpc.fn);
// console.dir(this);
// this.render('user', { user: { name: 'alfred' } });
return { a: a };
});

rpc.fn('/a', function (a) {
return { a: a };
});

rpc.fn('/b', function (a) {
if (this.method === 'POST') {
return { a: a, method: 'post' };
}
if (this.method === 'GET') {
return { a: a, method: 'get' };
}
});

rpc.fn('com.yourcompany.a', function (a: string) {
return { a: a };
});

rpc.fn('com.yourcompany.b', function (a: string) {
return `${this.path} , ${a} `;
});

rpc.add({
'/add': function (a: string, b: string) {

Check warning on line 44 in packages/app/src/__tests__/app.test.ts

View workflow job for this annotation

GitHub Actions / build

'b' is defined but never used
return { a: a };
},
});

const request = supertest(rpc.callback());

it('should start === rpc.callback', async () => {
const request2 = supertest(rpc.start(30001));
const res = await request2.get('/api/a?$p=["hello"]');
expect(res.type).toEqual('application/json');
expect(res.status).toEqual(200);
expect(res.body).toEqual({ a: 'hello' });
});

it('should access /a', async () => {
const res = await request.get('/api/a?$p=["hello"]');
expect(res.type).toEqual('application/json');
expect(res.status).toEqual(200);
expect(res.body).toEqual({ a: 'hello' });
});

it('should access no routers[key]', async () => {
// if (!['POST', 'PUT', 'PATCH'].includes(ctx.method) && !ctx.query.$p) {
const res = await request.get('/api/a123');
expect(res.type).toEqual('text/plain');
expect(res.status).toEqual(200);
expect(res.text).toEqual('not match $p param, no process');
});

it('should access no routers[key]', async () => {
const res = await request.get('/api/a123?$p=["hello"]');
expect(res.type).toEqual('text/plain');
expect(res.status).toEqual(200);
expect(res.text).toEqual('[fn plugin] no fn repsonse, please check your fn if exist');
});

it('should access /add', async () => {
const res = await request.get('/api/add?$p=["hello"]');
expect(res.type).toEqual('application/json');
expect(res.status).toEqual(200);
expect(res.body).toEqual({ a: 'hello' });
});

it('should access GET /b', async () => {
const res = await request.get('/api/b?$p=["hello1"]');
expect(res.type).toEqual('application/json');
expect(res.status).toEqual(200);
expect(res.body).toEqual({ a: 'hello1', method: 'get' });
});

it('should access POST /b', async () => {
const res = await request.post('/api/b').send(['hello']).set('Accept', 'application/json');

expect(res.type).toEqual('application/json');
expect(res.status).toEqual(200);
expect(res.body).toEqual({ a: 'hello', method: 'post' });
});

it('should access com.yourcompany.b', async () => {
const res = await request.get('/api/com/yourcompany/b?$p=["hello"]');
expect(res.type).toEqual('text/plain');
expect(res.status).toEqual(200);
expect(res.text).toEqual('/com/yourcompany/b , hello ');
});
});
14 changes: 9 additions & 5 deletions packages/app/src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { describe, expect, it } from 'vitest';
import { describe, expect, it, vi } from 'vitest';

// import mount from '../mount';

describe('lib', () => {
describe('app', async () => {
it('should render lib', () => {
// expect(lib()).toBe('lib');
expect('lib').toBe('lib');
});

it('mock console.dir', () => {
const spy = vi.spyOn(console, 'dir');
console.dir('2323');
expect(spy).toHaveBeenCalled();
});
});
78 changes: 42 additions & 36 deletions packages/app/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { createServer, combine } from '@tomrpc/core';
import { createServer, combine, RpcServer } from '@tomrpc/core';

Check warning on line 1 in packages/app/src/index.ts

View workflow job for this annotation

GitHub Actions / build

'createServer' is defined but never used

Check failure on line 1 in packages/app/src/index.ts

View workflow job for this annotation

GitHub Actions / build

Unable to resolve path to module '@tomrpc/core'
import type { IIndexServerConfig } from '@tomrpc/core';
// import mount from '@tomrpc/mount';
import exp from 'constants';

Check warning on line 4 in packages/app/src/index.ts

View workflow job for this annotation

GitHub Actions / build

'exp' is defined but never used
import debug from 'debug';

import { init } from './init';

Check warning on line 7 in packages/app/src/index.ts

View workflow job for this annotation

GitHub Actions / build

'init' is defined but never used
Expand Down Expand Up @@ -46,55 +48,59 @@ interface IJwt {
unless?: any;
getToken;
}
interface IConfig {
name: string | 'tomapp';
interface IAppConfig1 {
name?: string | 'tomapp';
base?: string;
port?: number | 3000;
debug?: boolean | false;
mount?: string;
buildin: {
buildin?: {
serve?: IServe;
cors?: ICors;
view?: IView;
jwt?: IJwt;
};
}
export async function createApp(cfg: IConfig) {
const rpc = createServer(
mergeDeep(
{
base: import.meta.url,
},
cfg
)
);

if (cfg.buildin.cors) {
const cors = new Cors(cfg.buildin.cors);
rpc.plugin(cors);
}
type IAppConfig = IAppConfig1 & IIndexServerConfig;

if (cfg.buildin.serve) {
const serve = new Serve(cfg.buildin.serve);
rpc.plugin(serve);
}
export class AppServer extends RpcServer {
constructor(cfg?: IAppConfig) {
super(cfg);

if (cfg?.buildin?.cors) {
const cors = new Cors(cfg?.buildin?.cors);
this.plugin(cors);
}

if (cfg?.buildin?.serve) {
const serve = new Serve(cfg?.buildin?.serve);
this.plugin(serve);
}

if (cfg.buildin.jwt) {
const jwt = new Jwt(cfg.buildin.jwt);
rpc.plugin(jwt);
if (cfg?.buildin?.jwt) {
const jwt = new Jwt(cfg?.buildin?.jwt);
this.plugin(jwt);
}
}

return mergeDeep(rpc, {
jwt: function (cb) {
// const mw = combine([cb]);
// console.dir(rpc.config);
// rpc.init.push(mw);
},
render: function (path, cb) {
// console.dir('render');
const view = new View(cfg.buildin.view);
public render(path, cb): void {
// console.dir('render');
if (this.config?.buildin?.view) {
const view = new View(this.config?.buildin?.view);
const mw = combine([view.proxy(), cb]);
rpc.app.use(mw);
},
});
this.app.use(mw);
}
}
}

export function createApp(cfg?: IAppConfig): AppServer {
return new AppServer(
mergeDeep(
{
base: import.meta.url,
},
cfg || {}
)
);
}
54 changes: 32 additions & 22 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import debug from 'debug';
import compose from 'koa-compose';

import { Fn, IFnConfig } from './fn';
import { RpcServer, IRpcServerConfig } from './server';
import { BaseRpcServer, IRpcServerConfig } from './server';
import { mergeDeep } from './utils';

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

interface IServerConfig {
export interface IServerConfig {
base?: string;
fn?: IFnConfig;
}

type IIndexServerConfig = IRpcServerConfig & IServerConfig;
export type IIndexServerConfig = IRpcServerConfig & IServerConfig;

export class RpcServer extends BaseRpcServer {
private fnPlugin;
public base;
public before;
public after;

constructor(cfg?: IIndexServerConfig) {
super(cfg);
this.fnPlugin = new Fn(mergeDeep({}, cfg.fn));
this.plugin(this.fnPlugin);

this.base = '.';
this.init = this['config']['hooks']['init'];
this.before = this['config']['hooks']['before'];
this.load = this['config']['hooks']['load'];
this.after = this['config']['hooks']['after'];
}

public fn(key, fun) {
log('use rpc.fn add fn =' + key);
this.fnPlugin.fn(key, fun);
}
public add(items) {
log('use rpc.add add fn =' + items);
this.fnPlugin.add(items);
}
}

export function createServer(cfg?: IIndexServerConfig) {
const rpc = new RpcServer(mergeDeep({ fn: {} }, cfg));
const fn = new Fn(mergeDeep({}, cfg.fn));
rpc.plugin(fn);

return mergeDeep(rpc, {
base: '.',
init: rpc['config']['hooks']['init'],
before: rpc['config']['hooks']['before'],
load: rpc['config']['hooks']['load'],
after: rpc['config']['hooks']['after'],
fn: function (key, fun) {
log('use rpc.fn add fn =' + key);
fn.fn(key, fun);
},
add: function (items) {
log('use rpc.add add fn =' + items);
fn.add(items);
},
});
return new RpcServer(mergeDeep({ fn: {} }, cfg));
}
Loading

0 comments on commit bcb3d7c

Please sign in to comment.