diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 2b898b35..e0e4bc4e 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -81,16 +81,24 @@ importers: ../../packages/libs/core: specifiers: + '@artus/core': ^2.x + '@artus/pipeline': ^0.2 '@artus/tsconfig': ^1.0.1 '@artusx/plugin-application-http': workspace:* + '@koa/cors': ~5.0.0 + '@types/koa__cors': ~5.0.0 '@types/node': ^18.11.17 ts-node: ^10.9.1 tslib: ^2.5.0 typescript: ^4.9.4 dependencies: + '@artus/core': 2.2.0 + '@artus/pipeline': 0.2.3 '@artusx/plugin-application-http': link:../../plugins/application-http + '@koa/cors': 5.0.0 devDependencies: '@artus/tsconfig': 1.0.1_@types+node@18.19.4 + '@types/koa__cors': 5.0.0 '@types/node': 18.19.4 ts-node: 10.9.2_rjts7x5ipcoasow4czzl2kffka tslib: 2.6.2 @@ -120,10 +128,8 @@ importers: '@artus/core': ^2.x '@artus/pipeline': ^0.2 '@artus/tsconfig': ^1.0.1 - '@koa/cors': ^5.0.0 '@koa/router': ^12.0.1 '@types/koa': ^2.13.12 - '@types/koa__cors': ^5.0.0 '@types/koa__router': ^12.0.4 '@types/node': ^18.11.17 koa: ^2.15.0 @@ -132,13 +138,11 @@ importers: dependencies: '@artus/core': 2.2.0 '@artus/pipeline': 0.2.3 - '@koa/cors': 5.0.0 '@koa/router': 12.0.1 koa: 2.15.0 devDependencies: '@artus/tsconfig': 1.0.1_@types+node@18.19.4 '@types/koa': 2.13.12 - '@types/koa__cors': 5.0.0 '@types/koa__router': 12.0.4 '@types/node': 18.19.4 tslib: 2.6.2 diff --git a/packages/apps/artusx-api/src/app/config/config.default.ts b/packages/apps/artusx-api/src/app/config/config.default.ts index 0f9724be..50ac077c 100644 --- a/packages/apps/artusx-api/src/app/config/config.default.ts +++ b/packages/apps/artusx-api/src/app/config/config.default.ts @@ -6,8 +6,14 @@ import checkAuth from '../middleware/checkAuth'; dotenv.config(); export default { - port: 7001, - middlewares: [checkAuth], + koa: { + port: 7001 + // middlewares: [] + }, + + artusx: { + middlewares: [checkAuth] + }, redis: { db: process.env.REDIS_DATABASE || 0, diff --git a/packages/apps/artusx-api/src/app/middleware/checkAuth.ts b/packages/apps/artusx-api/src/app/middleware/checkAuth.ts index 82ef3aeb..716924fa 100644 --- a/packages/apps/artusx-api/src/app/middleware/checkAuth.ts +++ b/packages/apps/artusx-api/src/app/middleware/checkAuth.ts @@ -2,6 +2,7 @@ import { Context, Next } from '@artus/pipeline'; export default async function checkAuth(ctx: Context, next: Next): Promise { const { data } = ctx.output; + data.authed = false; console.log('middleware - checkAuth', data); await next(); } diff --git a/packages/libs/core/package.json b/packages/libs/core/package.json index 9ec077ea..199280ba 100644 --- a/packages/libs/core/package.json +++ b/packages/libs/core/package.json @@ -17,18 +17,21 @@ "author": "Suyi ", "license": "MIT", "dependencies": { - "@artusx/plugin-application-http": "workspace:*" + "@artus/core": "^2.x", + "@artus/pipeline": "^0.2", + "@artusx/plugin-application-http": "workspace:*", + "@koa/cors": "~5.0.0" }, "peerDependencies": { - "@artus/core": "^2.x", - "@artus/pipeline": "^0.2" + "reflect-metadata": "^0.1.13" }, "devDependencies": { "@artus/tsconfig": "^1.0.1", "@types/node": "^18.11.17", "ts-node": "^10.9.1", "tslib": "^2.5.0", - "typescript": "^4.9.4" + "typescript": "^4.9.4", + "@types/koa__cors": "~5.0.0" }, "publishConfig": { "access": "public" diff --git a/packages/libs/core/src/app.ts b/packages/libs/core/src/app.ts index ff8b4c56..d43babe3 100644 --- a/packages/libs/core/src/app.ts +++ b/packages/libs/core/src/app.ts @@ -1 +1,33 @@ -export default {}; +import { + Inject, + ArtusInjectEnum, + ArtusApplication, + ApplicationLifecycle, + LifecycleHook, + LifecycleHookUnit +} from '@artus/core'; + +import cors from '@koa/cors'; +import KoaApplication from '@artusx/plugin-application-http/lib/koa/application'; + +@LifecycleHookUnit() +export default class ArtusXCoreLifecycle implements ApplicationLifecycle { + @Inject(ArtusInjectEnum.Application) + private readonly app: ArtusApplication; + + get koa(): KoaApplication { + return this.app.container.get(KoaApplication); + } + + @LifecycleHook() + async didLoad() { + this.koa.use( + cors({ + credentials: true, + origin(ctx) { + return ctx.get('Origin') || 'localhost'; + } + }) + ); + } +} diff --git a/packages/libs/core/src/config/config.default.ts b/packages/libs/core/src/config/config.default.ts index 5fdec0ab..b36ea75d 100644 --- a/packages/libs/core/src/config/config.default.ts +++ b/packages/libs/core/src/config/config.default.ts @@ -1,4 +1,5 @@ export default { - port: 7001, - middlewares: [] + koa: { + port: 7001 + } }; diff --git a/packages/libs/utils/src/constants.ts b/packages/libs/utils/src/constants.ts new file mode 100644 index 00000000..f18de1be --- /dev/null +++ b/packages/libs/utils/src/constants.ts @@ -0,0 +1,11 @@ +export enum ArtusXInjectEnum { + // application-http + Koa = 'ARTUSX_KOA', + Pipeline = 'ARTUSX_PIPELINE', + + // redis + Redis = 'ARTUSX_REDIS', + + // sequelize + Sequelize = 'ARTUSX_SEQUELIZE' +} diff --git a/packages/plugins/application-http/package.json b/packages/plugins/application-http/package.json index bcce85f1..218c5cfe 100644 --- a/packages/plugins/application-http/package.json +++ b/packages/plugins/application-http/package.json @@ -18,7 +18,6 @@ "author": "Suyi ", "license": "MIT", "dependencies": { - "@koa/cors": "^5.0.0", "@koa/router": "^12.0.1", "koa": "^2.15.0", "@artus/core": "^2.x", @@ -30,7 +29,6 @@ "devDependencies": { "@artus/tsconfig": "^1.0.1", "@types/koa": "^2.13.12", - "@types/koa__cors": "^5.0.0", "@types/koa__router": "^12.0.4", "@types/node": "^18.11.17", "tslib": "^2.5.0", diff --git a/packages/plugins/application-http/src/config/config.default.ts b/packages/plugins/application-http/src/config/config.default.ts index 5fdec0ab..fd8aaca4 100644 --- a/packages/plugins/application-http/src/config/config.default.ts +++ b/packages/plugins/application-http/src/config/config.default.ts @@ -1,4 +1,10 @@ export default { - port: 7001, - middlewares: [] + artusx: { + middlewares: [] + }, + + koa: { + port: 7001, + middlewares: [] + } }; diff --git a/packages/plugins/application-http/src/constants.ts b/packages/plugins/application-http/src/constants.ts new file mode 100644 index 00000000..3988a8c4 --- /dev/null +++ b/packages/plugins/application-http/src/constants.ts @@ -0,0 +1,5 @@ +export enum ArtusXInjectEnum { + Koa = 'ARTUSX_KOA', + KoaRouter = 'ARTUSX_KOA_ROUTER', + Pipeline = 'ARTUSX_PIPELINE' +} diff --git a/packages/plugins/application-http/src/koa/application.ts b/packages/plugins/application-http/src/koa/application.ts new file mode 100644 index 00000000..1bbc638e --- /dev/null +++ b/packages/plugins/application-http/src/koa/application.ts @@ -0,0 +1,9 @@ +import Koa from 'koa'; +import { Injectable, ScopeEnum } from '@artus/core'; +import { ArtusXInjectEnum } from '../constants'; + +@Injectable({ + id: ArtusXInjectEnum.Koa, + scope: ScopeEnum.SINGLETON +}) +export default class KoaApplication extends Koa {} diff --git a/packages/plugins/application-http/src/koa/router.ts b/packages/plugins/application-http/src/koa/router.ts new file mode 100644 index 00000000..a889bbc1 --- /dev/null +++ b/packages/plugins/application-http/src/koa/router.ts @@ -0,0 +1,9 @@ +import Router from '@koa/router'; +import { Injectable, ScopeEnum } from '@artus/core'; +import { ArtusXInjectEnum } from '../constants'; + +@Injectable({ + id: ArtusXInjectEnum.KoaRouter, + scope: ScopeEnum.SINGLETON +}) +export default class KoaRouter extends Router {} diff --git a/packages/plugins/application-http/src/lifecycle.ts b/packages/plugins/application-http/src/lifecycle.ts index 8387a429..58fd18d8 100644 --- a/packages/plugins/application-http/src/lifecycle.ts +++ b/packages/plugins/application-http/src/lifecycle.ts @@ -1,7 +1,5 @@ import path from 'path'; -import Koa from 'koa'; -import cors from '@koa/cors'; -import Router from '@koa/router'; +import { Server } from 'http'; import { Inject, @@ -16,7 +14,7 @@ import { Input, Context } from '@artus/pipeline'; import { CONTROLLER_METADATA, MIDDLEWARE_METADATA, ROUTER_METADATA, WEB_CONTROLLER_TAG } from './decorator'; -import HttpPipeline from './pipeline'; +import Pipeline from './pipeline'; import type { ControllerMetadata, @@ -26,15 +24,20 @@ import type { RouteMetadata } from './types'; +import KoaRouter from './koa/router'; +import KoaApplication from './koa/application'; + +import type { Middleware as KoaMiddleware } from 'koa'; + +export let server: Server; + @LifecycleHookUnit() export default class ApplicationHttpLifecycle implements ApplicationLifecycle { @Inject(ArtusInjectEnum.Application) private readonly app: ArtusApplication; @Inject() - pipeline: HttpPipeline; - - private router = new Router(); + pipeline: Pipeline; get container() { return this.app.container; @@ -44,6 +47,14 @@ export default class ApplicationHttpLifecycle implements ApplicationLifecycle { return this.app.logger; } + get router(): KoaRouter { + return this.app.container.get(KoaRouter); + } + + get koa(): KoaApplication { + return this.app.container.get(KoaApplication); + } + private registerRoute( controllerMetadata: ControllerMetadata, routeMetadataList: RouteMetadata[], @@ -104,29 +115,29 @@ export default class ApplicationHttpLifecycle implements ApplicationLifecycle { @LifecycleHook() async didLoad() { - const middlewares = this.app.config.middlewares || []; - this.pipeline.use(middlewares); + const ArtusXMiddlewares = this.app.config.artusx.middlewares || []; + this.pipeline.use(ArtusXMiddlewares); + + const koaMiddlewares: KoaMiddleware[] = this.app.config.koa.middlewares || []; + koaMiddlewares.map((middleware) => { + this.koa.use(middleware); + }); } @LifecycleHook() public async willReady() { this.loadController(); + const port = this.app.config.koa.port || 7001; - const app = new Koa(); - const port = this.app.config.port || 7001; - - app.use( - cors({ - credentials: true, - origin(ctx) { - return ctx.get('Origin') || 'localhost'; - } - }) - ); - - app.use(this.router.routes()); - app.listen(port, () => { + this.koa.use(this.router.routes()); + server = this.koa.listen(port, () => { this.logger.info(`Server listening on: http://localhost:${port}`); }); } + + @LifecycleHook() + beforeClose() { + this.logger.info('Server closing...'); + server?.close(); + } } diff --git a/packages/plugins/application-http/src/pipeline.ts b/packages/plugins/application-http/src/pipeline.ts index ef4d5a0d..2092d333 100644 --- a/packages/plugins/application-http/src/pipeline.ts +++ b/packages/plugins/application-http/src/pipeline.ts @@ -1,8 +1,12 @@ import { Pipeline, Context, Next } from '@artus/pipeline'; import { Injectable, ScopeEnum } from '@artus/core'; +import { ArtusXInjectEnum } from './constants'; -@Injectable({ scope: ScopeEnum.SINGLETON }) -export default class HttpPipeline extends Pipeline { +@Injectable({ + id: ArtusXInjectEnum.Pipeline, + scope: ScopeEnum.SINGLETON +}) +export default class ArtusPipeline extends Pipeline { constructor() { super(); diff --git a/packages/plugins/redis/src/app.ts b/packages/plugins/redis/src/app.ts index c6e6ff35..e34d5351 100644 --- a/packages/plugins/redis/src/app.ts +++ b/packages/plugins/redis/src/app.ts @@ -1,12 +1,9 @@ -import { Server } from 'http'; import { LifecycleHookUnit, LifecycleHook } from '@artus/core'; import { ApplicationLifecycle } from '@artus/core'; import { ArtusApplication, Inject, ArtusInjectEnum } from '@artus/core'; - +import { ArtusXInjectEnum } from './constants'; import Redis, { RedisConfig } from './client'; -export let server: Server; - @LifecycleHookUnit() export default class RedisLifecycle implements ApplicationLifecycle { @Inject(ArtusInjectEnum.Application) @@ -14,7 +11,7 @@ export default class RedisLifecycle implements ApplicationLifecycle { @LifecycleHook() async willReady() { - const redis = this.app.container.get('ARTUS_REDIS') as Redis; + const redis = this.app.container.get(ArtusXInjectEnum.Redis) as Redis; await redis.init(this.app.config.redis as RedisConfig); } } diff --git a/packages/plugins/redis/src/client.ts b/packages/plugins/redis/src/client.ts index 7afeb3e8..044ef8ba 100644 --- a/packages/plugins/redis/src/client.ts +++ b/packages/plugins/redis/src/client.ts @@ -1,5 +1,6 @@ import { Injectable, ScopeEnum } from '@artus/core'; import { Redis, RedisOptions } from 'ioredis'; +import { ArtusXInjectEnum } from './constants'; export interface RedisConfig extends RedisOptions { host: string; @@ -10,7 +11,7 @@ export interface RedisConfig extends RedisOptions { } @Injectable({ - id: 'ARTUS_REDIS', + id: ArtusXInjectEnum.Redis, scope: ScopeEnum.SINGLETON }) export default class Client { diff --git a/packages/plugins/redis/src/constants.ts b/packages/plugins/redis/src/constants.ts new file mode 100644 index 00000000..bad35cf8 --- /dev/null +++ b/packages/plugins/redis/src/constants.ts @@ -0,0 +1,3 @@ +export enum ArtusXInjectEnum { + Redis = 'ARTUSX_REDIS' +} diff --git a/packages/plugins/sequelize/src/app.ts b/packages/plugins/sequelize/src/app.ts index 926aaf36..51826f5f 100644 --- a/packages/plugins/sequelize/src/app.ts +++ b/packages/plugins/sequelize/src/app.ts @@ -1,7 +1,7 @@ import { LifecycleHookUnit, LifecycleHook } from '@artus/core'; import { ApplicationLifecycle } from '@artus/core'; import { ArtusApplication, Inject, ArtusInjectEnum } from '@artus/core'; - +import { ArtusXInjectEnum } from './constants'; import Sequelize, { SequelizeConfig } from './client'; @LifecycleHookUnit() @@ -11,7 +11,7 @@ export default class SequelizeLifecycle implements ApplicationLifecycle { @LifecycleHook() async willReady() { - const sequelize = this.app.container.get('ARTUS_SEQUELIZE') as Sequelize; + const sequelize = this.app.container.get(ArtusXInjectEnum.Sequelize) as Sequelize; await sequelize.init(this.app.config.sequelize as SequelizeConfig); } } diff --git a/packages/plugins/sequelize/src/client.ts b/packages/plugins/sequelize/src/client.ts index 4af0a6f6..453bf869 100644 --- a/packages/plugins/sequelize/src/client.ts +++ b/packages/plugins/sequelize/src/client.ts @@ -1,5 +1,6 @@ import { Injectable, ScopeEnum } from '@artus/core'; import { Sequelize, SequelizeOptions } from 'sequelize-typescript'; +import { ArtusXInjectEnum } from './constants'; export interface SequelizeConfig extends SequelizeOptions { database: string; @@ -11,7 +12,7 @@ export interface SequelizeConfig extends SequelizeOptions { } @Injectable({ - id: 'ARTUS_SEQUELIZE', + id: ArtusXInjectEnum.Sequelize, scope: ScopeEnum.SINGLETON }) export default class Client { diff --git a/packages/plugins/sequelize/src/constants.ts b/packages/plugins/sequelize/src/constants.ts new file mode 100644 index 00000000..92b24c6d --- /dev/null +++ b/packages/plugins/sequelize/src/constants.ts @@ -0,0 +1,3 @@ +export enum ArtusXInjectEnum { + Sequelize = 'ARTUSX_SEQUELIZE' +}