@nest-util/nest-crud 1.1.3 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export * from './lib/dtos/filter.dto';
5
5
  export * from './lib/dtos/pagination.dto';
6
6
  export * from './lib/dtos/cursor-pagination.dto';
7
7
  export * from './lib/dtos/list-audit-logs.dto';
8
+ export * from './lib/dtos/status-change.dto';
8
9
  export * from './lib/decorators/response-message.decorator';
9
10
  export * from './lib/decorators/audit-log.decorator';
10
11
  export * from './lib/interceptors/response.interceptor';
@@ -13,6 +14,7 @@ export * from './lib/interfaces/crud.interface';
13
14
  export * from './lib/interfaces/cursor-strategy.interface';
14
15
  export * from './lib/interfaces/hooks.interface';
15
16
  export * from './lib/interfaces/find-mine.interface';
17
+ export * from './lib/interfaces/status-pipeline.interface';
16
18
  export * from './lib/interfaces/audit-log.interface';
17
19
  export * from './lib/helpers/exception-filter.helper';
18
20
  export * from './lib/helpers/cursor-pagination.helper';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC;AACjD,cAAc,wCAAwC,CAAC;AACvD,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,sCAAsC,CAAC;AACrD,cAAc,yCAAyC,CAAC;AACxD,cAAc,0CAA0C,CAAC;AACzD,cAAc,iCAAiC,CAAC;AAChD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,kCAAkC,CAAC;AACjD,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,wCAAwC,CAAC;AACvD,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC;AACjD,cAAc,wCAAwC,CAAC;AACvD,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,sCAAsC,CAAC;AACrD,cAAc,yCAAyC,CAAC;AACxD,cAAc,0CAA0C,CAAC;AACzD,cAAc,iCAAiC,CAAC;AAChD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,kCAAkC,CAAC;AACjD,cAAc,sCAAsC,CAAC;AACrD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,wCAAwC,CAAC;AACvD,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ tslib_1.__exportStar(require("./lib/dtos/filter.dto"), exports);
8
8
  tslib_1.__exportStar(require("./lib/dtos/pagination.dto"), exports);
9
9
  tslib_1.__exportStar(require("./lib/dtos/cursor-pagination.dto"), exports);
10
10
  tslib_1.__exportStar(require("./lib/dtos/list-audit-logs.dto"), exports);
11
+ tslib_1.__exportStar(require("./lib/dtos/status-change.dto"), exports);
11
12
  tslib_1.__exportStar(require("./lib/decorators/response-message.decorator"), exports);
12
13
  tslib_1.__exportStar(require("./lib/decorators/audit-log.decorator"), exports);
13
14
  tslib_1.__exportStar(require("./lib/interceptors/response.interceptor"), exports);
@@ -16,6 +17,7 @@ tslib_1.__exportStar(require("./lib/interfaces/crud.interface"), exports);
16
17
  tslib_1.__exportStar(require("./lib/interfaces/cursor-strategy.interface"), exports);
17
18
  tslib_1.__exportStar(require("./lib/interfaces/hooks.interface"), exports);
18
19
  tslib_1.__exportStar(require("./lib/interfaces/find-mine.interface"), exports);
20
+ tslib_1.__exportStar(require("./lib/interfaces/status-pipeline.interface"), exports);
19
21
  tslib_1.__exportStar(require("./lib/interfaces/audit-log.interface"), exports);
20
22
  tslib_1.__exportStar(require("./lib/helpers/exception-filter.helper"), exports);
21
23
  tslib_1.__exportStar(require("./lib/helpers/cursor-pagination.helper"), exports);
@@ -3,6 +3,7 @@ import { CrudEndpoint, CrudInterface } from '../interfaces/crud.interface';
3
3
  import { PaginationDto } from '../dtos/pagination.dto';
4
4
  import { FilterDto } from '../dtos/filter.dto';
5
5
  import { ListAuditLogsDto } from '../dtos/list-audit-logs.dto';
6
+ import { StatusChangeDto } from '../dtos/status-change.dto';
6
7
  import type { OwnershipUser } from '../interfaces/find-mine.interface';
7
8
  export declare const AUTH_PERMISSIONS_METADATA_KEY = "auth:permissions";
8
9
  export type CrudEndpointPermissions = string | readonly string[];
