@flusys/nestjs-shared 6.0.1 → 6.1.0
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/cjs/classes/api-controller.class.spec.js +684 -0
- package/cjs/classes/api-service.class.spec.js +809 -0
- package/cjs/classes/handle-custome-db.spec.js +82 -0
- package/cjs/classes/hybrid-cache.class.spec.js +168 -0
- package/cjs/classes/winston.logger.class.spec.js +330 -0
- package/cjs/constants/index.js +1 -1
- package/cjs/decorators/api-response.decorator.spec.js +126 -0
- package/cjs/decorators/current-user.decorator.spec.js +74 -0
- package/cjs/decorators/log-action.decorator.spec.js +353 -0
- package/cjs/decorators/public.decorator.spec.js +50 -0
- package/cjs/decorators/require-permission.decorator.spec.js +147 -0
- package/cjs/exceptions/base-app.exception.spec.js +157 -0
- package/cjs/exceptions/permission.exception.spec.js +82 -0
- package/cjs/filters/global-exception.filter.spec.js +440 -0
- package/cjs/guards/jwt-auth.guard.spec.js +75 -0
- package/cjs/guards/optional-jwt-auth.guard.spec.js +55 -0
- package/cjs/guards/permission.guard.js +11 -10
- package/cjs/guards/permission.guard.spec.js +358 -0
- package/cjs/interceptors/delete-empty-id-from-body.interceptor.spec.js +107 -0
- package/cjs/interceptors/idempotency.interceptor.spec.js +116 -0
- package/cjs/interceptors/response-meta.interceptor.spec.js +89 -0
- package/cjs/interceptors/set-user-field-on-body.interceptor.spec.js +128 -0
- package/cjs/interceptors/slug.interceptor.spec.js +110 -0
- package/cjs/interfaces/index.js +1 -0
- package/cjs/interfaces/permission-sync-adapter.interface.js +11 -0
- package/cjs/middlewares/logger.middleware.spec.js +462 -0
- package/cjs/modules/cache/cache.module.spec.js +48 -0
- package/cjs/modules/datasource/multi-tenant-datasource.service.spec.js +381 -0
- package/cjs/modules/utils/utils.service.spec.js +169 -0
- package/cjs/utils/date-time.util.spec.js +84 -0
- package/cjs/utils/html-sanitizer.util.spec.js +76 -0
- package/cjs/utils/index.js +1 -0
- package/cjs/utils/permission-cache-key.util.js +31 -0
- package/cjs/utils/permission-cache-key.util.spec.js +88 -0
- package/cjs/utils/query-helpers.util.spec.js +209 -0
- package/cjs/utils/request.util.spec.js +249 -0
- package/cjs/utils/string.util.spec.js +63 -0
- package/constants/index.d.ts +1 -1
- package/fesm/classes/api-controller.class.spec.js +680 -0
- package/fesm/classes/api-service.class.spec.js +805 -0
- package/fesm/classes/handle-custome-db.spec.js +78 -0
- package/fesm/classes/hybrid-cache.class.spec.js +164 -0
- package/fesm/classes/winston.logger.class.spec.js +327 -0
- package/fesm/constants/index.js +1 -1
- package/fesm/decorators/api-response.decorator.spec.js +122 -0
- package/fesm/decorators/current-user.decorator.spec.js +73 -0
- package/fesm/decorators/log-action.decorator.spec.js +349 -0
- package/fesm/decorators/public.decorator.spec.js +46 -0
- package/fesm/decorators/require-permission.decorator.spec.js +143 -0
- package/fesm/exceptions/base-app.exception.spec.js +153 -0
- package/fesm/exceptions/permission.exception.spec.js +78 -0
- package/fesm/filters/global-exception.filter.spec.js +436 -0
- package/fesm/guards/jwt-auth.guard.spec.js +71 -0
- package/fesm/guards/optional-jwt-auth.guard.spec.js +51 -0
- package/fesm/guards/permission.guard.js +12 -11
- package/fesm/guards/permission.guard.spec.js +354 -0
- package/fesm/interceptors/delete-empty-id-from-body.interceptor.spec.js +103 -0
- package/fesm/interceptors/idempotency.interceptor.spec.js +112 -0
- package/fesm/interceptors/response-meta.interceptor.spec.js +85 -0
- package/fesm/interceptors/set-user-field-on-body.interceptor.spec.js +124 -0
- package/fesm/interceptors/slug.interceptor.spec.js +106 -0
- package/fesm/interfaces/index.js +1 -0
- package/fesm/interfaces/permission-sync-adapter.interface.js +1 -0
- package/fesm/middlewares/logger.middleware.spec.js +459 -0
- package/fesm/modules/cache/cache.module.spec.js +44 -0
- package/fesm/modules/datasource/multi-tenant-datasource.service.spec.js +377 -0
- package/fesm/modules/utils/utils.service.spec.js +165 -0
- package/fesm/utils/date-time.util.spec.js +80 -0
- package/fesm/utils/html-sanitizer.util.spec.js +72 -0
- package/fesm/utils/index.js +1 -0
- package/fesm/utils/permission-cache-key.util.js +10 -0
- package/fesm/utils/permission-cache-key.util.spec.js +84 -0
- package/fesm/utils/query-helpers.util.spec.js +205 -0
- package/fesm/utils/request.util.spec.js +245 -0
- package/fesm/utils/string.util.spec.js +59 -0
- package/guards/permission.guard.d.ts +0 -1
- package/interfaces/index.d.ts +1 -0
- package/interfaces/permission-sync-adapter.interface.d.ts +7 -0
- package/package.json +2 -2
- package/utils/index.d.ts +1 -0
- package/utils/permission-cache-key.util.d.ts +9 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _rxjs = require("rxjs");
|
|
6
|
+
const _setuserfieldonbodyinterceptor = require("./set-user-field-on-body.interceptor");
|
|
7
|
+
function buildContext(body, user) {
|
|
8
|
+
const request = {
|
|
9
|
+
body,
|
|
10
|
+
user
|
|
11
|
+
};
|
|
12
|
+
const context = {
|
|
13
|
+
switchToHttp: ()=>({
|
|
14
|
+
getRequest: ()=>request
|
|
15
|
+
})
|
|
16
|
+
};
|
|
17
|
+
return {
|
|
18
|
+
context,
|
|
19
|
+
request
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function buildCallHandler() {
|
|
23
|
+
return {
|
|
24
|
+
handle: jest.fn().mockReturnValue((0, _rxjs.of)('next-result'))
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
describe('createSetUserFieldInterceptor', ()=>{
|
|
28
|
+
it('should set the field on a single object body from the authenticated user', ()=>{
|
|
29
|
+
const Interceptor = (0, _setuserfieldonbodyinterceptor.createSetUserFieldInterceptor)('createdById');
|
|
30
|
+
const interceptor = new Interceptor();
|
|
31
|
+
const { context, request } = buildContext({
|
|
32
|
+
name: 'Product'
|
|
33
|
+
}, {
|
|
34
|
+
id: 'user-1'
|
|
35
|
+
});
|
|
36
|
+
interceptor.intercept(context, buildCallHandler());
|
|
37
|
+
expect(request.body).toEqual({
|
|
38
|
+
name: 'Product',
|
|
39
|
+
createdById: 'user-1'
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
it('should set the field on every item of an array body', ()=>{
|
|
43
|
+
const Interceptor = (0, _setuserfieldonbodyinterceptor.createSetUserFieldInterceptor)('updatedById');
|
|
44
|
+
const interceptor = new Interceptor();
|
|
45
|
+
const { context, request } = buildContext([
|
|
46
|
+
{
|
|
47
|
+
name: 'A'
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'B'
|
|
51
|
+
}
|
|
52
|
+
], {
|
|
53
|
+
id: 'user-2'
|
|
54
|
+
});
|
|
55
|
+
interceptor.intercept(context, buildCallHandler());
|
|
56
|
+
expect(request.body).toEqual([
|
|
57
|
+
{
|
|
58
|
+
name: 'A',
|
|
59
|
+
updatedById: 'user-2'
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'B',
|
|
63
|
+
updatedById: 'user-2'
|
|
64
|
+
}
|
|
65
|
+
]);
|
|
66
|
+
});
|
|
67
|
+
it('should not modify the body when there is no authenticated user', ()=>{
|
|
68
|
+
const Interceptor = (0, _setuserfieldonbodyinterceptor.createSetUserFieldInterceptor)('deletedById');
|
|
69
|
+
const interceptor = new Interceptor();
|
|
70
|
+
const { context, request } = buildContext({
|
|
71
|
+
name: 'Product'
|
|
72
|
+
}, undefined);
|
|
73
|
+
interceptor.intercept(context, buildCallHandler());
|
|
74
|
+
expect(request.body).toEqual({
|
|
75
|
+
name: 'Product'
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
it('should not throw when body is null and there is no user', ()=>{
|
|
79
|
+
const Interceptor = (0, _setuserfieldonbodyinterceptor.createSetUserFieldInterceptor)('createdById');
|
|
80
|
+
const interceptor = new Interceptor();
|
|
81
|
+
const { context, request } = buildContext(null, undefined);
|
|
82
|
+
expect(()=>interceptor.intercept(context, buildCallHandler())).not.toThrow();
|
|
83
|
+
expect(request.body).toBeNull();
|
|
84
|
+
});
|
|
85
|
+
it('should return next.handle() observable', (done)=>{
|
|
86
|
+
const Interceptor = (0, _setuserfieldonbodyinterceptor.createSetUserFieldInterceptor)('createdById');
|
|
87
|
+
const interceptor = new Interceptor();
|
|
88
|
+
const { context } = buildContext({}, {
|
|
89
|
+
id: 'user-1'
|
|
90
|
+
});
|
|
91
|
+
interceptor.intercept(context, buildCallHandler()).subscribe((value)=>{
|
|
92
|
+
expect(value).toBe('next-result');
|
|
93
|
+
done();
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
describe('preconfigured user-field interceptors', ()=>{
|
|
98
|
+
it('should set createdById via SetCreatedByOnBody', ()=>{
|
|
99
|
+
const interceptor = new _setuserfieldonbodyinterceptor.SetCreatedByOnBody();
|
|
100
|
+
const { context, request } = buildContext({}, {
|
|
101
|
+
id: 'user-1'
|
|
102
|
+
});
|
|
103
|
+
interceptor.intercept(context, buildCallHandler());
|
|
104
|
+
expect(request.body).toEqual({
|
|
105
|
+
createdById: 'user-1'
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
it('should set updatedById via SetUpdateByOnBody', ()=>{
|
|
109
|
+
const interceptor = new _setuserfieldonbodyinterceptor.SetUpdateByOnBody();
|
|
110
|
+
const { context, request } = buildContext({}, {
|
|
111
|
+
id: 'user-1'
|
|
112
|
+
});
|
|
113
|
+
interceptor.intercept(context, buildCallHandler());
|
|
114
|
+
expect(request.body).toEqual({
|
|
115
|
+
updatedById: 'user-1'
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
it('should set deletedById via SetDeletedByOnBody', ()=>{
|
|
119
|
+
const interceptor = new _setuserfieldonbodyinterceptor.SetDeletedByOnBody();
|
|
120
|
+
const { context, request } = buildContext({}, {
|
|
121
|
+
id: 'user-1'
|
|
122
|
+
});
|
|
123
|
+
interceptor.intercept(context, buildCallHandler());
|
|
124
|
+
expect(request.body).toEqual({
|
|
125
|
+
deletedById: 'user-1'
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _rxjs = require("rxjs");
|
|
6
|
+
const _sluginterceptor = require("./slug.interceptor");
|
|
7
|
+
function buildContext(body) {
|
|
8
|
+
const request = {
|
|
9
|
+
body
|
|
10
|
+
};
|
|
11
|
+
const context = {
|
|
12
|
+
switchToHttp: ()=>({
|
|
13
|
+
getRequest: ()=>request
|
|
14
|
+
})
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
context,
|
|
18
|
+
request
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function buildCallHandler() {
|
|
22
|
+
return {
|
|
23
|
+
handle: jest.fn().mockReturnValue((0, _rxjs.of)('next-result'))
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
describe('Slug interceptor', ()=>{
|
|
27
|
+
let utilsService;
|
|
28
|
+
let interceptor;
|
|
29
|
+
beforeEach(()=>{
|
|
30
|
+
utilsService = {
|
|
31
|
+
transformToSlug: jest.fn((value)=>value.toLowerCase().replace(/\s+/g, '-'))
|
|
32
|
+
};
|
|
33
|
+
interceptor = new _sluginterceptor.Slug(utilsService);
|
|
34
|
+
});
|
|
35
|
+
it('should generate a slug from name on a single object body without one', ()=>{
|
|
36
|
+
const { context, request } = buildContext({
|
|
37
|
+
name: 'My Product'
|
|
38
|
+
});
|
|
39
|
+
interceptor.intercept(context, buildCallHandler());
|
|
40
|
+
expect(utilsService.transformToSlug).toHaveBeenCalledWith('My Product');
|
|
41
|
+
expect(request.body).toEqual({
|
|
42
|
+
name: 'My Product',
|
|
43
|
+
slug: 'my-product'
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
it('should not overwrite an existing slug on a single object body', ()=>{
|
|
47
|
+
const { context, request } = buildContext({
|
|
48
|
+
name: 'My Product',
|
|
49
|
+
slug: 'custom-slug'
|
|
50
|
+
});
|
|
51
|
+
interceptor.intercept(context, buildCallHandler());
|
|
52
|
+
expect(utilsService.transformToSlug).not.toHaveBeenCalled();
|
|
53
|
+
expect(request.body).toEqual({
|
|
54
|
+
name: 'My Product',
|
|
55
|
+
slug: 'custom-slug'
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
it('should not generate a slug when there is no name', ()=>{
|
|
59
|
+
const { context, request } = buildContext({
|
|
60
|
+
description: 'no name here'
|
|
61
|
+
});
|
|
62
|
+
interceptor.intercept(context, buildCallHandler());
|
|
63
|
+
expect(utilsService.transformToSlug).not.toHaveBeenCalled();
|
|
64
|
+
expect(request.body).toEqual({
|
|
65
|
+
description: 'no name here'
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
it('should generate slugs for each array item missing one', ()=>{
|
|
69
|
+
const { context, request } = buildContext([
|
|
70
|
+
{
|
|
71
|
+
name: 'Item One'
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'Item Two',
|
|
75
|
+
slug: 'existing'
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
description: 'no name'
|
|
79
|
+
}
|
|
80
|
+
]);
|
|
81
|
+
interceptor.intercept(context, buildCallHandler());
|
|
82
|
+
expect(request.body).toEqual([
|
|
83
|
+
{
|
|
84
|
+
name: 'Item One',
|
|
85
|
+
slug: 'item-one'
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'Item Two',
|
|
89
|
+
slug: 'existing'
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
description: 'no name'
|
|
93
|
+
}
|
|
94
|
+
]);
|
|
95
|
+
});
|
|
96
|
+
it('should not throw when body is undefined', ()=>{
|
|
97
|
+
const { context, request } = buildContext(undefined);
|
|
98
|
+
expect(()=>interceptor.intercept(context, buildCallHandler())).not.toThrow();
|
|
99
|
+
expect(request.body).toBeUndefined();
|
|
100
|
+
});
|
|
101
|
+
it('should return next.handle() observable', (done)=>{
|
|
102
|
+
const { context } = buildContext({
|
|
103
|
+
name: 'X'
|
|
104
|
+
});
|
|
105
|
+
interceptor.intercept(context, buildCallHandler()).subscribe((value)=>{
|
|
106
|
+
expect(value).toBe('next-result');
|
|
107
|
+
done();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
package/cjs/interfaces/index.js
CHANGED
|
@@ -11,6 +11,7 @@ _export_star(require("./logged-user-info.interface"), exports);
|
|
|
11
11
|
_export_star(require("./module-config.interface"), exports);
|
|
12
12
|
_export_star(require("./notification-adapter.interface"), exports);
|
|
13
13
|
_export_star(require("./permission.interface"), exports);
|
|
14
|
+
_export_star(require("./permission-sync-adapter.interface"), exports);
|
|
14
15
|
function _export_star(from, to) {
|
|
15
16
|
Object.keys(from).forEach(function(k) {
|
|
16
17
|
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "PERMISSION_SYNC_ADAPTER", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return PERMISSION_SYNC_ADAPTER;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const PERMISSION_SYNC_ADAPTER = 'PERMISSION_SYNC_ADAPTER';
|