Skip to content

Commit

Permalink
feat: Trigger 支持 IoC ExecutionContainer (#19)
Browse files Browse the repository at this point in the history
* feat(trigger): support execution container

* chore: add todo remark

* chore: update pipeline
  • Loading branch information
noahziheng authored Apr 11, 2022
1 parent 52ad74b commit 20f3446
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 28 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "lib/index.js",
"scripts": {
"build": "tsc",
"test": "jest",
"test": "jest --detectOpenHandles",
"ci": "npm run test"
},
"repository": {
Expand All @@ -32,7 +32,7 @@
},
"dependencies": {
"@artus/injection": "^0.1.1",
"@artus/pipeline": "^0.1.2",
"@artus/pipeline": "^0.1.6",
"deepmerge": "^4.2.2",
"js-yaml": "^4.1.0"
},
Expand Down
5 changes: 5 additions & 0 deletions src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ export class ArtusApplication implements Application {
return this.container.get(ArtusInjectEnum.Trigger);
}

// 兜底方法,不建议对外部使用
getContainer(): Container {
return this.container;
}

async loadDefaultClass() {
// load Artus default clazz
this.container.set({ id: ArtusInjectEnum.Application, value: this });
Expand Down
14 changes: 12 additions & 2 deletions src/trigger/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { Input, Context, MiddlewareInput, Pipeline } from '@artus/pipeline';
import { Inject } from '@artus/injection';
import { Input, Context, MiddlewareInput, Pipeline, Output } from '@artus/pipeline';
import { ArtusInjectEnum } from '../constraints';
import { Application } from '../types';
import { DefineTrigger } from './decorator';

@DefineTrigger()
export default class Trigger {
private pipeline: Pipeline;

@Inject(ArtusInjectEnum.Application)
// @ts-ignore
private app: Application;

constructor() {
this.pipeline = new Pipeline();
Expand All @@ -15,7 +22,10 @@ export default class Trigger {
}

async initContext(input: Input): Promise<Context> {
return new Context(input);
return new Context(input, new Output(), {
// SEEME: need replace to injection provided container getter way in future.
parentContainer: this.app.getContainer()
});
}

async startPipeline(input: Input = new Input()): Promise<Context> {
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Container } from '@artus/injection';
import { HookFunction } from './lifecycle';
import { Manifest } from './loader';
import Trigger from './trigger';
Expand All @@ -24,6 +25,9 @@ export interface Application {
load(manifest: Manifest): Promise<this>;
run(): Promise<void>;
registerHook(hookName: string, hookFn: HookFunction): void;

// 兜底方法,不建议使用
getContainer(): Container;
}

export * from './loader/types';
22 changes: 14 additions & 8 deletions test/app.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ describe('test/app.test.ts', () => {
describe('app koa with ts', () => {
it('should run app', async () => {
// Skip Controller
const TestController = await import('./fixtures/app-koa-with-ts/src/controllers/test');
assert(TestController);
expect(await new TestController.default().index()).toStrictEqual({
const HelloController = await import('./fixtures/app-koa-with-ts/src/controllers/hello');
assert(HelloController);
expect(await new HelloController.default().index()).toStrictEqual({
content: 'Hello Artus',
status: 200
status: 200,
headers: {}
});

try {
Expand All @@ -19,11 +20,16 @@ describe('test/app.test.ts', () => {
isListening
} = await import('./fixtures/app-koa-with-ts/src/bootstrap');
const app = await main();
const testResponse = await axios.get('http://127.0.0.1:3000');
assert(testResponse.status === 200);
assert(testResponse.data === 'Hello Artus');
const testResponse = await axios.get('http://127.0.0.1:3000', {
headers: {
'x-hello-artus': 'true'
}
});
expect(testResponse.status).toBe(200);
expect(testResponse.data).toBe('Hello Artus');
expect(testResponse.headers?.['x-hello-artus']).toBe('true');
await app.close();
assert(!isListening());
expect(isListening()).toBeFalsy();
} catch (error) {
throw error;
}
Expand Down
6 changes: 4 additions & 2 deletions test/fixtures/app-koa-with-ts/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ApplicationExtension, ApplicationHook, WithApplication, WithContainer }
import { ApplicationLifecycle } from '../../../../src/types';

import KoaApplication from './koaApp';
import TestController from './controllers/test';
import HelloController from './controllers/hello';

export let server: Server;

Expand All @@ -29,7 +29,9 @@ export class ApplicationHookExtension implements ApplicationLifecycle {
@ApplicationHook()
async didLoad() {
this.app.trigger.use(async (ctx: Context) => {
ctx.output.data = await this.container.get(TestController).index();
const { koaCtx } = ctx.input.params;
ctx.container.set({ id: 'headers', value: koaCtx.headers });
ctx.output.data = await ctx.container.get(HelloController).index();
});
}

Expand Down
6 changes: 5 additions & 1 deletion test/fixtures/app-koa-with-ts/src/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ async function main() {
},
{
loader: 'module',
path: path.resolve(__dirname, './controllers/test')
path: path.resolve(__dirname, './controllers/hello')
},
{
loader: 'module',
path: path.resolve(__dirname, './services/hello')
}
]
});
Expand Down
23 changes: 23 additions & 0 deletions test/fixtures/app-koa-with-ts/src/controllers/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'reflect-metadata';
import { Inject, Injectable, ScopeEnum } from '@artus/injection';
import TestService from '../services/hello';

// TODO: 待实现 Controller/Route 装饰器
@Injectable({
scope: ScopeEnum.EXECUTION
})
export default class HelloController {
@Inject(TestService)
// @ts-ignore
helloService: HelloService;

async index () {
return {
status: 200,
content: 'Hello Artus',
headers: {
...this.helloService?.getTestHeaders()
}
};
}
}
13 changes: 0 additions & 13 deletions test/fixtures/app-koa-with-ts/src/controllers/test.ts

This file was deleted.

3 changes: 3 additions & 0 deletions test/fixtures/app-koa-with-ts/src/httpTrigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@ export default class HttpTrigger extends Trigger {

koaCtx.status = data.status || 200;
koaCtx.body = data.content;
for (const [k, v] of Object.entries(data.headers)) {
koaCtx.set(k, v);
}
}
}
17 changes: 17 additions & 0 deletions test/fixtures/app-koa-with-ts/src/services/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'reflect-metadata';
import { Inject, Injectable, ScopeEnum } from '@artus/injection';

@Injectable({
scope: ScopeEnum.EXECUTION
})
export default class HelloService {
@Inject('headers')
// @ts-ignore
headers: Record<string, any>;

public getTestHeaders() {
return {
['x-hello-artus']: this.headers['x-hello-artus']
};
}
}

0 comments on commit 20f3446

Please sign in to comment.