@@ -20,6 +21,7 @@ export interface IBaseController<CD, UD, RD> {
20
21
  findOne(id: number, user?: OwnershipUser): Promise<RD>;
21
22
  create(dto: CD, user?: OwnershipUser): Promise<RD>;
22
23
  update(id: number, dto: UD, user?: OwnershipUser): Promise<RD>;
24
+ changeStatus?(id: number, dto: StatusChangeDto, user?: OwnershipUser): Promise<RD>;
23
25
  remove(id: number, user?: OwnershipUser): Promise<boolean>;
24
26
  findAuditLogs?(query: ListAuditLogsDto): Promise<unknown>;
25
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"nest-crud.controller.d.ts","sourceRoot":"","sources":["../../../src/lib/controllers/nest-crud.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,IAAI,EACL,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAEvE,eAAO,MAAM,6BAA6B,qBAAqB,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;AAEjE,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACtC,MAAM,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAC9C,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;IACzC,OAAO,EAAE,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,CACL,KAAK,EAAE,aAAa,GAAG,SAAS,GAC/B,OAAO,CAAC;QAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/D,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,aAAa,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AAyDD,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EACnD,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,EACnB,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,EACnB,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,EACrB,OAAO,CAAC,EAAE,4BAA4B,GACrC,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAwInC"}
1
+ {"version":3,"file":"nest-crud.controller.d.ts","sourceRoot":"","sources":["../../../src/lib/controllers/nest-crud.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,IAAI,EACL,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAEvE,eAAO,MAAM,6BAA6B,qBAAqB,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;AAEjE,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACtC,MAAM,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAC9C,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;IACzC,OAAO,EAAE,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,CACL,KAAK,EAAE,aAAa,GAAG,SAAS,GAC/B,OAAO,CAAC;QAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/D,YAAY,CAAC,CACX,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,eAAe,EACpB,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC,EAAE,CAAC,CAAC;IACf,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,aAAa,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AAyDD,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EACnD,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,EACnB,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,EACnB,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,EACrB,OAAO,CAAC,EAAE,4BAA4B,GACrC,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CA2JnC"}
@@ -8,6 +8,7 @@ const swagger_1 = require("@nestjs/swagger");
8
8
  const response_message_decorator_1 = require("../decorators/response-message.decorator");
9
9
  const audit_log_decorator_1 = require("../decorators/audit-log.decorator");
10
10
  const list_audit_logs_dto_1 = require("../dtos/list-audit-logs.dto");
11
+ const status_change_dto_1 = require("../dtos/status-change.dto");
11
12
  const nest_auth_1 = require("@nest-util/nest-auth");
12
13
  exports.AUTH_PERMISSIONS_METADATA_KEY = 'auth:permissions';
13
14
  const toPermissionList = (permissionValue) => {
@@ -76,6 +77,13 @@ function CreateNestedCrudController(createDto, updateDto, responseDto, options)
76
77
  this.ensureEndpointEnabled('update');
77
78
  return this.service.update(id, dto, user);
78
79
  }
80
+ changeStatus(id, dto, user) {
81
+ this.ensureEndpointEnabled('changeStatus');
82
+ if (!this.service.changeStatus) {
83
+ throw new common_1.NotFoundException('Resource not found');
84
+ }
85
+ return this.service.changeStatus(id, dto.status, user);
86
+ }
79
87
  remove(id, user) {
80
88
  this.ensureEndpointEnabled('remove');
81
89
  return this.service.remove(id, user);
@@ -166,6 +174,19 @@ function CreateNestedCrudController(createDto, updateDto, responseDto, options)
166
174
  tslib_1.__metadata("design:paramtypes", [Number, Object, Object]),
167
175
  tslib_1.__metadata("design:returntype", void 0)
168
176
  ], BaseController.prototype, "update", null);
177
+ tslib_1.__decorate([
178
+ (0, common_1.Post)(':id/status'),
179
+ (0, response_message_decorator_1.Message)('updated'),
180
+ (0, audit_log_decorator_1.Audit)({ action: 'UPDATE' }),
181
+ (0, swagger_1.ApiBody)({ type: status_change_dto_1.StatusChangeDto }),
182
+ (0, swagger_1.ApiResponse)({ type: responseDto }),
183
+ tslib_1.__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
184
+ tslib_1.__param(1, (0, common_1.Body)()),
185
+ tslib_1.__param(2, (0, nest_auth_1.CurrentUser)()),
186
+ tslib_1.__metadata("design:type", Function),
187
+ tslib_1.__metadata("design:paramtypes", [Number, status_change_dto_1.StatusChangeDto, Object]),
188
+ tslib_1.__metadata("design:returntype", void 0)
189
+ ], BaseController.prototype, "changeStatus", null);
169
190
  tslib_1.__decorate([
170
191
  (0, common_1.Delete)(':id'),
171
192
  (0, response_message_decorator_1.Message)('deleted'),
@@ -0,0 +1,5 @@
1
+ import type { StatusValue } from '../interfaces/status-pipeline.interface';
2
+ export declare class StatusChangeDto {
3
+ status: StatusValue;
4
+ }
5
+ //# sourceMappingURL=status-change.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-change.dto.d.ts","sourceRoot":"","sources":["../../../src/lib/dtos/status-change.dto.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAE3E,qBAAa,eAAe;IAK1B,MAAM,EAAG,WAAW,CAAC;CACtB"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StatusChangeDto = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const class_validator_1 = require("class-validator");
6
+ const swagger_1 = require("@nestjs/swagger");
7
+ class StatusChangeDto {
8
+ }
9
+ exports.StatusChangeDto = StatusChangeDto;
10
+ tslib_1.__decorate([
11
+ (0, swagger_1.ApiProperty)({
12
+ description: 'The status value to transition to',
13
+ }),
14
+ (0, class_validator_1.IsDefined)(),
15
+ tslib_1.__metadata("design:type", Object)
16
+ ], StatusChangeDto.prototype, "status", void 0);
@@ -2,7 +2,8 @@ import { FilterDto } from '../dtos/filter.dto';
2
2
  import { PaginationDto } from '../dtos/pagination.dto';
3
3
  import { CursorPaginationDto } from '../dtos/cursor-pagination.dto';
4
4
  import { OwnershipUser } from './find-mine.interface';
5
- export type CrudEndpoint = 'findAll' | 'findOne' | 'create' | 'update' | 'remove' | 'findAuditLogs' | 'findMine';
5
+ import { StatusValue } from './status-pipeline.interface';
6
+ export type CrudEndpoint = 'findAll' | 'findOne' | 'create' | 'update' | 'changeStatus' | 'remove' | 'findAuditLogs' | 'findMine';
6
7
  export interface AuditLogQuery {
7
8
  user_id?: string;
8
9
  start_date?: string;
@@ -29,6 +30,7 @@ export interface CrudInterface<CreateDto, UpdateDto, ResponseDto> {
29
30
  findOne(id: number, user?: OwnershipUser): Promise<ResponseDto>;
30
31
  create(dto: CreateDto, user?: OwnershipUser): Promise<ResponseDto>;
31
32
  update(id: number, dto: UpdateDto, user?: OwnershipUser): Promise<ResponseDto>;
33
+ changeStatus?(id: number, status: StatusValue, user?: OwnershipUser): Promise<ResponseDto>;
32
34
  remove(id: number, user?: OwnershipUser): Promise<boolean>;
33
35
  findAuditLogs?(query: AuditLogQuery): Promise<unknown>;
34
36
  findMine?(userId: string | number, query: PaginationDto & FilterDto): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"crud.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/crud.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,eAAe,GACf,UAAU,CAAC;AAEf,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW;IAC9D,iBAAiB,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAE5C,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC;QACjD,IAAI,EAAE,WAAW,EAAE,CAAC;QACpB,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC,CAAC;IAEH,iBAAiB,CAAC,CAChB,KAAK,EAAE,mBAAmB,GAAG,SAAS,GACrC,OAAO,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC,CAAC;IAEhD,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEhE,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEnE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAE/E,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3D,aAAa,CAAC,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvD,QAAQ,CAAC,CACP,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,KAAK,EAAE,aAAa,GAAG,SAAS,GAC/B,OAAO,CAAC;QAAE,IAAI,EAAE,WAAW,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACrD"}
1
+ {"version":3,"file":"crud.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/crud.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,cAAc,GACd,QAAQ,GACR,eAAe,GACf,UAAU,CAAC;AAEf,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW;IAC9D,iBAAiB,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAE5C,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC;QACjD,IAAI,EAAE,WAAW,EAAE,CAAC;QACpB,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC,CAAC;IAEH,iBAAiB,CAAC,CAChB,KAAK,EAAE,mBAAmB,GAAG,SAAS,GACrC,OAAO,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC,CAAC;IAEhD,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEhE,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEnE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAE/E,YAAY,CAAC,CACX,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,WAAW,EACnB,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3D,aAAa,CAAC,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvD,QAAQ,CAAC,CACP,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,KAAK,EAAE,aAAa,GAAG,SAAS,GAC/B,OAAO,CAAC;QAAE,IAAI,EAAE,WAAW,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACrD"}
@@ -28,5 +28,12 @@ export interface FindMineConfig<TEntity extends ObjectLiteral> {
28
28
  * Takes precedence alongside ownershipBypassPermissions.
29
29
  */
30
30
  ownershipBypass?: (user: OwnershipUser) => boolean;
31
+ /**
32
+ * Permission string that grants full access and bypasses ownership checks,
33
+ * mirroring `rbac.superAdminPermission` from @nest-util/nest-auth. When the
34
+ * user's resolved permissions (direct or via roles) include this string,
35
+ * ownership checks are skipped. Example: 'admin.access'.
36
+ */
37
+ superAdminPermission?: string;
31
38
  }
32
39
  //# sourceMappingURL=find-mine.interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"find-mine.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/find-mine.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE5D;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc,CAAC,OAAO,SAAS,aAAa;IAC3D,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC;IACnC,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IAEnF;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,0BAA0B,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAE/C;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC;CACpD"}
1
+ {"version":3,"file":"find-mine.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/find-mine.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE5D;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc,CAAC,OAAO,SAAS,aAAa;IAC3D,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC;IACnC,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IAEnF;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,0BAA0B,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAE/C;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC;IAEnD;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B"}
@@ -0,0 +1,63 @@
1
+ import { OwnershipUser } from './find-mine.interface';
2
+ export type StatusValue = string | number;
3
+ /**
4
+ * Context passed to a status transition action. The transition has already
5
+ * been validated and persisted (`entity` reflects the new status) when the
6
+ * action runs.
7
+ */
8
+ export interface StatusTransitionContext<TEntity extends Record<string, unknown>> {
9
+ id: number;
10
+ entity: TEntity;
11
+ from: StatusValue;
12
+ to: StatusValue;
13
+ user?: OwnershipUser;
14
+ }
15
+ /**
16
+ * Callback that runs after a status transition is saved. May be async and is
17
+ * awaited. Edge actions run before the pipeline-level `onTransition`.
18
+ */
19
+ export type StatusTransitionAction<TEntity extends Record<string, unknown>> = (context: StatusTransitionContext<TEntity>) => void | Promise<void>;
20
+ /**
21
+ * A single allowed transition edge. When `permission` is set, the caller must
22
+ * have that permission in their resolved permissions to perform the
23
+ * transition. When `action` is set, it runs after the transition is saved.
24
+ */
25
+ export interface StatusTransitionEdge<TEntity extends Record<string, unknown>> {
26
+ from: StatusValue;
27
+ to: readonly StatusValue[];
28
+ permission?: string;
29
+ action?: StatusTransitionAction<TEntity>;
30
+ }
31
+ /**
32
+ * Allowed status transitions, provided either as a simple map
33
+ * ({ pending: ['approved', 'rejected'] }) or as an array of edges that can
34
+ * optionally carry per-transition permissions and actions.
35
+ */
36
+ export type StatusTransitions<TEntity extends Record<string, unknown>> = Record<StatusValue, readonly StatusValue[]> | readonly StatusTransitionEdge<TEntity>[];
37
+ export interface StatusPipelineConfig<TEntity extends Record<string, unknown>> {
38
+ /**
39
+ * The column on the entity that holds the status value, e.g. 'status'.
40
+ */
41
+ field: keyof TEntity;
42
+ /**
43
+ * Directed graph of allowed transitions. A transition not listed here is
44
+ * rejected. This covers both upgrades (pending -> approved) and controlled
45
+ * downgrades (approved -> pending) — only explicitly allowed moves pass.
46
+ */
47
+ transitions: StatusTransitions<TEntity>;
48
+ /**
49
+ * Status applied on create when the payload omits the status field.
50
+ */
51
+ initial?: StatusValue;
52
+ /**
53
+ * Statuses a create payload may set directly. Defaults to [initial].
54
+ */
55
+ allowCreateStatuses?: readonly StatusValue[];
56
+ /**
57
+ * Global action that runs after every successful status transition, after
58
+ * any edge-specific `action`. Useful for cross-cutting concerns such as
59
+ * audit logging of every transition.
60
+ */
61
+ onTransition?: StatusTransitionAction<TEntity>;
62
+ }
63
+ //# sourceMappingURL=status-pipeline.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-pipeline.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/status-pipeline.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1C;;;;GAIG;AACH,MAAM,WAAW,uBAAuB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC9E,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,EAAE,WAAW,CAAC;IAChB,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAC5E,OAAO,EAAE,uBAAuB,CAAC,OAAO,CAAC,KACtC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;;;GAIG;AACH,MAAM,WAAW,oBAAoB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3E,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,EAAE,SAAS,WAAW,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,sBAAsB,CAAC,OAAO,CAAC,CAAC;CAC1C;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACjE,MAAM,CAAC,WAAW,EAAE,SAAS,WAAW,EAAE,CAAC,GAC3C,SAAS,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;AAE7C,MAAM,WAAW,oBAAoB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3E;;OAEG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC;IAErB;;;;OAIG;IACH,WAAW,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAExC;;OAEG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;OAEG;IACH,mBAAmB,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAE7C;;;;OAIG;IACH,YAAY,CAAC,EAAE,sBAAsB,CAAC,OAAO,CAAC,CAAC;CAChD"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -8,6 +8,7 @@ import { CrudEndpoint, CrudInterface, CursorPaginationResult } from '../interfac
8
8
  import { CursorStrategy } from '../interfaces/cursor-strategy.interface';
9
9
  import { CrudHooks, TransactionConfig } from '../interfaces/hooks.interface';
10
10
  import { FindMineConfig, OwnershipUser } from '../interfaces/find-mine.interface';
11
+ import { StatusPipelineConfig, StatusTransitionAction, StatusValue } from '../interfaces/status-pipeline.interface';
11
12
  export interface CrudServiceOptions<Entity extends ObjectLiteral, ResponseDto> extends FindMineConfig<Entity> {
12
13
  repository: Repository<Entity>;
13
14
  allowedFilters?: readonly (keyof Entity | (string & {}))[];
@@ -25,6 +26,7 @@ export interface CrudServiceOptions<Entity extends ObjectLiteral, ResponseDto> e
25
26
  cursorStrategy?: CursorStrategy;
26
27
  hooks?: CrudHooks<Entity, any, any>;
27
28
  transactionConfig?: TransactionConfig;
29
+ statusPipeline?: StatusPipelineConfig<Entity>;
28
30
  }
29
31
  export declare class NestCrudService<Entity extends ObjectLiteral, CreateDto = Partial<Entity>, UpdateDto = Partial<Entity>, ResponseDto = Entity> implements CrudInterface<CreateDto, UpdateDto, ResponseDto> {
30
32
  protected readonly repo: Repository<Entity>;
@@ -48,7 +50,18 @@ export declare class NestCrudService<Entity extends ObjectLiteral, CreateDto = P
48
50
  protected readonly enforceOwnership: boolean;
49
51
  protected readonly ownershipBypassPermissions: readonly string[];
50
52
  protected readonly ownershipBypass?: (user: OwnershipUser) => boolean;
53
+ protected readonly superAdminPermission?: string;
54
+ protected readonly statusField?: keyof Entity;
55
+ protected readonly statusInitial?: StatusValue;
56
+ protected readonly statusCreateAllow: readonly StatusValue[];
57
+ protected readonly statusOnTransition?: StatusTransitionAction<Entity>;
58
+ protected readonly statusTransitions: Map<StatusValue, {
59
+ to: Set<StatusValue>;
60
+ permission?: string;
61
+ action?: StatusTransitionAction<Entity>;
62
+ }>;
51
63
  constructor(options: CrudServiceOptions<Entity, ResponseDto>);
64
+ private normalizeStatusTransitions;
52
65
  private resolveRelations;
53
66
  private executeInTransaction;
54
67
  private executeHook;
@@ -56,10 +69,16 @@ export declare class NestCrudService<Entity extends ObjectLiteral, CreateDto = P
56
69
  private applyIncludeJoins;
57
70
  private applyOrderBy;
58
71
  private isOwnershipConfigured;
72
+ private resolveUserPermissions;
59
73
  private canBypassOwnership;
60
74
  private enforceOwnershipFor;
61
75
  private applyOwnershipCondition;
62
76
  private findOwnedEntity;
77
+ private isStatusPipelineConfigured;
78
+ private applyInitialStatus;
79
+ private validateStatusTransition;
80
+ private runTransitionActions;
81
+ private canBypassOwnershipForTransition;
63
82
  findAll(query: PaginationDto & FilterDto): Promise<{
64
83
  data: ResponseDto[];
65
84
  meta: {
@@ -79,6 +98,8 @@ export declare class NestCrudService<Entity extends ObjectLiteral, CreateDto = P
79
98
  findOne(id: number, user?: OwnershipUser): Promise<ResponseDto>;
80
99
  create(payload: CreateDto, user?: OwnershipUser): Promise<ResponseDto>;
81
100
  update(id: number, payload: UpdateDto, user?: OwnershipUser): Promise<ResponseDto>;
101
+ changeStatus(id: number, status: StatusValue, user?: OwnershipUser): Promise<ResponseDto>;
102
+ private applyUpdateCore;
82
103
  remove(id: number, user?: OwnershipUser): Promise<boolean>;
83
104
  findAuditLogs(query: {
84
105
  user_id?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"nest-crud.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/nest-crud.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nest-crud.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/nest-crud.service.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ const pagination_helper_1 = require("../helpers/pagination.helper");
9
9
  const cursor_pagination_helper_1 = require("../helpers/cursor-pagination.helper");
10
10
  let NestCrudService = class NestCrudService {
11
11
  constructor(options) {
12
+ this.statusTransitions = new Map();
12
13
  this.repo = options.repository;
13
14
  this.allowedFilters = options.allowedFilters ?? [];
14
15
  this.allowedSortFields = options.allowedSortFields ?? [];
@@ -27,6 +28,50 @@ let NestCrudService = class NestCrudService {
27
28
  this.enforceOwnership = options.enforceOwnership ?? false;
28
29
  this.ownershipBypassPermissions = options.ownershipBypassPermissions ?? [];
29
30
  this.ownershipBypass = options.ownershipBypass;
31
+ this.superAdminPermission = options.superAdminPermission;
32
+ this.statusField = options.statusPipeline?.field;
33
+ this.statusInitial = options.statusPipeline?.initial;
34
+ this.statusOnTransition = options.statusPipeline?.onTransition;
35
+ this.statusCreateAllow = [
36
+ ...(options.statusPipeline?.initial !== undefined
37
+ ? [options.statusPipeline.initial]
38
+ : []),
39
+ ...(options.statusPipeline?.allowCreateStatuses ?? []),
40
+ ];
41
+ if (options.statusPipeline?.transitions) {
42
+ this.statusTransitions = this.normalizeStatusTransitions(options.statusPipeline.transitions);
43
+ }
44
+ }
45
+ normalizeStatusTransitions(transitions) {
46
+ const result = new Map();
47
+ const addEdge = (from, to, permission, action) => {
48
+ const existing = result.get(from) ?? {
49
+ to: new Set(),
50
+ permission: undefined,
51
+ action: undefined,
52
+ };
53
+ for (const target of to) {
54
+ existing.to.add(target);
55
+ }
56
+ if (permission !== undefined) {
57
+ existing.permission = permission;
58
+ }
59
+ if (action !== undefined) {
60
+ existing.action = action;
61
+ }
62
+ result.set(from, existing);
63
+ };
64
+ if (Array.isArray(transitions)) {
65
+ for (const edge of transitions) {
66
+ addEdge(edge.from, edge.to, edge.permission, edge.action);
67
+ }
68
+ }
69
+ else {
70
+ for (const [from, to] of Object.entries(transitions)) {
71
+ addEdge(from, to);
72
+ }
73
+ }
74
+ return result;
30
75
  }
31
76
  async resolveRelations(payload) {
32
77
  if (!this.relations.length)
@@ -128,16 +173,47 @@ let NestCrudService = class NestCrudService {
128
173
  isOwnershipConfigured() {
129
174
  return Boolean(this.userOwnershipField || this.findMineQuery);
130
175
  }
176
+ resolveUserPermissions(user) {
177
+ const out = new Set();
178
+ const add = (value) => {
179
+ if (Array.isArray(value)) {
180
+ value
181
+ .filter((item) => typeof item === 'string')
182
+ .forEach((permission) => out.add(permission));
183
+ }
184
+ };
185
+ add(user.permissions);
186
+ for (const rolesKey of ['userRoles', 'roles']) {
187
+ const rows = user[rolesKey];
188
+ if (!Array.isArray(rows))
189
+ continue;
190
+ for (const row of rows) {
191
+ if (!row || typeof row !== 'object')
192
+ continue;
193
+ const roleLike = row;
194
+ add(roleLike.permissions);
195
+ const nested = roleLike.role;
196
+ if (nested && typeof nested === 'object') {
197
+ add(nested.permissions);
198
+ }
199
+ }
200
+ }
201
+ return [...out];
202
+ }
131
203
  canBypassOwnership(user) {
132
204
  if (!user)
133
205
  return false;
206
+ if (this.superAdminPermission) {
207
+ const resolved = this.resolveUserPermissions(user);
208
+ if (resolved.includes(this.superAdminPermission)) {
209
+ return true;
210
+ }
211
+ }
134
212
  if (this.ownershipBypass && this.ownershipBypass(user)) {
135
213
  return true;
136
214
  }
137
215
  if (this.ownershipBypassPermissions.length > 0) {
138
- const userPermissions = Array.isArray(user.permissions)
139
- ? user.permissions
140
- : [];
216
+ const userPermissions = this.resolveUserPermissions(user);
141
217
  return this.ownershipBypassPermissions.some((permission) => userPermissions.includes(permission));
142
218
  }
143
219
  return false;
@@ -167,6 +243,78 @@ let NestCrudService = class NestCrudService {
167
243
  const rows = await qb.getMany();
168
244
  return rows[0] ?? null;
169
245
  }
246
+ isStatusPipelineConfigured() {
247
+ return Boolean(this.statusField);
248
+ }
249
+ applyInitialStatus(payload) {
250
+ if (!this.isStatusPipelineConfigured()) {
251
+ return;
252
+ }
253
+ const field = String(this.statusField);
254
+ const requested = payload[field];
255
+ if (requested === undefined) {
256
+ if (this.statusInitial !== undefined) {
257
+ payload[field] = this.statusInitial;
258
+ }
259
+ return;
260
+ }
261
+ if (this.statusCreateAllow.length > 0 &&
262
+ !this.statusCreateAllow.includes(requested)) {
263
+ throw new common_1.BadRequestException(`Invalid initial status '${String(requested)}'. Allowed: ${this.statusCreateAllow
264
+ .map(String)
265
+ .join(', ') || 'none'}`);
266
+ }
267
+ }
268
+ validateStatusTransition(existing, payload, user) {
269
+ if (!this.isStatusPipelineConfigured()) {
270
+ return null;
271
+ }
272
+ const field = String(this.statusField);
273
+ const requested = payload[field];
274
+ if (requested === undefined) {
275
+ return null;
276
+ }
277
+ const current = existing[field];
278
+ const requestedValue = requested;
279
+ if (current === requestedValue) {
280
+ return null;
281
+ }
282
+ const entry = this.statusTransitions.get(current);
283
+ if (!entry) {
284
+ throw new common_1.BadRequestException(`Invalid status transition: '${String(current)}' -> '${String(requestedValue)}'. Status '${String(current)}' has no allowed transitions`);
285
+ }
286
+ if (!entry.to.has(requestedValue)) {
287
+ throw new common_1.BadRequestException(`Invalid status transition: '${String(current)}' -> '${String(requestedValue)}'. Allowed: ${[...entry.to].map(String).join(', ')}`);
288
+ }
289
+ if (entry.permission && !this.canBypassOwnershipForTransition(user, entry.permission)) {
290
+ throw new common_1.ForbiddenException(`Missing required permission '${entry.permission}' for status transition`);
291
+ }
292
+ return {
293
+ from: current,
294
+ to: requestedValue,
295
+ action: entry.action,
296
+ };
297
+ }
298
+ async runTransitionActions(transition, id, entity, user) {
299
+ const context = {
300
+ id,
301
+ entity,
302
+ from: transition.from,
303
+ to: transition.to,
304
+ user,
305
+ };
306
+ if (transition.action) {
307
+ await transition.action(context);
308
+ }
309
+ if (this.statusOnTransition) {
310
+ await this.statusOnTransition(context);
311
+ }
312
+ }
313
+ canBypassOwnershipForTransition(user, permission) {
314
+ if (!user)
315
+ return false;
316
+ return this.resolveUserPermissions(user).includes(permission);
317
+ }
170
318
  async findAll(query) {
171
319
  const qb = this.repo.createQueryBuilder('e');
172
320
  this.applyIncludeJoins(qb);
@@ -296,6 +444,7 @@ let NestCrudService = class NestCrudService {
296
444
  }
297
445
  }
298
446
  }
447
+ this.applyInitialStatus(payload);
299
448
  await this.executeHook(this.hooks.beforeCreate, { payload });
300
449
  const payloadSnapshot = { ...payload };
301
450
  const resolved = await this.resolveRelations(payload);
@@ -307,6 +456,16 @@ let NestCrudService = class NestCrudService {
307
456
  return result;
308
457
  }
309
458
  async update(id, payload, user) {
459
+ return this.applyUpdateCore(id, payload, user);
460
+ }
461
+ async changeStatus(id, status, user) {
462
+ if (!this.isStatusPipelineConfigured()) {
463
+ throw new common_1.NotFoundException('Resource not found');
464
+ }
465
+ const payload = { [String(this.statusField)]: status };
466
+ return this.applyUpdateCore(id, payload, user);
467
+ }
468
+ async applyUpdateCore(id, payload, user) {
310
469
  let existing;
311
470
  if (this.enforceOwnershipFor(user)) {
312
471
  existing = await this.findOwnedEntity(id, user);
@@ -320,12 +479,16 @@ let NestCrudService = class NestCrudService {
320
479
  throw new common_1.NotFoundException('Resource not found');
321
480
  }
322
481
  await this.executeHook(this.hooks.beforeUpdate, { payload, entity: existing, id });
482
+ const transition = this.validateStatusTransition(existing, payload, user);
323
483
  const payloadSnapshot = { ...payload };
324
484
  const resolved = await this.resolveRelations(payload);
325
485
  this.repo.merge(existing, resolved);
326
486
  await this.repo.save(existing);
327
487
  const result = await this.findOne(id, user);
328
488
  await this.executeHook(this.hooks.afterUpdate, { entity: result, payload: payloadSnapshot, id });
489
+ if (transition) {
490
+ await this.runTransitionActions(transition, id, existing, user);
491
+ }
329
492
  return result;
330
493
  }
331
494
  async remove(id, user) {
@@ -1 +1 @@
1
- {"version":3,"file":"crud-controller.test-suites.d.ts","sourceRoot":"","sources":["../../../src/lib/testing/crud-controller.test-suites.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAMxC,OAAO,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGhF,wBAAgB,mBAAmB,CACjC,OAAO,SAAS,aAAa,EAC7B,UAAU,EACV,UAAU,EACV,YAAY,EAEZ,MAAM,EAAE,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,GAC9E,eAAe,CAuNjB"}
1
+ {"version":3,"file":"crud-controller.test-suites.d.ts","sourceRoot":"","sources":["../../../src/lib/testing/crud-controller.test-suites.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAMxC,OAAO,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGhF,wBAAgB,mBAAmB,CACjC,OAAO,SAAS,aAAa,EAC7B,UAAU,EACV,UAAU,EACV,YAAY,EAEZ,MAAM,EAAE,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,GAC9E,eAAe,CA6OjB"}
@@ -17,6 +17,7 @@ function crudControllerTests(config) {
17
17
  findOne: jest.fn(),
18
18
  create: jest.fn(),
19
19
  update: jest.fn(),
20
+ changeStatus: jest.fn(),
20
21
  remove: jest.fn(),
21
22
  findAuditLogs: jest.fn(),
22
23
  findMine: jest.fn(),
@@ -95,6 +96,20 @@ function crudControllerTests(config) {
95
96
  expect(result).toEqual(expectedResult);
96
97
  });
97
98
  });
99
+ describe('changeStatus', () => {
100
+ it('should call service.changeStatus with id and status', async () => {
101
+ const dto = { status: 'approved' };
102
+ const expectedResult = { id: 1, status: 'approved' };
103
+ service.changeStatus.mockResolvedValue(expectedResult);
104
+ const result = await controller.changeStatus?.(1, dto);
105
+ expect(service.changeStatus).toHaveBeenCalledWith(1, 'approved', undefined);
106
+ expect(result).toEqual(expectedResult);
107
+ });
108
+ it('should throw when status endpoint is not available', () => {
109
+ service.changeStatus = undefined;
110
+ expect(() => controller.changeStatus?.(1, { status: 'x' })).toThrow(common_1.NotFoundException);
111
+ });
112
+ });
98
113
  describe('remove', () => {
99
114
  it('should call service.remove', async () => {
100
115
  service.remove.mockResolvedValue(true);
@@ -28,7 +28,7 @@ export interface CrudTestConfig<TEntity extends ObjectLiteral, TCreateDto, TUpda
28
28
  export interface CrudControllerTestConfig<TEntity extends ObjectLiteral, TCreateDto, TUpdateDto, TResponseDto> extends Omit<CrudTestConfig<TEntity, TCreateDto, TUpdateDto, TResponseDto>, 'serviceClass'> {
29
29
  controllerFactory: () => Type<any>;
30
30
  serviceClass: Type<any>;
31
- permissions?: Record<CrudEndpoint, string | string[]>;
31
+ permissions?: Partial<Record<CrudEndpoint, string | string[]>>;
32
32
  authOptions?: Record<string, unknown>;
33
33
  }
34
34
  export interface CrudTestContext {
@@ -1 +1 @@
1
- {"version":3,"file":"testing.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/testing/testing.interface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"testing.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/testing/testing.interface.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nest-util/nest-crud",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",