@nestjsx/crud
Advanced tools
Comparing version 3.0.0-rc.2 to 3.0.0
@@ -13,3 +13,3 @@ import { FilterParamParsed } from './request-parsed-params.interface'; | ||
updateOneBase?(parsedParams: FilterParamParsed[], dto: T): Promise<T>; | ||
deleteOneBase?(parsedParams: FilterParamParsed[]): Promise<void>; | ||
deleteOneBase?(parsedParams: FilterParamParsed[]): Promise<void | T>; | ||
} | ||
@@ -16,0 +16,0 @@ export interface EntitiesBulk<T> { |
{ | ||
"name": "@nestjsx/crud", | ||
"version": "3.0.0-rc.2", | ||
"version": "3.0.0", | ||
"description": "NestJs CRUD for RESTful APIs", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
201
README.md
@@ -8,4 +8,4 @@ <p align="center"> | ||
<p align="center"> | ||
<a href="https://coveralls.io/github/nestjsx/crud?branch=master"><img src="https://travis-ci.org/nestjsx/crud.svg?branch=master" alt="Coverage" /></a> | ||
<a href="https://travis-ci.org/nestjsx/crud"><img src="https://coveralls.io/repos/github/nestjsx/crud/badge.svg?branch=master" alt="Build" /></a> | ||
<a href="https://coveralls.io/github/nestjsx/crud?branch=master"><img src="https://coveralls.io/repos/github/nestjsx/crud/badge.svg?branch=master" alt="Build" /></a> | ||
<a href="https://travis-ci.org/nestjsx/crud"><img src="https://travis-ci.org/nestjsx/crud.svg?branch=master" alt="Coverage" /></a> | ||
<a href="https://github.com/nestjsx/crud/blob/master/LICENSE"><img src="https://img.shields.io/github/license/nestjsx/crud.svg" alt="License" /></a> | ||
@@ -42,5 +42,6 @@ </p> | ||
- [Crud Controller](#crud-controller) | ||
- [Restful Options merge](#restful-options-merge) | ||
- [Path Filter](#path-filter) | ||
- [Validation](#validation) | ||
- [Restful Options](#options-restful) | ||
- [Routes Options](#routes-options) | ||
- [Params Options](#params-options) | ||
- [Validation Options](#validation-options) | ||
- [IntelliSense](#intellisense) | ||
@@ -134,3 +135,3 @@ - [Method Override](#method-override) | ||
_Result:_ array of entities | empty array | ||
_Result:_ array of entities | pagination object with data | ||
_Status Codes:_ 200 | ||
@@ -143,3 +144,3 @@ | ||
_Request Params:_ `:id` - entity id | ||
_Request Params:_ `:id` - some entity field (slug) | ||
_Result:_ entity object | error object | ||
@@ -176,5 +177,5 @@ _Status Codes:_ 200 | 404 | ||
> `PATCH /heroes/:id` | ||
> `PATCH /heroes/:heroId/perks:id` | ||
> `PATCH /heroes/:heroId/perks/:id` | ||
_Request Params:_ `:id` - entity id | ||
_Request Params:_ `:id` - some entity field (slug) | ||
_Request Body:_ entity object (or partial) | entity object with nested (relational) objects (or partial) | ||
@@ -187,5 +188,5 @@ _Result:_: updated partial entity object | error object | ||
> `DELETE /heroes/:id` | ||
> `DELETE /heroes/:heroId/perks:id` | ||
> `DELETE /heroes/:heroId/perks/:id` | ||
_Request Params:_ `:id` - entity id | ||
_Request Params:_ `:id` - some entity field (slug) | ||
_Result:_: empty | error object | ||
@@ -232,2 +233,6 @@ _Status codes:_ 200 | 404 | ||
> ?join=**relation**&filter=**relation**.**field**||**condition**||**value** | ||
**_Notice:_** Using nested filter shall join relation first. | ||
_Examples:_ | ||
@@ -491,3 +496,8 @@ | ||
company: {}, | ||
'company.projects': {} | ||
'company.projects': { | ||
persist: ['status'] | ||
}, | ||
'users.projects.tasks': { | ||
exclude: ['description'], | ||
}, | ||
} | ||
@@ -554,6 +564,4 @@ } | ||
Our newly generated working horse. `@Crud()` decorator accepts two arguments - Entity class and `CrudOptions` object. Let's dive in some details. | ||
Our newly generated working horse. | ||
### Restful Options merge | ||
```typescript | ||
@@ -564,5 +572,3 @@ ... | ||
@Crud(Hero, { | ||
options: { | ||
// RestfulOptions goes here | ||
} | ||
// CrudOptions goes here | ||
}) | ||
@@ -575,10 +581,76 @@ @Controller('heroes') | ||
`CrudOptions` object may have `options` parameter which is the same object as [Restful Options](#restful-options). | ||
`@Crud()` decorator accepts two arguments - Entity class and `CrudOptions` object. All fields here are optional as well. Let's dive in some details. | ||
### Crud Options | ||
- [**`options`**](#options-restful) | ||
- [**`routes`**](#routes-options) | ||
- [**`params`**](#params-options) | ||
- [**`validation`**](#validaton-options) | ||
### Options (restful) | ||
This option has the same structure as as [Restful Options](#restful-options). | ||
**_Notice:_** If you have this options set up in your `RepositoryService`, in that case they will be **merged**. | ||
### Path Filter | ||
### Routes Options | ||
`CrudOptions` object may have `params` parameter that will be used for auto filtering by URL path parameters. | ||
This object may have `exclude` and `only` arrays of route names which must be excluded or only which ones must be created accordingly. | ||
```typescript | ||
{ | ||
routes: { | ||
only: ['getManyBase']; | ||
} | ||
} | ||
``` | ||
```typescript | ||
{ | ||
routes: { | ||
exclude: ['createManyBase']; | ||
} | ||
} | ||
``` | ||
**_Notice:_** If both are present, then `exclude` will be ignored. | ||
Also, routes options object may have some options for each particular route: | ||
```typescript | ||
{ | ||
routes: { | ||
getManyBase: { | ||
interceptors: [], | ||
}, | ||
getOneBase: { | ||
interceptors: [], | ||
}, | ||
createOneBase: { | ||
interceptors: [], | ||
}, | ||
createManyBase: { | ||
interceptors: [], | ||
}, | ||
updateOneBase: { | ||
interceptors: [], | ||
allowParamsOverride: true | ||
}, | ||
deleteOneBase: { | ||
interceptors: [], | ||
returnDeleted: true | ||
}, | ||
} | ||
} | ||
``` | ||
`interceptors` - an array of your custom interceptors | ||
`allowParamsOverride` - whether or not to allow body data be overriten by the URL params on PATH request. Default: `false` | ||
`returnDeleted` - whether or not an entity object should be returned in the response body on DELETE request. Default: `false` | ||
### Params Options | ||
`CrudOptions` object may have `params` parameter that will be used for validation sake of you URL params and for defining a slug param (if it differs from `id` that is used by default). | ||
Assume, you have an entity `User` that belongs to some `Company` and has a field `companyId`. And you whant to create `UsersController` so that an admin could access users from his own Company only. Let's do this: | ||
@@ -591,3 +663,5 @@ | ||
@Crud(Hero, { | ||
params: ['companyId'] | ||
params: { | ||
companyId: 'number' | ||
} | ||
}) | ||
@@ -600,26 +674,29 @@ @Controller('/company/:companyId/users') | ||
In this example you're URL param name `companyId` should match the name of `User.companyId` field. If not, you can do mapping, like this: | ||
In this example you're URL param name `companyId` should match the name of `User.companyId` field. | ||
If you don't want to use numeric `id` (by default) and, say, you use some unique field, e.g. it's called `slug` and it's a UUID string - in that case need to add this: | ||
```typescript | ||
... | ||
import { Crud } from '@nestjsx/crud'; | ||
{ | ||
params: { | ||
slug: 'uuid'; | ||
} | ||
} | ||
``` | ||
@Crud(Hero, { | ||
Or if your slug/id is just another random unique string, then: | ||
```typescript | ||
{ | ||
params: { | ||
company: 'companyId' | ||
id: 'string'; | ||
} | ||
}) | ||
@Controller('/company/:company/users') | ||
export class UsersCrud { | ||
constructor(public service: UsersService) {} | ||
} | ||
``` | ||
Where `company` is the name of the URL param, and `companyId` is the name of the entity field. | ||
As you might guess, all request will add `companyId` to the DB queries alongside with the `:id` (or another field that you defined) of `GET`, `PATCH`, `DELETE` requests. On `POST` (both: one and bulk) requests, `companyId` will be added to the `dto` automatically. | ||
As you might guess, all request will add `companyId` to the DB queries alongside with the `:id` of `GET`, `PATCH`, `DELETE` requests. On `POST` (both: one and bulk) requests, `companyId` will be added to the `dto` automatically. | ||
When you done with the controller, you'll need to add some logic to your `AuthGuard` or any other interface, where you do the authorization of a requester. You will need to match `companyId` URL param with the `user.companyId` entity that has been validated from the DB. | ||
### Validation | ||
### Validation Options | ||
@@ -670,3 +747,3 @@ Request data validation is performed by using [class-validator](https://github.com/typestack/class-validator) package and [ValidationPipe](https://docs.nestjs.com/techniques/validation). If you don't use this approach in your project, then you can implementat request data validation on your own. | ||
// validate relations, that could be saved/updated as nested objects | ||
// validate relations | ||
@IsOptional({ groups: [UPDATE] }) | ||
@@ -713,3 +790,3 @@ @IsNotEmpty({ groups: [CREATE] }) | ||
@Controller('heroes') | ||
export class HeroesCrud implements CrudController<HeroesService, Hero> { | ||
export class HeroesCrud { | ||
constructor(public service: HeroesService) {} | ||
@@ -729,3 +806,3 @@ } | ||
@Controller('heroes') | ||
export class HeroesCrud implements CrudController<HeroesService, Hero> { | ||
export class HeroesCrud { | ||
constructor(public service: HeroesService) {} | ||
@@ -745,14 +822,13 @@ | ||
getManyBase( | ||
@Param() params: ObjectLiteral, | ||
@Query() query: RestfulParamsDto, | ||
): Promise<T[]>; | ||
@ParsedQuery() query: RestfulParamsDto, | ||
@ParsedOptions() options: CrudOptions, | ||
): Promise<GetManyDefaultResponse<T> | T[]>; | ||
getOneBase( | ||
@Param('id') id: number, | ||
@Param() params: ObjectLiteral, | ||
@Query() query: RestfulParamsDto, | ||
@ParsedQuery() query: RestfulParamsDto, | ||
@ParsedOptions() options: CrudOptions, | ||
): Promise<T>; | ||
createOneBase( | ||
@Param() params: ObjectLiteral, | ||
@ParsedParams() params: FilterParamParsed[], | ||
@Body() dto: T, | ||
@@ -762,3 +838,3 @@ ): Promise<T>; | ||
createManyBase( | ||
@Param() params: ObjectLiteral, | ||
@ParsedParams() params: FilterParamParsed[], | ||
@Body() dto: EntitiesBulk<T>, | ||
@@ -768,4 +844,3 @@ ): Promise<T[]>; | ||
updateOneBase( | ||
@Param('id') id: number, | ||
@Param() params: ObjectLiteral, | ||
@ParsedParams() params: FilterParamParsed[] | ||
@Body() dto: T, | ||
@@ -775,5 +850,4 @@ ): Promise<T>; | ||
deleteOneBase( | ||
@Param('id') id: number, | ||
@Param() params: ObjectLiteral, | ||
): Promise<void>; | ||
@ParsedParams() params: FilterParamParsed[] | ||
): Promise<void | T>; | ||
``` | ||
@@ -793,8 +867,11 @@ | ||
Override, | ||
RestfulParamsDto | ||
RestfulParamsDto, | ||
ParsedQuery, | ||
ParsedParams, | ||
ParsedOptions | ||
} from '@nestjsx/crud'; | ||
@Crud(Hero) | ||
@Crud(Hero, {}) | ||
@Controller('heroes') | ||
export class HeroesCrud implements CrudController<HeroesService, Hero> { | ||
export class HeroesCrud { | ||
constructor(public service: HeroesService) {} | ||
@@ -807,15 +884,25 @@ | ||
@Override() | ||
getMany(@Param() params, @Query() query: RestfulParamsDto) { | ||
getMany( | ||
@ParsedQuery() query: RestfulParamsDto, | ||
@ParsedOptions() options: CrudOptions, | ||
) { | ||
// do some stuff | ||
return this.base.getManyBase(params, query); | ||
return this.base.getManyBase(query, options); | ||
} | ||
@Override('getOneBase') | ||
getOneAndDoStuff() { | ||
getOneAndDoStuff( | ||
@ParsedQuery() query: RestfulParamsDto, | ||
@ParsedOptions() options: CrudOptions, | ||
) { | ||
// do some stuff | ||
} | ||
... | ||
} | ||
``` | ||
**_Notice:_** new custom route decorators were created to simplify process: `@ParsedQuery()`, `@ParsedParams`, and `@ParsedOptions()`. But you still can add your param decorators to any of the methods, e.g. `@Param()`, `@Session()`, etc. Or any of your own cutom route decorators. | ||
### Additional Decorators | ||
@@ -822,0 +909,0 @@ |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
177916
1
995