mm-share-lib 0.0.2 → 0.0.3

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/package.json CHANGED
@@ -1,78 +1,81 @@
1
- {
2
- "name": "mm-share-lib",
3
- "version": "0.0.2",
4
- "description": "Share the generic service, entity, dto.",
5
- "author": "Mesa SOT",
6
- "license": "MIT",
7
- "main": "dist/index.js",
8
- "types": "dist/index.d.ts",
9
- "scripts": {
10
- "build": "nest build",
11
- "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
12
- "start": "nest start",
13
- "start:dev": "nest start --watch",
14
- "start:debug": "nest start --debug --watch",
15
- "start:prod": "node dist/main",
16
- "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
17
- "test": "jest",
18
- "test:watch": "jest --watch",
19
- "test:cov": "jest --coverage",
20
- "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
21
- "test:e2e": "jest --config ./test/jest-e2e.json",
22
- "prepare": "husky install"
23
- },
24
- "dependencies": {
25
- "@babel/runtime": "^7.22.5",
26
- "@nestjs/common": "^9.4.2",
27
- "@nestjs/core": "^9.4.2",
28
- "@nestjs/platform-express": "^9.4.2",
29
- "@nestjs/typeorm": "^9.0.1",
30
- "class-transformer": "^0.5.1",
31
- "class-validator": "^0.14.0",
32
- "reflect-metadata": "^0.1.13",
33
- "rxjs": "^7.8.1",
34
- "typeorm": "^0.3.16",
35
- "typesense": "^1.5.4"
36
- },
37
- "devDependencies": {
38
- "@nestjs/cli": "^9.5.0",
39
- "@nestjs/schematics": "^9.2.0",
40
- "@nestjs/testing": "^9.4.2",
41
- "@types/express": "^4.17.17",
42
- "@types/jest": "29.5.2",
43
- "@types/node": "20.2.5",
44
- "@types/supertest": "^2.0.12",
45
- "@typescript-eslint/eslint-plugin": "^5.59.9",
46
- "@typescript-eslint/parser": "^5.59.9",
47
- "eslint": "^8.42.0",
48
- "eslint-config-prettier": "^8.8.0",
49
- "eslint-plugin-prettier": "^4.2.1",
50
- "husky": "^8.0.3",
51
- "jest": "29.5.0",
52
- "prettier": "^2.8.8",
53
- "source-map-support": "^0.5.21",
54
- "supertest": "^6.3.3",
55
- "ts-jest": "29.1.0",
56
- "ts-loader": "^9.4.3",
57
- "ts-node": "^10.9.1",
58
- "tsconfig-paths": "4.2.0",
59
- "typescript": "^5.1.3"
60
- },
61
- "jest": {
62
- "moduleFileExtensions": [
63
- "js",
64
- "json",
65
- "ts"
66
- ],
67
- "rootDir": "src",
68
- "testRegex": ".*\\.spec\\.ts$",
69
- "transform": {
70
- "^.+\\.(t|j)s$": "ts-jest"
71
- },
72
- "collectCoverageFrom": [
73
- "**/*.(t|j)s"
74
- ],
75
- "coverageDirectory": "../coverage",
76
- "testEnvironment": "node"
77
- }
78
- }
1
+ {
2
+ "name": "mm-share-lib",
3
+ "version": "0.0.3",
4
+ "description": "Share the generic service, entity, dto.",
5
+ "author": "Mesa SOT",
6
+ "license": "MIT",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "scripts": {
10
+ "build": "nest build",
11
+ "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
12
+ "start": "nest start",
13
+ "start:dev": "nest start --watch",
14
+ "start:debug": "nest start --debug --watch",
15
+ "start:prod": "node dist/main",
16
+ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
17
+ "test": "jest",
18
+ "test:watch": "jest --watch",
19
+ "test:cov": "jest --coverage",
20
+ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
21
+ "test:e2e": "jest --config ./test/jest-e2e.json",
22
+ "prepare": "husky install"
23
+ },
24
+ "dependencies": {
25
+ "@babel/runtime": "^7.22.5",
26
+ "@nestjs/common": "^9.4.2",
27
+ "@nestjs/core": "^9.4.2",
28
+ "@nestjs/platform-express": "^9.4.2",
29
+ "@nestjs/typeorm": "^9.0.1",
30
+ "class-transformer": "^0.5.1",
31
+ "class-validator": "^0.14.0",
32
+ "dayjs": "^1.11.8",
33
+ "reflect-metadata": "^0.1.13",
34
+ "rxjs": "^7.8.1",
35
+ "typeorm": "^0.3.16",
36
+ "bcrypt": "^5.1.0",
37
+ "typesense": "^1.5.4"
38
+ },
39
+ "devDependencies": {
40
+ "@nestjs/cli": "^9.5.0",
41
+ "@nestjs/schematics": "^9.2.0",
42
+ "@nestjs/testing": "^9.4.2",
43
+ "@types/bcrypt": "^5.0.0",
44
+ "@types/express": "^4.17.17",
45
+ "@types/jest": "29.5.2",
46
+ "@types/node": "20.2.5",
47
+ "@types/supertest": "^2.0.12",
48
+ "@typescript-eslint/eslint-plugin": "^5.59.9",
49
+ "@typescript-eslint/parser": "^5.59.9",
50
+ "eslint": "^8.42.0",
51
+ "eslint-config-prettier": "^8.8.0",
52
+ "eslint-plugin-prettier": "^4.2.1",
53
+ "husky": "^8.0.3",
54
+ "jest": "29.5.0",
55
+ "prettier": "^2.8.8",
56
+ "source-map-support": "^0.5.21",
57
+ "supertest": "^6.3.3",
58
+ "ts-jest": "29.1.0",
59
+ "ts-loader": "^9.4.3",
60
+ "ts-node": "^10.9.1",
61
+ "tsconfig-paths": "4.2.0",
62
+ "typescript": "^5.1.3"
63
+ },
64
+ "jest": {
65
+ "moduleFileExtensions": [
66
+ "js",
67
+ "json",
68
+ "ts"
69
+ ],
70
+ "rootDir": "src",
71
+ "testRegex": ".*\\.spec\\.ts$",
72
+ "transform": {
73
+ "^.+\\.(t|j)s$": "ts-jest"
74
+ },
75
+ "collectCoverageFrom": [
76
+ "**/*.(t|j)s"
77
+ ],
78
+ "coverageDirectory": "../coverage",
79
+ "testEnvironment": "node"
80
+ }
81
+ }
@@ -1,4 +1,4 @@
1
- export enum EntityStateConstant {
2
- Active = 1,
3
- Archived = 0,
4
- }
1
+ export enum EntityStateConstant {
2
+ Active = 1,
3
+ Archived = 0,
4
+ }
@@ -1 +1 @@
1
- export * from './entity-state.constant';
1
+ export * from './entity-state.constant';
@@ -1,34 +1,34 @@
1
- import {
2
- Column,
3
- VersionColumn,
4
- CreateDateColumn,
5
- UpdateDateColumn,
6
- PrimaryGeneratedColumn,
7
- } from 'typeorm';
8
-
9
- export class EntityGeneric {
10
- constructor(id?: number) {
11
- this.id = id;
12
- }
13
-
14
- @PrimaryGeneratedColumn()
15
- id: number;
16
-
17
- @CreateDateColumn()
18
- createdAt: Date;
19
-
20
- @UpdateDateColumn()
21
- updatedAt: Date;
22
-
23
- @Column()
24
- createdBy: number;
25
-
26
- @Column({ select: false })
27
- updatedBy: number;
28
-
29
- @Column()
30
- state: number;
31
-
32
- @VersionColumn({ select: false })
33
- version: number;
34
- }
1
+ import {
2
+ Column,
3
+ VersionColumn,
4
+ CreateDateColumn,
5
+ UpdateDateColumn,
6
+ PrimaryGeneratedColumn,
7
+ } from 'typeorm';
8
+
9
+ export class EntityGeneric {
10
+ constructor(id?: number) {
11
+ this.id = id;
12
+ }
13
+
14
+ @PrimaryGeneratedColumn()
15
+ id: number;
16
+
17
+ @CreateDateColumn()
18
+ createdAt: Date;
19
+
20
+ @UpdateDateColumn()
21
+ updatedAt: Date;
22
+
23
+ @Column()
24
+ createdBy: number;
25
+
26
+ @Column({ select: false })
27
+ updatedBy: number;
28
+
29
+ @Column()
30
+ state: number;
31
+
32
+ @VersionColumn({ select: false })
33
+ version: number;
34
+ }
@@ -1 +1 @@
1
- export * from './entity.generic';
1
+ export * from './entity.generic';
@@ -1,2 +1,2 @@
1
- export * from './entity/entity.generic';
2
- export * from './service/service.generic';
1
+ export * from './entity/entity.generic';
2
+ export * from './service/service.generic';
@@ -1 +1 @@
1
- export * from './service.generic';
1
+ export * from './service.generic';
@@ -1,112 +1,112 @@
1
- import {
2
- Repository,
3
- Connection,
4
- EntityManager,
5
- SelectQueryBuilder,
6
- } from 'typeorm';
7
- import { EntityGeneric } from '../entity';
8
- import { PaginationDto, BaseFilterDto } from '../../../dto';
9
- import { EntityStateConstant } from '../../constant';
10
- import { PaginationResponse } from '../../../response';
11
-
12
- export abstract class ServiceGeneric<
13
- Entity extends EntityGeneric,
14
- CustomRepository extends Repository<Entity>,
15
- > {
16
- protected readonly entityName: string;
17
- protected readonly loggable: boolean = false;
18
- protected repository: CustomRepository;
19
- protected connection: Connection;
20
- constructor(
21
- protected readonly connectionOrManager: Connection | EntityManager,
22
- repositoryType: { new (connection: Connection): CustomRepository },
23
- ) {
24
- if (connectionOrManager instanceof EntityManager) {
25
- this.connection = connectionOrManager.connection;
26
- } else {
27
- this.connection = connectionOrManager;
28
- }
29
- this.repository = this.connection.getCustomRepository(repositoryType);
30
- }
31
-
32
- async create(entity: Entity): Promise<Entity> {
33
- return this.repository.save(entity);
34
- }
35
-
36
- async update(entity: Entity): Promise<Entity> {
37
- return this.repository.save(entity);
38
- }
39
-
40
- async getListWithPagination(
41
- paginationDto: PaginationDto,
42
- callback?: (query: SelectQueryBuilder<Entity>) => void,
43
- ): Promise<PaginationResponse<Entity>> {
44
- const { limit = 25, offset = 0 } = paginationDto;
45
- const query = this.repository.createQueryBuilder(this.entityName);
46
- query.limit(limit);
47
- query.offset(offset);
48
- query.where(`${this.entityName}.state != :state`, {
49
- state: EntityStateConstant.Archived,
50
- });
51
- const defaultSelectable = ['createdAt', 'updatedAt'];
52
- query.orderBy(`${this.entityName}.updatedAt`, 'DESC');
53
- const selection = defaultSelectable.map(
54
- (column: string) => `${this.entityName}.${column}`,
55
- );
56
- query.addSelect(selection);
57
- if (callback != null) {
58
- callback(query);
59
- }
60
- const entities = await query.getMany();
61
- const total = await query.getCount();
62
- const response = new PaginationResponse(entities, total, limit, offset);
63
- return response;
64
- }
65
-
66
- async getAutocompleteWithPagination(
67
- paginationDto: PaginationDto,
68
- filter: BaseFilterDto,
69
- callback?: (query: SelectQueryBuilder<Entity>) => void,
70
- ): Promise<PaginationResponse<Entity>> {
71
- const { limit = 25, offset = 0 } = paginationDto;
72
- const query = this.repository.createQueryBuilder(this.entityName);
73
- query.limit(limit);
74
- query.offset(offset);
75
- query.where(`${this.entityName}.state != :state`, {
76
- state: EntityStateConstant.Archived,
77
- });
78
- const defaultSelectable = ['createdAt', 'updatedAt'];
79
- query.orderBy(`${this.entityName}.updatedAt`, 'DESC');
80
- const selection = defaultSelectable.map(
81
- (column: string) => `${this.entityName}.${column}`,
82
- );
83
- query.addSelect(selection);
84
- if (callback != null) {
85
- callback(query);
86
- }
87
- const { excludeIds = [], includeIds = [] } = { ...filter };
88
- // Exclude some ids from the list.
89
- if (excludeIds?.length > 0) {
90
- query.andWhere(`${this.entityName}.id NOT IN (:ids)`, {
91
- ids: excludeIds,
92
- });
93
- }
94
- let entities = await query.getMany();
95
- const total = await query.getCount();
96
- // Include some ids to the list.
97
- const allIds: number[] = [];
98
- for (const id of includeIds) {
99
- const entity = entities.filter((entity: Entity) => entity.id === id);
100
- if (entity.length == 0) {
101
- allIds.push(id);
102
- }
103
- }
104
- if (allIds.length > 0) {
105
- query.where(`${this.entityName}.id IN (:ids)`, { ids: allIds });
106
- const data = await query.getMany();
107
- entities = data.concat(entities);
108
- }
109
- const response = new PaginationResponse(entities, total, limit, offset);
110
- return response;
111
- }
112
- }
1
+ import {
2
+ Repository,
3
+ Connection,
4
+ EntityManager,
5
+ SelectQueryBuilder,
6
+ } from 'typeorm';
7
+ import { EntityGeneric } from '../entity';
8
+ import { PaginationDto, BaseFilterDto } from '../../dto';
9
+ import { EntityStateConstant } from '../../constant';
10
+ import { PaginationResponse } from '../../response';
11
+
12
+ export abstract class ServiceGeneric<
13
+ Entity extends EntityGeneric,
14
+ CustomRepository extends Repository<Entity>,
15
+ > {
16
+ protected readonly entityName: string;
17
+ protected readonly loggable: boolean = false;
18
+ protected repository: CustomRepository;
19
+ protected connection: Connection;
20
+ constructor(
21
+ protected readonly connectionOrManager: Connection | EntityManager,
22
+ repositoryType: { new (connection: Connection): CustomRepository },
23
+ ) {
24
+ if (connectionOrManager instanceof EntityManager) {
25
+ this.connection = connectionOrManager.connection;
26
+ } else {
27
+ this.connection = connectionOrManager;
28
+ }
29
+ this.repository = this.connection.getCustomRepository(repositoryType);
30
+ }
31
+
32
+ async create(entity: Entity): Promise<Entity> {
33
+ return this.repository.save(entity);
34
+ }
35
+
36
+ async update(entity: Entity): Promise<Entity> {
37
+ return this.repository.save(entity);
38
+ }
39
+
40
+ async getListWithPagination(
41
+ paginationDto: PaginationDto,
42
+ callback?: (query: SelectQueryBuilder<Entity>) => void,
43
+ ): Promise<PaginationResponse<Entity>> {
44
+ const { limit = 25, offset = 0 } = paginationDto;
45
+ const query = this.repository.createQueryBuilder(this.entityName);
46
+ query.limit(limit);
47
+ query.offset(offset);
48
+ query.where(`${this.entityName}.state != :state`, {
49
+ state: EntityStateConstant.Archived,
50
+ });
51
+ const defaultSelectable = ['createdAt', 'updatedAt'];
52
+ query.orderBy(`${this.entityName}.updatedAt`, 'DESC');
53
+ const selection = defaultSelectable.map(
54
+ (column: string) => `${this.entityName}.${column}`,
55
+ );
56
+ query.addSelect(selection);
57
+ if (callback != null) {
58
+ callback(query);
59
+ }
60
+ const entities = await query.getMany();
61
+ const total = await query.getCount();
62
+ const response = new PaginationResponse(entities, total, limit, offset);
63
+ return response;
64
+ }
65
+
66
+ async getAutocompleteWithPagination(
67
+ paginationDto: PaginationDto,
68
+ filter: BaseFilterDto,
69
+ callback?: (query: SelectQueryBuilder<Entity>) => void,
70
+ ): Promise<PaginationResponse<Entity>> {
71
+ const { limit = 25, offset = 0 } = paginationDto;
72
+ const query = this.repository.createQueryBuilder(this.entityName);
73
+ query.limit(limit);
74
+ query.offset(offset);
75
+ query.where(`${this.entityName}.state != :state`, {
76
+ state: EntityStateConstant.Archived,
77
+ });
78
+ const defaultSelectable = ['createdAt', 'updatedAt'];
79
+ query.orderBy(`${this.entityName}.updatedAt`, 'DESC');
80
+ const selection = defaultSelectable.map(
81
+ (column: string) => `${this.entityName}.${column}`,
82
+ );
83
+ query.addSelect(selection);
84
+ if (callback != null) {
85
+ callback(query);
86
+ }
87
+ const { excludeIds = [], includeIds = [] } = { ...filter };
88
+ // Exclude some ids from the list.
89
+ if (excludeIds?.length > 0) {
90
+ query.andWhere(`${this.entityName}.id NOT IN (:ids)`, {
91
+ ids: excludeIds,
92
+ });
93
+ }
94
+ let entities = await query.getMany();
95
+ const total = await query.getCount();
96
+ // Include some ids to the list.
97
+ const allIds: number[] = [];
98
+ for (const id of includeIds) {
99
+ const entity = entities.filter((entity: Entity) => entity.id === id);
100
+ if (entity.length == 0) {
101
+ allIds.push(id);
102
+ }
103
+ }
104
+ if (allIds.length > 0) {
105
+ query.where(`${this.entityName}.id IN (:ids)`, { ids: allIds });
106
+ const data = await query.getMany();
107
+ entities = data.concat(entities);
108
+ }
109
+ const response = new PaginationResponse(entities, total, limit, offset);
110
+ return response;
111
+ }
112
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
- export * from './common';
1
+ export * from './generic';
2
+ export * from './constant';
2
3
  export * from './dto';
3
4
  export * from './lib';
4
5
  export * from './response';
@@ -0,0 +1,49 @@
1
+ import dayjs from 'dayjs';
2
+ import { addSecond, isExpired } from './date.util';
3
+
4
+ describe('Utility Functions', () => {
5
+ test('addSecond should return a Date object with the specified duration added', () => {
6
+ // Arrange
7
+ const duration = 10;
8
+
9
+ // Act
10
+ const result = addSecond(duration);
11
+
12
+ // Assert
13
+ const expectedDate = dayjs().add(duration, 'seconds').toDate();
14
+ expect(result).toEqual(expectedDate);
15
+ });
16
+
17
+ test('isExpired should return true for a past date', () => {
18
+ // Arrange
19
+ const pastDate = dayjs().subtract(1, 'day').toDate();
20
+
21
+ // Act
22
+ const result = isExpired(pastDate);
23
+
24
+ // Assert
25
+ expect(result).toBe(true);
26
+ });
27
+
28
+ test('isExpired should return false for a future date', () => {
29
+ // Arrange
30
+ const futureDate = dayjs().add(1, 'day').toDate();
31
+
32
+ // Act
33
+ const result = isExpired(futureDate);
34
+
35
+ // Assert
36
+ expect(result).toBe(false);
37
+ });
38
+
39
+ test('isExpired should return false for the current date', () => {
40
+ // Arrange
41
+ const currentDate = dayjs().toDate();
42
+
43
+ // Act
44
+ const result = isExpired(currentDate);
45
+
46
+ // Assert
47
+ expect(result).toBe(false);
48
+ });
49
+ });
@@ -1 +1,10 @@
1
- export class Test {}
1
+ import dayjs from 'dayjs';
2
+
3
+ export const addSecond = (duration: number): Date => {
4
+ return dayjs().add(duration, 'seconds').toDate();
5
+ };
6
+
7
+ export const isExpired = (date: Date): boolean => {
8
+ const currentDate = dayjs();
9
+ return dayjs(date).isBefore(currentDate);
10
+ };
@@ -1,35 +1,79 @@
1
- import { generateKey, generateDigitCode } from './generator.util';
2
-
3
- describe('Utils', () => {
4
- describe('generateKey', () => {
5
- it('should generate a key of the specified length', () => {
6
- const keyLength = 10;
7
- const key = generateKey(keyLength);
8
- expect(key).toHaveLength(keyLength);
9
- });
10
-
11
- it('should generate a key with default length if not specified', () => {
12
- const defaultKeyLength = 36;
13
- const key = generateKey();
14
- expect(key).toHaveLength(defaultKeyLength);
15
- });
16
- });
17
-
18
- describe('generateDigitCode', () => {
19
- it('should generate a digit code of the specified length', () => {
20
- const codeLength = 6;
21
- const code = generateDigitCode(codeLength);
22
- expect(code).toHaveLength(codeLength);
23
- expect(Number(code)).toBeGreaterThanOrEqual(100000);
24
- expect(Number(code)).toBeLessThanOrEqual(999999);
25
- });
26
-
27
- it('should generate a digit code with default length if not specified', () => {
28
- const defaultCodeLength = 4;
29
- const code = generateDigitCode();
30
- expect(code).toHaveLength(defaultCodeLength);
31
- expect(Number(code)).toBeGreaterThanOrEqual(1000);
32
- expect(Number(code)).toBeLessThanOrEqual(9999);
33
- });
34
- });
35
- });
1
+ import * as bcrypt from 'bcrypt';
2
+ import {
3
+ generateKey,
4
+ generateDigitCode,
5
+ generatePassword,
6
+ } from './generator.util';
7
+
8
+ describe('Utils', () => {
9
+ describe('generateKey', () => {
10
+ it('should generate a key of the specified length', () => {
11
+ const keyLength = 10;
12
+ const key = generateKey(keyLength);
13
+ expect(key).toHaveLength(keyLength);
14
+ });
15
+
16
+ it('should generate a key with default length if not specified', () => {
17
+ const defaultKeyLength = 36;
18
+ const key = generateKey();
19
+ expect(key).toHaveLength(defaultKeyLength);
20
+ });
21
+ });
22
+
23
+ describe('generateDigitCode', () => {
24
+ it('should generate a digit code of the specified length', () => {
25
+ const codeLength = 6;
26
+ const code = generateDigitCode(codeLength);
27
+ expect(code).toHaveLength(codeLength);
28
+ expect(Number(code)).toBeGreaterThanOrEqual(100000);
29
+ expect(Number(code)).toBeLessThanOrEqual(999999);
30
+ });
31
+
32
+ it('should generate a digit code with default length if not specified', () => {
33
+ const defaultCodeLength = 4;
34
+ const code = generateDigitCode();
35
+ expect(code).toHaveLength(defaultCodeLength);
36
+ expect(Number(code)).toBeGreaterThanOrEqual(1000);
37
+ expect(Number(code)).toBeLessThanOrEqual(9999);
38
+ });
39
+ });
40
+
41
+ describe('Utility Functions', () => {
42
+ test('generatePassword should return a hashed password with the specified salt rounds', async () => {
43
+ // Arrange
44
+ const password = 'password123';
45
+ const saltRounds = 12;
46
+
47
+ // Act
48
+ const hashedPassword = await generatePassword(password, saltRounds);
49
+
50
+ // Assert
51
+ expect(typeof hashedPassword).toBe('string');
52
+ expect(hashedPassword).not.toBe(password);
53
+ expect(await bcrypt.compare(password, hashedPassword)).toBeTruthy();
54
+ });
55
+
56
+ test('generatePassword should use the default salt rounds when no value is provided', async () => {
57
+ // Arrange
58
+ const password = 'password123';
59
+ const defaultSaltRounds = 10;
60
+
61
+ // Act
62
+ const hashedPassword = await generatePassword(password);
63
+
64
+ // Assert
65
+ expect(typeof hashedPassword).toBe('string');
66
+ expect(hashedPassword).not.toBe(password);
67
+ expect(await bcrypt.compare(password, hashedPassword)).toBeTruthy();
68
+ expect(bcrypt.getRounds(hashedPassword)).toBe(defaultSaltRounds);
69
+ });
70
+
71
+ test('generatePassword should throw an error when an invalid password is provided', async () => {
72
+ // Arrange
73
+ const invalidPassword = '';
74
+
75
+ // Act and Assert
76
+ await expect(generatePassword(invalidPassword)).rejects.toThrow();
77
+ });
78
+ });
79
+ });
@@ -1,18 +1,27 @@
1
- export const generateKey = (length = 36) => {
2
- const chars =
3
- 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
4
- let result = '';
5
- for (let i = length; i > 0; i--) {
6
- result += chars[Math.floor(Math.random() * chars.length)];
7
- }
8
- return result;
9
- };
10
-
11
- export const generateDigitCode = (length = 4): string => {
12
- const startAt = 1 + '0'.repeat(length - 1);
13
- const endAt = 9 + '0'.repeat(length - 1);
14
- const generateCode = `${Math.floor(
15
- Number(startAt) + Math.random() * Number(endAt),
16
- )}`;
17
- return generateCode;
18
- };
1
+ import * as bcrypt from 'bcrypt';
2
+
3
+ export const generateKey = (length = 36) => {
4
+ const chars =
5
+ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
6
+ let result = '';
7
+ for (let i = length; i > 0; i--) {
8
+ result += chars[Math.floor(Math.random() * chars.length)];
9
+ }
10
+ return result;
11
+ };
12
+
13
+ export const generateDigitCode = (length = 4): string => {
14
+ const startAt = 1 + '0'.repeat(length - 1);
15
+ const endAt = 9 + '0'.repeat(length - 1);
16
+ const generateCode = `${Math.floor(
17
+ Number(startAt) + Math.random() * Number(endAt),
18
+ )}`;
19
+ return generateCode;
20
+ };
21
+
22
+ export const generatePassword = async (
23
+ password: string,
24
+ saltOrRounds = 10,
25
+ ): Promise<string> => {
26
+ return await bcrypt.hash(password, saltOrRounds);
27
+ };
@@ -1,44 +0,0 @@
1
- import { EntityGeneric } from './entity.generic';
2
-
3
- describe('EntityGeneric', () => {
4
- let entity: EntityGeneric;
5
-
6
- beforeEach(() => {
7
- entity = new EntityGeneric();
8
- });
9
-
10
- it('should have an id property', () => {
11
- expect(entity).toHaveProperty('id');
12
- expect(entity.id).toBeUndefined(); // Assuming the constructor sets id as undefined
13
- });
14
-
15
- it('should have a createdAt property', () => {
16
- expect(entity).toHaveProperty('createdAt');
17
- expect(entity.createdAt).toBeInstanceOf(Date);
18
- });
19
-
20
- it('should have an updatedAt property', () => {
21
- expect(entity).toHaveProperty('updatedAt');
22
- expect(entity.updatedAt).toBeInstanceOf(Date);
23
- });
24
-
25
- it('should have a createdBy property', () => {
26
- expect(entity).toHaveProperty('createdBy');
27
- expect(entity.createdBy).toBeUndefined(); // Assuming createdBy is not set in the constructor
28
- });
29
-
30
- it('should have an updatedBy property', () => {
31
- expect(entity).toHaveProperty('updatedBy');
32
- expect(entity.updatedBy).toBeUndefined(); // Assuming updatedBy is not set in the constructor
33
- });
34
-
35
- it('should have a state property', () => {
36
- expect(entity).toHaveProperty('state');
37
- expect(entity.state).toBeUndefined(); // Assuming state is not set in the constructor
38
- });
39
-
40
- it('should have a version property', () => {
41
- expect(entity).toHaveProperty('version');
42
- expect(entity.version).toBeUndefined(); // Assuming version is not set in the constructor
43
- });
44
- });
@@ -1,2 +0,0 @@
1
- export * from './generic';
2
- export * from './constant';