Skip to content

Commit

Permalink
Merge branch 'master' into soft-remove
Browse files Browse the repository at this point in the history
  • Loading branch information
klalex committed Dec 19, 2020
2 parents bbc24cf + 77bb83a commit 412238d
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 44 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"nps": "5.9.8",
"nps-utils": "1.7.0",
"pg": "^8.4.2",
"pluralize": "^8.0.0",
"prettier": "1.18.2",
"pretty-quick": "1.11.1",
"qs": "6.8.0",
Expand Down
20 changes: 13 additions & 7 deletions packages/crud-typeorm/src/typeorm-crud.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,16 @@ export class TypeOrmCrudService<T> extends CrudService<T> {
if (returnShallow) {
return saved;
} else {
const primaryParam = this.getPrimaryParam(req.options);
const primaryParams = this.getPrimaryParams(req.options);

/* istanbul ignore if */
if (!primaryParam && /* istanbul ignore next */ isNil(saved[primaryParam])) {
/* istanbul ignore next */
if (!primaryParams.length && primaryParams.some((p) => isNil(saved[p]))) {
return saved;
} else {
req.parsed.search = { [primaryParam]: saved[primaryParam] };
req.parsed.search = primaryParams.reduce(
(acc, p) => ({ ...acc, [p]: saved[p] }),
{},
);
return this.getOneOrFail(req);
}
}
Expand Down Expand Up @@ -223,14 +226,17 @@ export class TypeOrmCrudService<T> extends CrudService<T> {
if (returnShallow) {
return replaced;
} else {
const primaryParam = this.getPrimaryParam(req.options);
const primaryParams = this.getPrimaryParams(req.options);

/* istanbul ignore if */
if (!primaryParam) {
if (!primaryParams.length) {
return replaced;
}

req.parsed.search = { [primaryParam]: replaced[primaryParam] };
req.parsed.search = primaryParams.reduce(
(acc, p) => ({ ...acc, [p]: replaced[p] }),
{},
);
return this.getOneOrFail(req);
}
}
Expand Down
22 changes: 22 additions & 0 deletions packages/crud-typeorm/test/c.basic-crud.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,18 @@ describe('#crud-typeorm', () => {
constructor(public service: UsersService) {}
}

@Crud({
model: { type: User },
params: {
companyId: { field: 'companyId', type: 'number', primary: true },
profileId: { field: 'profileId', type: 'number', primary: true },
},
})
@Controller('users4')
class UsersController4 {
constructor(public service: UsersService) {}
}

@Crud({
model: { type: Device },
params: {
Expand Down Expand Up @@ -271,6 +283,7 @@ describe('#crud-typeorm', () => {
UsersController,
UsersController2,
UsersController3,
UsersController4,
DevicesController,
],
providers: [
Expand Down Expand Up @@ -426,6 +439,15 @@ describe('#crud-typeorm', () => {
done();
});
});
it('should return an entity with compound key', (done) => {
return request(server)
.get('/users4/1/5')
.end((_, res) => {
expect(res.status).toBe(200);
expect(res.body.id).toBe(5);
done();
});
});
it('should return an entity with and set cache', (done) => {
return request(server)
.get('/companies/1/users/1')
Expand Down
17 changes: 10 additions & 7 deletions packages/crud/src/crud/crud-routes.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export class CrudRoutesFactory {
: isObjectFull(CrudConfigService.config.params)
? CrudConfigService.config.params
: {};
const hasPrimary = this.getPrimaryParam();
const hasPrimary = this.getPrimaryParams().length > 0;
if (!hasPrimary) {
this.options.params['id'] = {
field: 'id',
Expand Down Expand Up @@ -306,7 +306,9 @@ export class CrudRoutesFactory {
}

private createRoutes(routesSchema: BaseRoute[]) {
const primaryParam = this.getPrimaryParam();
const primaryParams = this.getPrimaryParams().filter(
(param) => !this.options.params[param].disabled,
);

routesSchema.forEach((route) => {
if (this.canCreateRoute(route.name)) {
Expand All @@ -317,9 +319,10 @@ export class CrudRoutesFactory {
this.setBaseRouteMeta(route.name);
}

if (route.withParams && !this.options.params[primaryParam].disabled) {
route.path =
route.path.length > 0 ? `/:${primaryParam}${route.path}` : `/:${primaryParam}`;
if (route.withParams && primaryParams.length > 0) {
route.path = route.path.length > 0
? `${primaryParams.map((param) => `/:${param}`).join('')}${route.path}`
: primaryParams.map((param) => `/:${param}`).join('');
}
});
}
Expand Down Expand Up @@ -415,8 +418,8 @@ export class CrudRoutesFactory {
}
}

private getPrimaryParam(): string {
return objKeys(this.options.params).find(
private getPrimaryParams(): string[] {
return objKeys(this.options.params).filter(
(param) => this.options.params[param] && this.options.params[param].primary,
);
}
Expand Down
17 changes: 4 additions & 13 deletions packages/crud/src/crud/reflection.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,25 +84,16 @@ export class R {
target: object,
name: string,
) {
// this makes proxy decorator works
Reflect.defineProperty(
target,
name,
Reflect.decorate(
decorators,
target,
name,
Reflect.getOwnPropertyDescriptor(target, name),
),
);

// this makes metadata decorator works
Reflect.decorate(
const decoratedDescriptor = Reflect.decorate(
decorators,
target,
name,
Reflect.getOwnPropertyDescriptor(target, name),
);

// this makes proxy decorator works
Reflect.defineProperty(target, name, decoratedDescriptor);
}

static setParsedRequestArg(index: number) {
Expand Down
15 changes: 8 additions & 7 deletions packages/crud/src/crud/swagger.helper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { HttpStatus } from '@nestjs/common';
import { objKeys, isString, isFunction } from '@nestjsx/util';
import { RequestQueryBuilder } from '@nestjsx/crud-request';
const pluralize = require('pluralize');

import { safeRequire } from '../util';
import { R } from './reflection.helper';
Expand All @@ -14,13 +15,13 @@ export const swaggerPkgJson = safeRequire('@nestjs/swagger/package.json');
export class Swagger {
static operationsMap(modelName): { [key in BaseRouteName]: string } {
return {
getManyBase: `Retrieve many ${modelName}`,
getOneBase: `Retrieve one ${modelName}`,
createManyBase: `Create many ${modelName}`,
createOneBase: `Create one ${modelName}`,
updateOneBase: `Update one ${modelName}`,
replaceOneBase: `Replace one ${modelName}`,
deleteOneBase: `Delete one ${modelName}`,
getManyBase: `Retrieve multiple ${pluralize(modelName)}`,
getOneBase: `Retrieve a single ${modelName}`,
createManyBase: `Create multiple ${pluralize(modelName)}`,
createOneBase: `Create a single ${modelName}`,
updateOneBase: `Update a single ${modelName}`,
replaceOneBase: `Replace a single ${modelName}`,
deleteOneBase: `Delete a single ${modelName}`,
recoverOneBase: `Recover one ${modelName}`,
};
}
Expand Down
11 changes: 3 additions & 8 deletions packages/crud/src/services/crud-service.abstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,11 @@ export abstract class CrudService<T> {
* Get primary param name from CrudOptions
* @param options
*/
getPrimaryParam(options: CrudRequestOptions): string {
const param = objKeys(options.params).find(
getPrimaryParams(options: CrudRequestOptions): string[] {
const params = objKeys(options.params).filter(
(n) => options.params[n] && options.params[n].primary,
);

/* istanbul ignore if */
if (!param) {
return undefined;
}

return options.params[param].field;
return params.map((p) => options.params[p].field);
}
}
24 changes: 23 additions & 1 deletion packages/crud/test/crud-request.interceptor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,31 @@ describe('#crud', () => {
}
}

@Crud({
model: { type: TestModel },
params: {
someParam: { field: 'someParam', type: 'number', primary: true },
someParam2: { field: 'someParam2', type: 'number', primary: true },
},
})
@Controller('test5')
class Test5Controller {
constructor(public service: TestService<TestModel>) {}
}

let $: supertest.SuperTest<supertest.Test>;
let app: NestApplication;

beforeAll(async () => {
const module = await Test.createTestingModule({
providers: [TestService],
controllers: [TestController, Test2Controller, Test3Controller, Test4Controller],
controllers: [
TestController,
Test2Controller,
Test3Controller,
Test4Controller,
Test5Controller,
],
}).compile();
app = module.createNestApplication();
await app.init();
Expand Down Expand Up @@ -195,6 +213,10 @@ describe('#crud', () => {
expect(res.body.filter[0].value).toBe(1);
});

it('should parse multiple primary key', async () => {
const res = await $.get('/test5/123/456').expect(200);
});

it('should work like before', async () => {
const res = await $.get('/test2/normal/0').expect(200);
expect(res.body.filter).toHaveLength(1);
Expand Down
2 changes: 1 addition & 1 deletion packages/crud/test/crud.decorator.override.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ describe('#crud', () => {
});
it('should return swagger operation', () => {
const operation = Swagger.getOperation(TestController.prototype.getMany);
const expected = { summary: 'Retrieve many TestModel' };
const expected = { summary: 'Retrieve multiple TestModels' };
expect(operation).toMatchObject(expected);
});
it('should return swagger params', () => {
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7070,6 +7070,11 @@ please-upgrade-node@^3.2.0:
dependencies:
semver-compare "^1.0.0"

pluralize@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1"
integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==

pn@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
Expand Down

0 comments on commit 412238d

Please sign in to comment.