Skip to content

Commit

Permalink
fix(crud): updated CrudRoutesFactory methods visibility
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelyali committed Feb 6, 2021
1 parent 014ff6e commit 278dcc9
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 36 deletions.
69 changes: 35 additions & 34 deletions packages/crud/src/crud/crud-routes.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,29 @@ export class CrudRoutesFactory {
protected options: MergedCrudOptions;
protected swaggerModels: any = {};

constructor(private target: any, options: CrudOptions) {
constructor(protected target: any, options: CrudOptions) {
this.options = options;
this.create();
}

/* istanbul ignore next */
static create(target: any, options: CrudOptions): CrudRoutesFactory {
return new CrudRoutesFactory(target, options);
}

private get targetProto(): any {
protected get targetProto(): any {
return this.target.prototype;
}

private get modelName(): string {
protected get modelName(): string {
return this.options.model.type.name;
}

private get modelType(): any {
protected get modelType(): any {
return this.options.model.type;
}

private get actionsMap(): { [key in BaseRouteName]: CrudActions } {
protected get actionsMap(): { [key in BaseRouteName]: CrudActions } {
return {
getManyBase: CrudActions.ReadAll,
getOneBase: CrudActions.ReadOne,
Expand All @@ -62,7 +63,7 @@ export class CrudRoutesFactory {
};
}

private create() {
protected create() {
const routesSchema = this.getRoutesSchema();
this.mergeOptions();
this.setResponseModels();
Expand All @@ -71,7 +72,7 @@ export class CrudRoutesFactory {
this.enableRoutes(routesSchema);
}

private mergeOptions() {
protected mergeOptions() {
// merge auth config
const authOptions = R.getCrudAuthOptions(this.target);
this.options.auth = isObjectFull(authOptions) ? authOptions : {};
Expand Down Expand Up @@ -140,7 +141,7 @@ export class CrudRoutesFactory {
R.setCrudOptions(this.options, this.target);
}

private getRoutesSchema(): BaseRoute[] {
protected getRoutesSchema(): BaseRoute[] {
return [
{
name: 'getOneBase',
Expand Down Expand Up @@ -209,55 +210,55 @@ export class CrudRoutesFactory {
];
}

private getManyBase(name: BaseRouteName) {
protected getManyBase(name: BaseRouteName) {
this.targetProto[name] = function getManyBase(req: CrudRequest) {
return this.service.getMany(req);
};
}

private getOneBase(name: BaseRouteName) {
protected getOneBase(name: BaseRouteName) {
this.targetProto[name] = function getOneBase(req: CrudRequest) {
return this.service.getOne(req);
};
}

private createOneBase(name: BaseRouteName) {
protected createOneBase(name: BaseRouteName) {
this.targetProto[name] = function createOneBase(req: CrudRequest, dto: any) {
return this.service.createOne(req, dto);
};
}

private createManyBase(name: BaseRouteName) {
protected createManyBase(name: BaseRouteName) {
this.targetProto[name] = function createManyBase(req: CrudRequest, dto: any) {
return this.service.createMany(req, dto);
};
}

private updateOneBase(name: BaseRouteName) {
protected updateOneBase(name: BaseRouteName) {
this.targetProto[name] = function updateOneBase(req: CrudRequest, dto: any) {
return this.service.updateOne(req, dto);
};
}

private replaceOneBase(name: BaseRouteName) {
protected replaceOneBase(name: BaseRouteName) {
this.targetProto[name] = function replaceOneBase(req: CrudRequest, dto: any) {
return this.service.replaceOne(req, dto);
};
}

private deleteOneBase(name: BaseRouteName) {
protected deleteOneBase(name: BaseRouteName) {
this.targetProto[name] = function deleteOneBase(req: CrudRequest) {
return this.service.deleteOne(req);
};
}

private recoverOneBase(name: BaseRouteName) {
protected recoverOneBase(name: BaseRouteName) {
this.targetProto[name] = function recoverOneBase(req: CrudRequest) {
return this.service.recoverOne(req);
};
}

private canCreateRoute(name: BaseRouteName) {
protected canCreateRoute(name: BaseRouteName) {
const only = this.options.routes.only;
const exclude = this.options.routes.exclude;

Expand All @@ -277,7 +278,7 @@ export class CrudRoutesFactory {
return true;
}

private setResponseModels() {
protected setResponseModels() {
const modelType = isFunction(this.modelType)
? this.modelType
: SerializeHelper.createGetOneResponseDto(this.modelName);
Expand Down Expand Up @@ -305,7 +306,7 @@ export class CrudRoutesFactory {
Swagger.setExtraModels(this.swaggerModels);
}

private createRoutes(routesSchema: BaseRoute[]) {
protected createRoutes(routesSchema: BaseRoute[]) {
const primaryParams = this.getPrimaryParams().filter(
(param) => !this.options.params[param].disabled,
);
Expand All @@ -328,7 +329,7 @@ export class CrudRoutesFactory {
});
}

private overrideRoutes(routesSchema: BaseRoute[]) {
protected overrideRoutes(routesSchema: BaseRoute[]) {
getOwnPropNames(this.targetProto).forEach((name) => {
const override = R.getOverrideRoute(this.targetProto[name]);
const route = routesSchema.find((r) => isEqual(r.name, override));
Expand Down Expand Up @@ -364,15 +365,15 @@ export class CrudRoutesFactory {
});
}

private enableRoutes(routesSchema: BaseRoute[]) {
protected enableRoutes(routesSchema: BaseRoute[]) {
routesSchema.forEach((route) => {
if (!route.override && route.enable) {
R.setRoute(route, this.targetProto[route.name]);
}
});
}

private overrideParsedBodyDecorator(override: BaseRouteName, name: string) {
protected overrideParsedBodyDecorator(override: BaseRouteName, name: string) {
const allowed = [
'createManyBase',
'createOneBase',
Expand Down Expand Up @@ -419,13 +420,13 @@ export class CrudRoutesFactory {
}
}

private getPrimaryParams(): string[] {
protected getPrimaryParams(): string[] {
return objKeys(this.options.params).filter(
(param) => this.options.params[param] && this.options.params[param].primary,
);
}

private setBaseRouteMeta(name: BaseRouteName) {
protected setBaseRouteMeta(name: BaseRouteName) {
this.setRouteArgs(name);
this.setRouteArgsTypes(name);
this.setInterceptors(name);
Expand All @@ -438,7 +439,7 @@ export class CrudRoutesFactory {
this.setDecorators(name);
}

private setRouteArgs(name: BaseRouteName) {
protected setRouteArgs(name: BaseRouteName) {
let rest = {};
const routes: BaseRouteName[] = [
'createManyBase',
Expand All @@ -460,7 +461,7 @@ export class CrudRoutesFactory {
R.setRouteArgs({ ...R.setParsedRequestArg(0), ...rest }, this.target, name);
}

private setRouteArgsTypes(name: BaseRouteName) {
protected setRouteArgsTypes(name: BaseRouteName) {
if (isEqual(name, 'createManyBase')) {
const bulkDto = Validation.createBulkDto(this.options);
R.setRouteArgsTypes([Object, bulkDto], this.targetProto, name);
Expand All @@ -473,7 +474,7 @@ export class CrudRoutesFactory {
}
}

private setInterceptors(name: BaseRouteName) {
protected setInterceptors(name: BaseRouteName) {
const interceptors = this.options.routes[name].interceptors;
R.setInterceptors(
[
Expand All @@ -485,7 +486,7 @@ export class CrudRoutesFactory {
);
}

private setDecorators(name: BaseRouteName) {
protected setDecorators(name: BaseRouteName) {
const decorators = this.options.routes[name].decorators;
R.setDecorators(
isArrayFull(decorators) ? /* istanbul ignore next */ decorators : [],
Expand All @@ -494,17 +495,17 @@ export class CrudRoutesFactory {
);
}

private setAction(name: BaseRouteName) {
protected setAction(name: BaseRouteName) {
R.setAction(this.actionsMap[name], this.targetProto[name]);
}

private setSwaggerOperation(name: BaseRouteName) {
protected setSwaggerOperation(name: BaseRouteName) {
const summary = Swagger.operationsMap(this.modelName)[name];
const operationId = name + this.targetProto.constructor.name + this.modelName;
Swagger.setOperation({ summary, operationId }, this.targetProto[name]);
}

private setSwaggerPathParams(name: BaseRouteName) {
protected setSwaggerPathParams(name: BaseRouteName) {
const metadata = Swagger.getParams(this.targetProto[name]);
const withoutPrimary: BaseRouteName[] = [
'createManyBase',
Expand All @@ -522,21 +523,21 @@ export class CrudRoutesFactory {
Swagger.setParams([...metadata, ...pathParamsMeta], this.targetProto[name]);
}

private setSwaggerQueryParams(name: BaseRouteName) {
protected setSwaggerQueryParams(name: BaseRouteName) {
const metadata = Swagger.getParams(this.targetProto[name]);
const queryParamsMeta = Swagger.createQueryParamsMeta(name, this.options);
Swagger.setParams([...metadata, ...queryParamsMeta], this.targetProto[name]);
}

private setSwaggerResponseOk(name: BaseRouteName) {
protected setSwaggerResponseOk(name: BaseRouteName) {
const metadata = Swagger.getResponseOk(this.targetProto[name]);
const metadataToAdd =
Swagger.createResponseMeta(name, this.options, this.swaggerModels) ||
/* istanbul ignore next */ {};
Swagger.setResponseOk({ ...metadata, ...metadataToAdd }, this.targetProto[name]);
}

private routeNameAction(name: BaseRouteName): string {
protected routeNameAction(name: BaseRouteName): string {
return (
name.split('OneBase')[0] || /* istanbul ignore next */ name.split('ManyBase')[0]
);
Expand Down
3 changes: 2 additions & 1 deletion packages/crud/src/decorators/crud.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { CrudRoutesFactory } from '../crud';
import { CrudOptions } from '../interfaces';

export const Crud = (options: CrudOptions) => (target: Object) => {
let factory = CrudRoutesFactory.create(target, options);
const factoryMethod = options.routesFactory || CrudRoutesFactory;
let factory = new factoryMethod(target, options);
factory = undefined;
};
1 change: 1 addition & 0 deletions packages/crud/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './crud/crud-routes.factory';
export * from './decorators';
export * from './enums';
export * from './interfaces';
Expand Down
2 changes: 2 additions & 0 deletions packages/crud/src/interfaces/crud-options.interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ValidationPipeOptions } from '@nestjs/common';

import { CrudRoutesFactory } from '../crud';
import { ModelOptions } from './model-options.interface';
import { ParamsOptions } from './params-options.interface';
import { QueryOptions } from './query-options.interface';
Expand All @@ -20,6 +21,7 @@ export interface CrudOptions {
serialize?: SerializeOptions;
query?: QueryOptions;
routes?: RoutesOptions;
routesFactory?: typeof CrudRoutesFactory;
params?: ParamsOptions;
validation?: ValidationPipeOptions | false;
}
Expand Down
19 changes: 18 additions & 1 deletion packages/crud/test/crud.decorator.options.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { Controller, INestApplication } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';

import { CrudRoutesFactory } from '../src/crud/crud-routes.factory';
import { Swagger } from '../src/crud/swagger.helper';
import { Crud } from '../src/decorators';
import { CrudOptions } from '../src/interfaces';
import { BaseRouteName } from '../src/types';
import { HttpExceptionFilter } from './__fixture__/exception.filter';
import { TestModel } from './__fixture__/models';
import { TestService } from './__fixture__/services';
Expand All @@ -14,6 +16,14 @@ describe('#crud', () => {
let app: INestApplication;
let server: any;

class CustomSwaggerRoutesFactory extends CrudRoutesFactory {
protected setSwaggerOperation(name: BaseRouteName) {
const summary = Swagger.operationsMap(this.modelName)[name];
const operationId = '_' + name + this.modelName;
Swagger.setOperation({ summary, operationId }, this.targetProto[name]);
}
}

const options: CrudOptions = {
model: { type: TestModel },
params: {
Expand Down Expand Up @@ -59,6 +69,7 @@ describe('#crud', () => {
returnDeleted: true,
},
},
routesFactory: CustomSwaggerRoutesFactory,
};

@Crud(options)
Expand Down Expand Up @@ -95,5 +106,11 @@ describe('#crud', () => {
done();
});
});

it('should use crudRoutesFactory override', () => {
const testController = app.get('TestController');
const { operationId } = Swagger.getOperation(testController.replaceOneBase);
expect(operationId).toEqual('_replaceOneBaseTestModel');
});
});
});

0 comments on commit 278dcc9

Please sign in to comment.