enhancement() add loader function to load package utility

This commit is contained in:
Kamil Myśliwiec
2019-01-30 23:07:34 +01:00
parent b0de7ce6f3
commit e4179eb380
24 changed files with 1150 additions and 62 deletions

1
.gitignore vendored
View File

@@ -28,4 +28,5 @@ yarn-error.log
/test
/coverage
/.nyc_output
/benchmarks/memory
build/config\.gypi

1063
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -90,6 +90,7 @@
"@types/sinon": "^1.16.36",
"@types/socket.io": "^1.4.32",
"@types/ws": "^4.0.1",
"artillery": "^1.6.0-26",
"awesome-typescript-loader": "^3.0.0-beta.18",
"body-parser": "^1.18.3",
"chai": "^3.5.0",
@@ -99,6 +100,7 @@
"conventional-changelog": "^1.1.15",
"core-js": "^2.4.1",
"coveralls": "^2.11.16",
"csv-write-stream": "^2.0.0",
"delete-empty": "^2.0.0",
"fastify-static": "^0.8.0",
"gulp": "^4.0.0",
@@ -113,6 +115,7 @@
"json-loader": "^0.5.4",
"lerna": "^2.5.1",
"lint-staged": "^7.2.2",
"memory-usage": "^1.2.1",
"mocha": "^3.2.0",
"nodemon": "^1.18.4",
"nyc": "^10.1.2",
@@ -123,7 +126,7 @@
"supertest": "^3.0.0",
"ts-node": "^7.0.1",
"tslint": "^5.11.0",
"typescript": "^3.2.2"
"typescript": "^3.2.4"
},
"collective": {
"type": "opencollective",

View File

@@ -8,7 +8,9 @@ export function createCacheManager(): Provider {
return {
provide: CACHE_MANAGER,
useFactory: (options: CacheManagerOptions) => {
const cacheManager = loadPackage('cache-manager', 'CacheModule');
const cacheManager = loadPackage('cache-manager', 'CacheModule', () =>
require('cache-manager'),
);
const memoryCache = cacheManager.caching({
...defaultCacheOptions,
...(options || {}),

View File

@@ -39,9 +39,12 @@ export class ValidationPipe implements PipeTransform<any> {
this.isDetailedOutputDisabled ? undefined : errors,
));
const loadPkg = (pkg: any) => loadPackage(pkg, 'ValidationPipe');
classValidator = loadPkg('class-validator');
classTransformer = loadPkg('class-transformer');
classValidator = loadPackage('class-validator', 'ValidationPipe', () =>
require('class-validator'),
);
classTransformer = loadPackage('class-transformer', 'ValidationPipe', () =>
require('class-transformer'),
);
}
public async transform(value: any, metadata: ArgumentMetadata) {

View File

@@ -25,9 +25,11 @@ const REFLECTOR = 'Reflector';
@Injectable()
export class ClassSerializerInterceptor implements NestInterceptor {
constructor(@Inject(REFLECTOR) protected readonly reflector: any) {
const loadPkg = (pkg: any) =>
loadPackage(pkg, 'ClassSerializerInterceptor');
classTransformer = loadPkg('class-transformer');
classTransformer = loadPackage(
'class-transformer',
'ClassSerializerInterceptor',
() => require('class-transformer'),
);
require('class-transformer');
}

View File

@@ -5,9 +5,13 @@ const MISSING_REQUIRED_DEPENDENCY = (name: string, reason: string) =>
const logger = new Logger('PackageLoader');
export function loadPackage(packageName: string, context: string) {
export function loadPackage(
packageName: string,
context: string,
loaderFn?: Function,
) {
try {
return require(packageName);
return loaderFn ? loaderFn() : require(packageName);
} catch (e) {
logger.error(MISSING_REQUIRED_DEPENDENCY(packageName, context));
process.exit(1);

View File

@@ -149,9 +149,10 @@ export class NestApplication extends NestApplicationContext
}
public connectMicroservice(options: MicroserviceOptions): INestMicroservice {
const { NestMicroservice } = this.loadPackage(
const { NestMicroservice } = loadPackage(
'@nestjs/microservices',
'NestFactory',
() => require('@nestjs/microservices'),
);
const applicationConfig = new ApplicationConfig();
@@ -281,10 +282,6 @@ export class NestApplication extends NestApplicationContext
return this;
}
private loadPackage<T = any>(name: string, ctx: string): T {
return loadPackage(name, ctx) as T;
}
private async registerMiddleware(instance: any) {
await this.middlewareModule.registerMiddleware(
this.middlewareContainer,

View File

@@ -77,6 +77,7 @@ export class NestFactoryStatic {
const { NestMicroservice } = loadPackage(
'@nestjs/microservices',
'NestFactory',
() => require('@nestjs/microservices'),
);
const applicationConfig = new ApplicationConfig();
const container = new NestContainer(applicationConfig);

View File

@@ -28,7 +28,9 @@ export class ClientGrpcProxy extends ClientProxy implements ClientGrpc {
this.getOptionsProp<GrpcOptions>(options, 'protoLoader') ||
GRPC_DEFAULT_PROTO_LOADER;
grpcPackage = loadPackage('grpc', ClientGrpcProxy.name);
grpcPackage = loadPackage('grpc', ClientGrpcProxy.name, () =>
require('grpc'),
);
grpcProtoLoaderPackage = loadPackage(protoLoader, ClientGrpcProxy.name);
this.grpcClient = this.createClient();
}

View File

@@ -27,7 +27,7 @@ export class ClientMqtt extends ClientProxy {
this.url =
this.getOptionsProp<MqttOptions>(this.options, 'url') || MQTT_DEFAULT_URL;
mqttPackage = loadPackage('mqtt', ClientMqtt.name);
mqttPackage = loadPackage('mqtt', ClientMqtt.name, () => require('mqtt'));
}
public getAckPatternName(pattern: string): string {
return `${pattern}_ack`;
@@ -75,10 +75,7 @@ export class ClientMqtt extends ClientProxy {
}
public createClient(): MqttClient {
return mqttPackage.connect(
this.url,
this.options as MqttOptions,
);
return mqttPackage.connect(this.url, this.options as MqttOptions);
}
public handleError(client: MqttClient) {
@@ -143,8 +140,10 @@ export class ClientMqtt extends ClientProxy {
protected dispatchEvent(packet: ReadPacket): Promise<any> {
const pattern = this.normalizePattern(packet.pattern);
return new Promise((resolve, reject) =>
this.mqttClient.publish(pattern, JSON.stringify(packet), err =>
err ? reject(err) : resolve(),
this.mqttClient.publish(
pattern,
JSON.stringify(packet),
err => (err ? reject(err) : resolve()),
),
);
}

View File

@@ -20,7 +20,7 @@ export class ClientNats extends ClientProxy {
super();
this.url =
this.getOptionsProp<NatsOptions>(this.options, 'url') || NATS_DEFAULT_URL;
natsPackage = loadPackage('nats', ClientNats.name);
natsPackage = loadPackage('nats', ClientNats.name, () => require('nats'));
}
public close() {
@@ -107,8 +107,10 @@ export class ClientNats extends ClientProxy {
protected dispatchEvent(packet: ReadPacket): Promise<any> {
const pattern = this.normalizePattern(packet.pattern);
return new Promise((resolve, reject) =>
this.natsClient.publish(pattern, packet as any, err =>
err ? reject(err) : resolve(),
this.natsClient.publish(
pattern,
packet as any,
err => (err ? reject(err) : resolve()),
),
);
}

View File

@@ -33,7 +33,9 @@ export class ClientRedis extends ClientProxy {
this.url =
this.getOptionsProp<RedisOptions>(options, 'url') || REDIS_DEFAULT_URL;
redisPackage = loadPackage('redis', ClientRedis.name);
redisPackage = loadPackage('redis', ClientRedis.name, () =>
require('redis'),
);
}
public getAckPatternName(pattern: string): string {
@@ -171,8 +173,10 @@ export class ClientRedis extends ClientProxy {
protected dispatchEvent(packet: ReadPacket): Promise<any> {
const pattern = this.normalizePattern(packet.pattern);
return new Promise((resolve, reject) =>
this.pubClient.publish(pattern, JSON.stringify(packet), err =>
err ? reject(err) : resolve(),
this.pubClient.publish(
pattern,
JSON.stringify(packet),
err => (err ? reject(err) : resolve()),
),
);
}

View File

@@ -50,8 +50,10 @@ export class ClientRMQ extends ClientProxy {
this.getOptionsProp<RmqOptions>(this.options, 'queueOptions') ||
RQM_DEFAULT_QUEUE_OPTIONS;
loadPackage('amqplib', ClientRMQ.name);
rqmPackage = loadPackage('amqp-connection-manager', ClientRMQ.name);
loadPackage('amqplib', ClientRMQ.name, () => require('amqplib'));
rqmPackage = loadPackage('amqp-connection-manager', ClientRMQ.name, () =>
require('amqp-connection-manager'),
);
}
public close(): void {
@@ -79,10 +81,7 @@ export class ClientRMQ extends ClientProxy {
const connect$ = this.connect$(this.client);
this.connection = this.mergeDisconnectEvent(this.client, connect$)
.pipe(
switchMap(() => this.createChannel()),
share(),
)
.pipe(switchMap(() => this.createChannel()), share())
.toPromise();
return this.connection;
}

View File

@@ -36,7 +36,9 @@ export class ServerGrpc extends Server implements CustomTransportStrategy {
this.getOptionsProp<GrpcOptions>(options, 'protoLoader') ||
GRPC_DEFAULT_PROTO_LOADER;
grpcPackage = this.loadPackage('grpc', ServerGrpc.name);
grpcPackage = this.loadPackage('grpc', ServerGrpc.name, () =>
require('grpc'),
);
grpcProtoLoaderPackage = this.loadPackage(protoLoader, ServerGrpc.name);
}

View File

@@ -27,7 +27,9 @@ export class ServerMqtt extends Server implements CustomTransportStrategy {
this.url =
this.getOptionsProp<MqttOptions>(options, 'url') || MQTT_DEFAULT_URL;
mqttPackage = this.loadPackage('mqtt', ServerMqtt.name);
mqttPackage = this.loadPackage('mqtt', ServerMqtt.name, () =>
require('mqtt'),
);
}
public async listen(callback: () => void) {
@@ -58,10 +60,7 @@ export class ServerMqtt extends Server implements CustomTransportStrategy {
}
public createMqttClient(): MqttClient {
return mqttPackage.connect(
this.url,
this.options as MqttOptions,
);
return mqttPackage.connect(this.url, this.options as MqttOptions);
}
public getMessageHandler(pub: MqttClient): Function {

View File

@@ -27,7 +27,9 @@ export class ServerNats extends Server implements CustomTransportStrategy {
this.url =
this.getOptionsProp<NatsOptions>(this.options, 'url') || NATS_DEFAULT_URL;
natsPackage = this.loadPackage('nats', ServerNats.name);
natsPackage = this.loadPackage('nats', ServerNats.name, () =>
require('nats'),
);
}
public listen(callback: () => void) {

View File

@@ -34,7 +34,9 @@ export class ServerRedis extends Server implements CustomTransportStrategy {
this.getOptionsProp<RedisOptions>(this.options, 'url') ||
REDIS_DEFAULT_URL;
redisPackage = this.loadPackage('redis', ServerRedis.name);
redisPackage = this.loadPackage('redis', ServerRedis.name, () =>
require('redis'),
);
}
public listen(callback: () => void) {

View File

@@ -1,4 +1,3 @@
import { loadPackage } from '@nestjs/common/utils/load-package.util';
import { isString, isUndefined } from '@nestjs/common/utils/shared.utils';
import { Observable } from 'rxjs';
import {
@@ -46,8 +45,12 @@ export class ServerRMQ extends Server implements CustomTransportStrategy {
this.getOptionsProp<RmqOptions>(this.options, 'queueOptions') ||
RQM_DEFAULT_QUEUE_OPTIONS;
loadPackage('amqplib', ServerRMQ.name);
rqmPackage = loadPackage('amqp-connection-manager', ServerRMQ.name);
this.loadPackage('amqplib', ServerRMQ.name, () => require('amqplib'));
rqmPackage = this.loadPackage(
'amqp-connection-manager',
ServerRMQ.name,
() => require('amqp-connection-manager'),
);
}
public async listen(callback: () => void): Promise<void> {

View File

@@ -75,7 +75,11 @@ export abstract class Server {
this.logger.error(error);
}
protected loadPackage<T = any>(name: string, ctx: string): T {
return loadPackage(name, ctx);
protected loadPackage<T = any>(
name: string,
ctx: string,
loader?: Function,
): T {
return loadPackage(name, ctx, loader);
}
}

View File

@@ -76,7 +76,9 @@ export class FastifyAdapter extends AbstractHttpAdapter {
send?: any;
}) {
return this.register(
loadPackage('fastify-static', 'FastifyAdapter.useStaticAssets()'),
loadPackage('fastify-static', 'FastifyAdapter.useStaticAssets()', () =>
require('fastify-static'),
),
options,
);
}
@@ -85,6 +87,7 @@ export class FastifyAdapter extends AbstractHttpAdapter {
return this.register(
loadPackage('point-of-view', 'FastifyAdapter.setViewEngine()'),
options,
() => require('point-of-view'),
);
}

View File

@@ -1,7 +1,8 @@
{
"name": "@nestjs/platform-fastify",
"version": "6.0.0-alpha.3",
"description": "Nest - modern, fast, powerful node.js web framework (@platform-fastify)",
"description":
"Nest - modern, fast, powerful node.js web framework (@platform-fastify)",
"author": "Kamil Mysliwiec",
"license": "MIT",
"repository": {
@@ -13,8 +14,8 @@
},
"dependencies": {
"fastify": "^1.13.1",
"fastify-cors": "^0.2.0",
"fastify-formbody": "2.0.3",
"path-to-regexp": "2.2.1"
"fastify-cors": "^1.0.0",
"fastify-formbody": "2.1.0",
"path-to-regexp": "3.0.0"
}
}

View File

@@ -24,7 +24,7 @@ export class WsAdapter extends AbstractWsAdapter {
constructor(appOrHttpServer?: INestApplicationContext | any) {
super(appOrHttpServer);
wsPackage = loadPackage('ws', 'WsAdapter');
wsPackage = loadPackage('ws', 'WsAdapter', () => require('ws'));
}
public create(
@@ -55,10 +55,7 @@ export class WsAdapter extends AbstractWsAdapter {
handlers: MessageMappingProperties[],
transform: (data: any) => Observable<any>,
) {
const close$ = fromEvent(client, CLOSE_EVENT).pipe(
share(),
first(),
);
const close$ = fromEvent(client, CLOSE_EVENT).pipe(share(), first());
const source$ = fromEvent(client, 'message').pipe(
mergeMap(data =>
this.bindMessageHandler(data, handlers, transform).pipe(

View File

@@ -49,6 +49,7 @@ export class TestingModule extends NestApplicationContext {
const { NestMicroservice } = loadPackage(
'@nestjs/microservices',
'TestingModule',
() => require('@nestjs/microservices'),
);
this.applyLogger(options);
return new NestMicroservice(