Skip to content

Commit 83a8bb7

Browse files
Merge pull request #369 from andrechristikan/development
Development
2 parents 4a5c348 + 17bf3fe commit 83a8bb7

20 files changed

+1499
-1325
lines changed

package.json

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ack-nestjs-boilerplate",
3-
"version": "4.2.3",
3+
"version": "4.2.5",
44
"description": "Ack NestJs Boilerplate",
55
"repository": {
66
"type": "git",
@@ -52,7 +52,7 @@
5252
"rollback": "yarn rollback:setting && yarn rollback:apikey && yarn rollback:user && yarn rollback:role && yarn rollback:permission"
5353
},
5454
"dependencies": {
55-
"@aws-sdk/client-s3": "^3.245.0",
55+
"@aws-sdk/client-s3": "^3.259.0",
5656
"@faker-js/faker": "^7.6.0",
5757
"@joi/date": "^2.1.0",
5858
"@nestjs/axios": "^1.0.1",
@@ -76,7 +76,7 @@
7676
"helmet": "^6.0.1",
7777
"joi": "^17.7.0",
7878
"moment": "^2.29.4",
79-
"mongoose": "^6.8.3",
79+
"mongoose": "^6.9.0",
8080
"morgan": "^1.10.0",
8181
"nest-winston": "^1.8.0",
8282
"nestjs-command": "^3.1.3",
@@ -86,28 +86,28 @@
8686
"passport-jwt": "^4.0.1",
8787
"reflect-metadata": "^0.1.13",
8888
"response-time": "^2.3.2",
89-
"rimraf": "^4.0.4",
89+
"rimraf": "^4.1.2",
9090
"rotating-file-stream": "^3.0.4",
9191
"rxjs": "^7.8.0",
92-
"ua-parser-js": "^1.0.32",
92+
"ua-parser-js": "^1.0.33",
9393
"winston": "^3.8.2",
9494
"winston-daily-rotate-file": "^4.7.1",
9595
"xlsx": "^0.18.5",
9696
"yargs": "^17.6.2",
9797
"yarn": "^1.22.19"
9898
},
9999
"devDependencies": {
100-
"@nestjs/cli": "^9.1.8",
100+
"@nestjs/cli": "^9.1.9",
101101
"@nestjs/schematics": "^9.0.4",
102102
"@nestjs/testing": "^9.2.1",
103103
"@types/bcryptjs": "^2.4.2",
104104
"@types/bytes": "^3.1.1",
105105
"@types/cors": "^2.8.13",
106106
"@types/cron": "^2.0.0",
107107
"@types/crypto-js": "^4.1.1",
108-
"@types/express": "^4.17.15",
108+
"@types/express": "^4.17.16",
109109
"@types/express-rate-limit": "^6.0.0",
110-
"@types/jest": "^29.2.5",
110+
"@types/jest": "^29.4.0",
111111
"@types/lodash": "^4.14.191",
112112
"@types/morgan": "^1.9.4",
113113
"@types/ms": "^0.7.31",
@@ -117,14 +117,14 @@
117117
"@types/supertest": "^2.0.12",
118118
"@types/ua-parser-js": "^0.7.36",
119119
"@types/uuid": "^9.0.0",
120-
"@typescript-eslint/eslint-plugin": "^5.48.1",
121-
"@typescript-eslint/parser": "^5.48.1",
122-
"cspell": "^6.18.1",
123-
"eslint": "^8.31.0",
120+
"@typescript-eslint/eslint-plugin": "^5.49.0",
121+
"@typescript-eslint/parser": "^5.49.0",
122+
"cspell": "^6.19.2",
123+
"eslint": "^8.32.0",
124124
"eslint-config-prettier": "^8.6.0",
125-
"eslint-plugin-import": "^2.27.4",
125+
"eslint-plugin-import": "^2.27.5",
126126
"husky": "^8.0.3",
127-
"jest": "^29.3.1",
127+
"jest": "^29.4.1",
128128
"prettier": "^2.8.3",
129129
"supertest": "^6.3.3",
130130
"ts-jest": "^29.0.5",

src/common/api-key/serializations/api-key.get.serialization.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,22 @@ export class ApiKeyGetSerialization {
4242
})
4343
isActive: boolean;
4444

