Skip to content

Commit

Permalink
feat: support specific framework & plugin in scanner (#158)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyj1991 authored Aug 2, 2022
1 parent df834fc commit e42f6bf
Show file tree
Hide file tree
Showing 29 changed files with 383 additions and 4 deletions.
11 changes: 7 additions & 4 deletions src/scanner/scan.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'reflect-metadata';
import * as path from 'path';
import * as fs from 'fs/promises';
import deepmerge from 'deepmerge';
import { Container } from '@artus/injection';
import {
ArtusInjectEnum,
Expand All @@ -16,7 +17,7 @@ import ConfigurationHandler, { ConfigObject } from '../configuration';
import { FrameworkConfig, FrameworkHandler } from '../framework';
import { BasePlugin, PluginFactory } from '../plugin';
import { ScanUtils } from './utils';
import { PluginMetadata } from '../plugin/types';
import { PluginConfigItem, PluginMetadata } from '../plugin/types';
import { getConfigMetaFromFilename } from '../loader/utils/config_file_meta';

export class Scanner {
Expand Down Expand Up @@ -95,7 +96,8 @@ export class Scanner {
const config = await this.getAllConfig(root, env);

// 2. scan all file in framework
const frameworkDirs = await this.getFrameworkDirs(config.framework, root, env);
const frameworkConfig = this.options.framework ?? config.framework;
const frameworkDirs = await this.getFrameworkDirs(frameworkConfig, root, env);
for (const frameworkDir of frameworkDirs) {
await this.walk(frameworkDir, this.formatWalkOptions('framework', frameworkDir));
}
Expand All @@ -107,7 +109,8 @@ export class Scanner {
configList.forEach(config => this.configHandle.setConfig(env, config));
}
const { plugin } = this.configHandle.getMergedConfig(env);
const pluginSortedList = await PluginFactory.createFromConfig(plugin || {});
const pluginConfig = deepmerge.all([plugin || {}, this.options.plugin || {}]) as Record<string, PluginConfigItem>;
const pluginSortedList = await PluginFactory.createFromConfig(pluginConfig);
for (const plugin of pluginSortedList) {
if (!plugin.enable) continue;
this.setPluginMeta(plugin);
Expand Down Expand Up @@ -153,7 +156,7 @@ export class Scanner {
const container = new Container(ArtusInjectEnum.DefaultContainerName);
container.set({ type: ConfigurationHandler });
const loaderFactory = LoaderFactory.create(container);
const configItemList: (ManifestItem|null)[] = await Promise.all(configFileList.map(async filename => {
const configItemList: (ManifestItem | null)[] = await Promise.all(configFileList.map(async filename => {
const extname = path.extname(filename);
if (ScanUtils.isExclude(filename, extname, this.options.exclude, this.options.extensions)) {
return null;
Expand Down
4 changes: 4 additions & 0 deletions src/scanner/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { BaseLoader, ManifestItem } from "../loader";
import { FrameworkConfig } from "../framework";
import { PluginConfigItem } from "../plugin/types";

export interface ScannerOptions {
appName: string;
Expand All @@ -8,6 +10,8 @@ export interface ScannerOptions {
exclude: string[];
configDir: string;
envs?: string[];
framework?: FrameworkConfig;
plugin?: Record<string, Partial<PluginConfigItem>>;
loaderListGenerator: (defaultLoaderList: string[]) => (string | typeof BaseLoader)[];
}

Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/application_specific/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "application-specific"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const name = 'from application';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const name = 'from application <private>';
16 changes: 16 additions & 0 deletions test/fixtures/application_specific/src/config/plugin.default.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import path from 'path';

export default {
mysql: {
enable: true,
path: path.resolve(__dirname, '../plugins/artus_plugin_mysql_rds'),
},
redis: {
enable: true,
path: path.resolve(__dirname, '../plugins/artus_plugin_redis'),
},
base: {
enable: true,
path: path.resolve(__dirname, '../plugins/artus_plugin_base'),
},
};
17 changes: 17 additions & 0 deletions test/fixtures/application_specific/src/controller/conifg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Context } from '@artus/pipeline';
import { HttpController, HttpMethod, HTTPMethodEnum } from '../../../frameworks/bar/src';

@HttpController()
export default class Hello {
@HttpMethod({
method: HTTPMethodEnum.GET,
path: '/config',
})
async index(ctx: Context) {
const { params: { config } } = ctx.input;
return {
message: `get conifg succeed`,
config,
};
}
}
32 changes: 32 additions & 0 deletions test/fixtures/application_specific/src/controller/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Context } from '@artus/pipeline';
import { HttpController, HttpMethod, HTTPMethodEnum } from '../../../frameworks/bar/src';

@HttpController()
export default class Hello {
@HttpMethod({
method: HTTPMethodEnum.GET,
path: '/home',
})
async index(ctx: Context) {
const { params: { config } } = ctx.input;
return { title: `Hello Artus ${config.name}` };
}

@HttpMethod({
method: HTTPMethodEnum.GET,
path: '/get_name2',
})
async name2(ctx: Context) {
const { params: { config } } = ctx.input;
return { title: `Hello Artus ${config.name2}` };
}

@HttpMethod({
method: HTTPMethodEnum.GET,
path: '/get_name3',
})
async name3(ctx: Context) {
const { params: { config } } = ctx.input;
return { title: `Hello Artus ${config.name3}` };
}
}
39 changes: 39 additions & 0 deletions test/fixtures/application_specific/src/controller/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { HttpController, HttpMethod, HTTPMethodEnum } from '../../../frameworks/bar/src';
import { Inject } from '@artus/injection';
import { ArtusApplication } from '../../../../../src';
import { Context } from '@artus/pipeline';

@HttpController()
export default class Hello {
@Inject('ARTUS_MYSQL')
private client: any;

@HttpMethod({
method: HTTPMethodEnum.GET,
path: '/plugin-mysql',
})
async getMysqlClient() {
return {
client: await this.client.getClient(),
};
}

@HttpMethod({
method: HTTPMethodEnum.GET,
path: '/plugin-redis',
})
async getRedisClient(ctx: Context) {
const app: ArtusApplication = ctx.input.params.app;
let client;
try {
client = app.container.get('ARTUS_REDIS');
} catch {

}

const result = client ? {
client: await client.getClient(),
} : { message: 'plugin redis not enabled' };
return result;
}
}
33 changes: 33 additions & 0 deletions test/fixtures/application_specific/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import path from 'path';
import { Manifest, ArtusApplication, ArtusInjectEnum } from "../../../../src";
import { AbstractBar } from '../../frameworks/bar/src';
import { Inject, Injectable } from "@artus/injection";

@Injectable()
export default class MyArtusApplication {
@Inject('ABSTRACT_BAR')
private bar: AbstractBar;
@Inject(ArtusInjectEnum.Application)
public artus: ArtusApplication;

static async instance(manifest: Manifest): Promise<MyArtusApplication> {
const app = new ArtusApplication();
await app.load(manifest, path.join(__dirname, '..'));
const instance = app.container.get(MyArtusApplication);
return instance;
}

isListening(): boolean {
return this.bar.isListening();
}

async run() {
await this.artus.run();
}
}

export async function main(manifest: Manifest) {
const app = await MyArtusApplication.instance(manifest);
await app.run();
return app;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "base"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@artus/plugin-base"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default {
mysql: {
clientName: 'mysql-ob-base',
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "mysql",
"configDir": "src/custom_config",
"dependencies": [
{
"name": "base"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@artus/plugin-mysql-ob"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Server } from 'http';
import { LifecycleHookUnit, LifecycleHook } from '../../../../../../../src/decorator';
import { ApplicationLifecycle } from '../../../../../../../src/types';
import { ArtusApplication, Inject, ArtusInjectEnum } from '../../../../../../../src';
import Client, { MysqlConfig } from './client';

export let server: Server;

@LifecycleHookUnit()
export default class MyLifecycle implements ApplicationLifecycle {
@Inject(ArtusInjectEnum.Application)
app: ArtusApplication;

@LifecycleHook()
async willReady() {
const mysql = this.app.container.get('ARTUS_MYSQL') as Client;
await mysql.init(this.app.config.mysql as MysqlConfig);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Injectable } from "@artus/injection";

export interface MysqlConfig {
clientName: string
}

@Injectable({
id: 'ARTUS_MYSQL',
})
export default class Client {
private clientName = '';

async init(config: MysqlConfig) {
this.clientName = config.clientName;
}

async getClient(): Promise<string> {
return this.clientName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default {
mysql: {
clientName: 'mysql-ob',
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "mysql"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@artus/plugin-mysql-rds"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Server } from 'http';
import { LifecycleHookUnit, LifecycleHook } from '../../../../../../../src/decorator';
import { ApplicationLifecycle } from '../../../../../../../src/types';
import { ArtusApplication, Inject, ArtusInjectEnum } from '../../../../../../../src';
import Client, { MysqlConfig } from './client';

export let server: Server;

@LifecycleHookUnit()
export default class MyLifecycle implements ApplicationLifecycle {
@Inject(ArtusInjectEnum.Application)
app: ArtusApplication;

@LifecycleHook()
async willReady() {
const mysql = this.app.container.get('ARTUS_MYSQL') as Client;
await mysql.init(this.app.config.mysql as MysqlConfig);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Injectable } from "@artus/injection";

export interface MysqlConfig {
clientName: string
}

@Injectable({
id: 'ARTUS_MYSQL',
})
export default class Client {
private clientName = '';

async init(config: MysqlConfig) {
this.clientName = config.clientName;
}

async getClient(): Promise<string> {
return this.clientName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default {
mysql: {
clientName: 'mysql-rds',
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "redis"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@artus/plugin-redis"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Server } from 'http';
import { LifecycleHookUnit, LifecycleHook } from '../../../../../../../src/decorator';
import { ApplicationLifecycle } from '../../../../../../../src/types';
import { ArtusApplication, Inject, ArtusInjectEnum } from '../../../../../../../src';
import Client, { RedisConfig } from './client';

export let server: Server;

@LifecycleHookUnit()
export default class MyLifecycle implements ApplicationLifecycle {
@Inject(ArtusInjectEnum.Application)
app: ArtusApplication;

@LifecycleHook()
async willReady() {
const redis = this.app.container.get('ARTUS_REDIS') as Client;
await redis.init(this.app.config.redis as RedisConfig);
}
}
Loading

0 comments on commit e42f6bf

Please sign in to comment.