45+
@ApiProperty({
46+
description: 'Api Key start date',
47+
example: faker.date.recent(),
48+
required: false,
49+
nullable: true,
50+
})
51+
startDate?: Date;
52+
53+
@ApiProperty({
54+
description: 'Api Key end date',
55+
example: faker.date.recent(),
56+
required: false,
57+
nullable: true,
58+
})
59+
endDate?: Date;
60+
4561
@ApiProperty({
4662
description: 'Date created at',
4763
example: faker.date.recent(),

src/common/database/abstracts/database.base-repository.abstract.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
IDatabaseRestoreManyOptions,
1313
IDatabaseUpdateOptions,
1414
IDatabaseDeleteOptions,
15+
IDatabaseRawOptions,
1516
} from 'src/common/database/interfaces/database.interface';
1617

1718
export abstract class DatabaseBaseRepositoryAbstract<T> {
@@ -46,7 +47,10 @@ export abstract class DatabaseBaseRepositoryAbstract<T> {
4647
options?: IDatabaseExistOptions<any>
4748
): Promise<boolean>;
4849

49-
abstract raw<N, R = any>(rawOperation: R): Promise<N[]>;
50+
abstract raw<N, R = any>(
51+
rawOperation: R,
52+
options?: IDatabaseRawOptions
53+
): Promise<N[]>;
5054

5155
abstract create<N>(
5256
data: N,

src/common/database/abstracts/mongo/repositories/database.mongo.object-id.repository.abstract.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
IDatabaseRestoreManyOptions,
2323
IDatabaseUpdateOptions,
2424
IDatabaseDeleteOptions,
25+
IDatabaseRawOptions,
2526
} from 'src/common/database/interfaces/database.interface';
2627
import { IDatabaseRepository } from 'src/common/database/interfaces/database.repository.interface';
2728
import { ENUM_PAGINATION_SORT_TYPE } from 'src/common/pagination/constants/pagination.enum.constant';
@@ -314,12 +315,46 @@ export abstract class DatabaseMongoObjectIdRepositoryAbstract<T>
314315
return result ? true : false;
315316
}
316317

317-
async raw<N, R = PipelineStage[]>(rawOperation: R): Promise<N[]> {
318+
async raw<N, R = PipelineStage[]>(
319+
rawOperation: R,
320+
options?: IDatabaseRawOptions
321+
): Promise<N[]> {
318322
if (!Array.isArray(rawOperation)) {
319323
throw new Error('Must in array');
320324
}
321325

322-
return this._repository.aggregate<N>(rawOperation);
326+
const pipeline: PipelineStage[] = rawOperation;
327+
328+
if (options?.withDeleted) {
329+
pipeline.push({
330+
$match: {
331+
$or: [
332+
{
333+
[DATABASE_DELETED_AT_FIELD_NAME]: {
334+
$exists: false,
335+
},
336+
},
337+
{
338+
[DATABASE_DELETED_AT_FIELD_NAME]: { $exists: true },
339+
},
340+
],
341+
},
342+
});
343+
} else {
344+
pipeline.push({
345+
$match: {
346+
[DATABASE_DELETED_AT_FIELD_NAME]: { $exists: false },
347+
},
348+
});
349+
}
350+
351+
const aggregate = this._repository.aggregate<N>(pipeline);
352+
353+
if (options?.session) {
354+
aggregate.session(options?.session);
355+
}
356+
357+
return aggregate;
323358
}
324359

325360
async create<N>(

src/common/database/abstracts/mongo/repositories/database.mongo.uuid.repository.abstract.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
IDatabaseRestoreManyOptions,
2222
IDatabaseUpdateOptions,
2323
IDatabaseDeleteOptions,
24+
IDatabaseRawOptions,
2425
} from 'src/common/database/interfaces/database.interface';
2526
import { IDatabaseRepository } from 'src/common/database/interfaces/database.repository.interface';
2627
import { ENUM_PAGINATION_SORT_TYPE } from 'src/common/pagination/constants/pagination.enum.constant';
@@ -310,12 +311,46 @@ export abstract class DatabaseMongoUUIDRepositoryAbstract<T>
310311
return result ? true : false;
311312
}
312313

313-
async raw<N, R = PipelineStage[]>(rawOperation: R): Promise<N[]> {
314+
async raw<N, R = PipelineStage[]>(
315+
rawOperation: R,
316+
options?: IDatabaseRawOptions
317+
): Promise<N[]> {
314318
if (!Array.isArray(rawOperation)) {
315319
throw new Error('Must in array');
316320
}
317321

318-
return this._repository.aggregate<N>(rawOperation);
322+
const pipeline: PipelineStage[] = rawOperation;
323+
324+
if (options?.withDeleted) {
325+
pipeline.push({
326+
$match: {
327+
$or: [
328+
{
329+
[DATABASE_DELETED_AT_FIELD_NAME]: {
330+
$exists: false,
331+
},
332+
},
333+
{
334+
[DATABASE_DELETED_AT_FIELD_NAME]: { $exists: true },
335+
},
336+
],
337+
},
338+
});
339+
} else {
340+
pipeline.push({
341+
$match: {
342+
[DATABASE_DELETED_AT_FIELD_NAME]: { $exists: false },
343+
},
344+
});
345+
}
346+
347+
const aggregate = this._repository.aggregate<N>(pipeline);
348+
349+
if (options?.session) {
350+
aggregate.session(options?.session);
351+
}
352+
353+
return aggregate;
319354
}
320355

321356
async create<N>(

src/common/database/interfaces/database.interface.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,8 @@ export type IDatabaseCreateManyOptions<T = any> = Pick<
6565
export type IDatabaseSoftDeleteManyOptions<T = any> = IDatabaseManyOptions<T>;
6666

6767
export type IDatabaseRestoreManyOptions<T = any> = IDatabaseManyOptions<T>;
68+
69+
export type IDatabaseRawOptions<T = any> = Pick<
70+
IDatabaseOptions<T>,
71+
'session' | 'withDeleted'
72+
>;

src/common/helper/interfaces/helper.date-service.interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {
55
IHelperDateOptionsDiff,
66
IHelperDateOptionsFormat,
77
IHelperDateOptionsForward,
8+
IHelperDateStartAndEnd,
9+
IHelperDateStartAndEndDate,
810
} from 'src/common/helper/interfaces/helper.interface';
911

1012
export interface IHelperDateService {
@@ -90,4 +92,8 @@ export interface IHelperDateService {
9092
startOfDay(date?: Date): Date;
9193

9294
extractDate(date: string | Date | number): IHelperDateExtractDate;
95+
96+
getStartAndEndDate(
97+
options?: IHelperDateStartAndEnd
98+
): IHelperDateStartAndEndDate;
9399
}

src/common/helper/interfaces/helper.interface.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ export interface IHelperGeoRules extends IHelperGeoCurrent {
4141
}
4242

4343
// Helper Date
44+
export interface IHelperDateStartAndEnd {
45+
month?: number;
46+
year?: number;
47+
}
48+
49+
export interface IHelperDateStartAndEndDate {
50+
startDate: Date;
51+
endDate: Date;
52+
}
53+
4454
export interface IHelperDateExtractDate {
4555
date: Date;
4656
day: string;

src/common/helper/services/helper.date.service.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {
1313
IHelperDateOptionsFormat,
1414
IHelperDateOptionsForward,
1515
IHelperDateOptionsRoundDown,
16+
IHelperDateStartAndEnd,
17+
IHelperDateStartAndEndDate,
1618
} from 'src/common/helper/interfaces/helper.interface';
1719

1820
@Injectable()
@@ -213,4 +215,35 @@ export class HelperDateService implements IHelperDateService {
213215

214216
return mDate.toDate();
215217
}
218+
219+
getStartAndEndDate(
220+
options?: IHelperDateStartAndEnd
221+
): IHelperDateStartAndEndDate {
222+
const today = moment();
223+
const todayMonth = Number(
224+
today.format(ENUM_HELPER_DATE_FORMAT.ONLY_MONTH)
225+
);
226+
const todayYear = Number(
227+
today.format(ENUM_HELPER_DATE_FORMAT.ONLY_YEAR)
228+
);
229+
230+
// set month and year
231+
const year = options?.year ?? todayYear;
232+
const month = options?.month ?? todayMonth;
233+
234+
const date = moment(`${year}-${month}-02`);
235+
let startDate: Date = date.startOf('year').toDate();
236+
let endDate: Date = date.endOf('year').toDate();
237+
238+
if (options?.month) {
239+
const date = moment(`${year}-${month}-02`);
240+
startDate = date.startOf('month').toDate();
241+
endDate = date.endOf('month').toDate();
242+
}
243+
244+
return {
245+
startDate,
246+
endDate,
247+
};
248+
}
216249
}

src/common/pagination/pipes/pagination.filter-contain.pipe.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ export function PaginationFilterContainPipe(
1414
async transform(
1515
value: string,
1616
{ data: field }: ArgumentMetadata
17-
): Promise<Record<string, any>> {
17+
): Promise<Record<string, { $regex: RegExp; $options: string }>> {
1818
if (!value) {
19-
return undefined;
19+
value = '';
2020
}
2121

2222
if (
@@ -33,10 +33,7 @@ export function PaginationFilterContainPipe(
3333
value = value.trim();
3434
}
3535

36-
const filter: Record<string, any> =
37-
this.paginationService.filterContain(field, value);
38-
39-
return filter;
36+
return this.paginationService.filterContain(field, value);
4037
}
4138
}
4239

0 commit comments

Comments
 (0)