nodejs-quickstart-structure 1.18.1 → 1.19.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/CHANGELOG.md +7 -0
- package/README.md +2 -1
- package/lib/modules/caching-setup.js +76 -73
- package/lib/modules/kafka-setup.js +249 -191
- package/lib/modules/project-setup.js +1 -0
- package/package.json +13 -2
- package/templates/clean-architecture/js/src/errors/BadRequestError.js +11 -10
- package/templates/clean-architecture/js/src/errors/BadRequestError.spec.js.ejs +22 -21
- package/templates/clean-architecture/js/src/errors/NotFoundError.js +11 -10
- package/templates/clean-architecture/js/src/errors/NotFoundError.spec.js.ejs +22 -21
- package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.js.ejs +69 -39
- package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.spec.js.ejs +142 -81
- package/templates/clean-architecture/js/src/interfaces/controllers/userController.js.ejs +156 -75
- package/templates/clean-architecture/js/src/interfaces/controllers/userController.spec.js.ejs +234 -138
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs +27 -21
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.spec.js.ejs +66 -49
- package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/user.types.js.ejs +19 -17
- package/templates/clean-architecture/js/src/interfaces/routes/api.js +12 -10
- package/templates/clean-architecture/js/src/usecases/DeleteUser.js +11 -0
- package/templates/clean-architecture/js/src/usecases/DeleteUser.spec.js.ejs +47 -0
- package/templates/clean-architecture/js/src/usecases/UpdateUser.js +11 -0
- package/templates/clean-architecture/js/src/usecases/UpdateUser.spec.js.ejs +48 -0
- package/templates/clean-architecture/js/src/utils/errorMessages.js +14 -0
- package/templates/clean-architecture/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
- package/templates/clean-architecture/ts/src/errors/BadRequestError.ts +9 -8
- package/templates/clean-architecture/ts/src/errors/NotFoundError.spec.ts.ejs +22 -21
- package/templates/clean-architecture/ts/src/errors/NotFoundError.ts +9 -8
- package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.spec.ts.ejs +175 -85
- package/templates/clean-architecture/ts/src/infrastructure/repositories/userRepository.ts.ejs +74 -0
- package/templates/clean-architecture/ts/src/interfaces/controllers/userController.spec.ts.ejs +331 -185
- package/templates/clean-architecture/ts/src/interfaces/controllers/userController.ts.ejs +173 -84
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs +29 -21
- package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/user.types.ts.ejs +17 -15
- package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +13 -11
- package/templates/clean-architecture/ts/src/usecases/deleteUser.spec.ts.ejs +47 -0
- package/templates/clean-architecture/ts/src/usecases/deleteUser.ts +9 -0
- package/templates/clean-architecture/ts/src/usecases/updateUser.spec.ts.ejs +48 -0
- package/templates/clean-architecture/ts/src/usecases/updateUser.ts +9 -0
- package/templates/clean-architecture/ts/src/utils/errorMessages.ts +12 -0
- package/templates/common/.gitattributes +46 -0
- package/templates/common/README.md.ejs +294 -270
- package/templates/common/caching/clean/js/DeleteUser.js.ejs +27 -0
- package/templates/common/caching/clean/js/UpdateUser.js.ejs +27 -0
- package/templates/common/caching/clean/ts/deleteUser.ts.ejs +24 -0
- package/templates/common/caching/clean/ts/updateUser.ts.ejs +25 -0
- package/templates/common/caching/ts/memoryCache.ts.ejs +73 -64
- package/templates/common/caching/ts/redisClient.ts.ejs +89 -80
- package/templates/common/database/js/models/User.js.ejs +79 -53
- package/templates/common/database/js/models/User.js.mongoose.ejs +23 -19
- package/templates/common/database/js/models/User.spec.js.ejs +94 -84
- package/templates/common/database/ts/models/User.spec.ts.ejs +100 -84
- package/templates/common/database/ts/models/User.ts.ejs +87 -61
- package/templates/common/database/ts/models/User.ts.mongoose.ejs +30 -25
- package/templates/common/health/js/healthRoute.js.ejs +50 -47
- package/templates/common/health/ts/healthRoute.ts.ejs +49 -46
- package/templates/common/jest.e2e.config.js.ejs +8 -8
- package/templates/common/kafka/js/messaging/baseConsumer.js.ejs +30 -30
- package/templates/common/kafka/js/messaging/userEventSchema.js.ejs +12 -11
- package/templates/common/kafka/js/messaging/welcomeEmailConsumer.js.ejs +44 -31
- package/templates/common/kafka/js/messaging/welcomeEmailConsumer.spec.js.ejs +86 -49
- package/templates/common/kafka/js/services/kafkaService.js.ejs +93 -93
- package/templates/common/kafka/js/utils/kafkaEvents.js.ejs +7 -0
- package/templates/common/kafka/ts/messaging/userEventSchema.spec.ts.ejs +51 -51
- package/templates/common/kafka/ts/messaging/userEventSchema.ts.ejs +12 -11
- package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.spec.ts.ejs +86 -49
- package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.ts.ejs +38 -25
- package/templates/common/kafka/ts/services/kafkaService.ts.ejs +95 -95
- package/templates/common/kafka/ts/utils/kafkaEvents.ts.ejs +5 -0
- package/templates/common/shutdown/js/gracefulShutdown.js.ejs +65 -61
- package/templates/common/shutdown/js/gracefulShutdown.spec.js.ejs +149 -160
- package/templates/common/shutdown/ts/gracefulShutdown.spec.ts.ejs +179 -158
- package/templates/common/shutdown/ts/gracefulShutdown.ts.ejs +59 -55
- package/templates/common/src/tests/e2e/e2e.users.test.js.ejs +120 -49
- package/templates/common/src/tests/e2e/e2e.users.test.ts.ejs +120 -49
- package/templates/common/swagger.yml.ejs +118 -66
- package/templates/db/mysql/V1__Initial_Setup.sql.ejs +10 -9
- package/templates/db/postgres/V1__Initial_Setup.sql.ejs +10 -9
- package/templates/mvc/js/src/controllers/userController.js.ejs +246 -105
- package/templates/mvc/js/src/controllers/userController.spec.js.ejs +481 -209
- package/templates/mvc/js/src/errors/BadRequestError.js +11 -10
- package/templates/mvc/js/src/errors/BadRequestError.spec.js.ejs +22 -21
- package/templates/mvc/js/src/errors/NotFoundError.js +11 -10
- package/templates/mvc/js/src/errors/NotFoundError.spec.js.ejs +22 -21
- package/templates/mvc/js/src/graphql/resolvers/user.resolvers.js.ejs +25 -19
- package/templates/mvc/js/src/graphql/resolvers/user.resolvers.spec.js.ejs +64 -47
- package/templates/mvc/js/src/graphql/typeDefs/user.types.js.ejs +19 -17
- package/templates/mvc/js/src/routes/api.js +10 -8
- package/templates/mvc/js/src/routes/api.spec.js.ejs +41 -36
- package/templates/mvc/js/src/utils/errorMessages.js +14 -0
- package/templates/mvc/ts/src/controllers/userController.spec.ts.ejs +481 -203
- package/templates/mvc/ts/src/controllers/userController.ts.ejs +248 -107
- package/templates/mvc/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
- package/templates/mvc/ts/src/errors/BadRequestError.ts +9 -8
- package/templates/mvc/ts/src/errors/NotFoundError.spec.ts.ejs +27 -21
- package/templates/mvc/ts/src/errors/NotFoundError.ts +9 -8
- package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
- package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.ts.ejs +29 -21
- package/templates/mvc/ts/src/graphql/typeDefs/user.types.ts.ejs +17 -15
- package/templates/mvc/ts/src/index.ts.ejs +156 -153
- package/templates/mvc/ts/src/routes/api.spec.ts.ejs +59 -40
- package/templates/mvc/ts/src/routes/api.ts +12 -10
- package/templates/mvc/ts/src/utils/errorMessages.ts +12 -0
- package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.ts.ejs +0 -37
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<%_ if (caching === 'Redis') { -%>
|
|
2
|
+
const cacheService = require('../infrastructure/caching/redisClient');
|
|
3
|
+
<%_ } else if (caching === 'Memory Cache') { -%>
|
|
4
|
+
const cacheService = require('../infrastructure/caching/memoryCache');
|
|
5
|
+
<%_ } -%>
|
|
6
|
+
const logger = require('../infrastructure/log/logger');
|
|
7
|
+
|
|
8
|
+
class UpdateUser {
|
|
9
|
+
constructor(userRepository) {
|
|
10
|
+
this.userRepository = userRepository;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async execute(id, data) {
|
|
14
|
+
const updatedUser = await this.userRepository.update(id, data);
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
await cacheService.del('users:all');
|
|
18
|
+
logger.info('Invalidated users:all cache');
|
|
19
|
+
} catch (error) {
|
|
20
|
+
logger.error('Cache error (del):', error);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return updatedUser;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = UpdateUser;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { UserRepository } from '@/infrastructure/repositories/UserRepository';
|
|
2
|
+
<%_ if (caching === 'Redis') { -%>
|
|
3
|
+
import cacheService from '@/infrastructure/caching/redisClient';
|
|
4
|
+
<%_ } else if (caching === 'Memory Cache') { -%>
|
|
5
|
+
import cacheService from '@/infrastructure/caching/memoryCache';
|
|
6
|
+
<%_ } -%>
|
|
7
|
+
import logger from '@/infrastructure/log/logger';
|
|
8
|
+
|
|
9
|
+
export default class DeleteUser {
|
|
10
|
+
constructor(private userRepository: UserRepository) {}
|
|
11
|
+
|
|
12
|
+
async execute(id: number | string) {
|
|
13
|
+
const result = await this.userRepository.delete(id);
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
await cacheService.del('users:all');
|
|
17
|
+
logger.info('Invalidated users:all cache');
|
|
18
|
+
} catch (error) {
|
|
19
|
+
logger.error('Cache error (del):', error);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { User } from '@/domain/user';
|
|
2
|
+
import { UserRepository } from '@/infrastructure/repositories/UserRepository';
|
|
3
|
+
<%_ if (caching === 'Redis') { -%>
|
|
4
|
+
import cacheService from '@/infrastructure/caching/redisClient';
|
|
5
|
+
<%_ } else if (caching === 'Memory Cache') { -%>
|
|
6
|
+
import cacheService from '@/infrastructure/caching/memoryCache';
|
|
7
|
+
<%_ } -%>
|
|
8
|
+
import logger from '@/infrastructure/log/logger';
|
|
9
|
+
|
|
10
|
+
export default class UpdateUser {
|
|
11
|
+
constructor(private userRepository: UserRepository) {}
|
|
12
|
+
|
|
13
|
+
async execute(id: number | string, data: { name?: string, email?: string }) {
|
|
14
|
+
const updatedUser = await this.userRepository.update(id, data);
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
await cacheService.del('users:all');
|
|
18
|
+
logger.info('Invalidated users:all cache');
|
|
19
|
+
} catch (error) {
|
|
20
|
+
logger.error('Cache error (del):', error);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return updatedUser;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -1,64 +1,73 @@
|
|
|
1
|
-
import NodeCache from 'node-cache';
|
|
2
|
-
import logger from '<%- loggerPath %>';
|
|
3
|
-
|
|
4
|
-
class MemoryCacheService {
|
|
5
|
-
private cache: NodeCache;
|
|
6
|
-
private static instance: MemoryCacheService;
|
|
7
|
-
|
|
8
|
-
private constructor() {
|
|
9
|
-
// Default TTL of 0 (unlimited), check period of 120s
|
|
10
|
-
this.cache = new NodeCache({ stdTTL: 0, checkperiod: 120 });
|
|
11
|
-
logger.info('Memory Cache initialized');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
public static getInstance(): MemoryCacheService {
|
|
15
|
-
if (!MemoryCacheService.instance) {
|
|
16
|
-
MemoryCacheService.instance = new MemoryCacheService();
|
|
17
|
-
}
|
|
18
|
-
return MemoryCacheService.instance;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public async get<T>(key: string): Promise<T | null> {
|
|
22
|
-
try {
|
|
23
|
-
const data = this.cache.get<T>(key);
|
|
24
|
-
// Simulating un-parsed data similar to Redis for consistency
|
|
25
|
-
if (data === undefined) return null;
|
|
26
|
-
return typeof data === 'string' ? JSON.parse(data) : data;
|
|
27
|
-
} catch (error) {
|
|
28
|
-
logger.error(`Memory Cache get error for key ${key}:`, error);
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
public async set(key: string, value: unknown, ttl?: number): Promise<void> {
|
|
34
|
-
try {
|
|
35
|
-
const data = JSON.stringify(value);
|
|
36
|
-
if (ttl) {
|
|
37
|
-
this.cache.set(key, data, ttl);
|
|
38
|
-
} else {
|
|
39
|
-
this.cache.set(key, data);
|
|
40
|
-
}
|
|
41
|
-
} catch (error) {
|
|
42
|
-
logger.error(`Memory Cache set error for key ${key}:`, error);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public async del(key: string): Promise<void> {
|
|
47
|
-
try {
|
|
48
|
-
this.cache.del(key);
|
|
49
|
-
} catch (error) {
|
|
50
|
-
logger.error(`Memory Cache del error for key ${key}:`, error);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
public async
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
1
|
+
import NodeCache from 'node-cache';
|
|
2
|
+
import logger from '<%- loggerPath %>';
|
|
3
|
+
|
|
4
|
+
class MemoryCacheService {
|
|
5
|
+
private cache: NodeCache;
|
|
6
|
+
private static instance: MemoryCacheService;
|
|
7
|
+
|
|
8
|
+
private constructor() {
|
|
9
|
+
// Default TTL of 0 (unlimited), check period of 120s
|
|
10
|
+
this.cache = new NodeCache({ stdTTL: 0, checkperiod: 120 });
|
|
11
|
+
logger.info('Memory Cache initialized');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public static getInstance(): MemoryCacheService {
|
|
15
|
+
if (!MemoryCacheService.instance) {
|
|
16
|
+
MemoryCacheService.instance = new MemoryCacheService();
|
|
17
|
+
}
|
|
18
|
+
return MemoryCacheService.instance;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public async get<T>(key: string): Promise<T | null> {
|
|
22
|
+
try {
|
|
23
|
+
const data = this.cache.get<T>(key);
|
|
24
|
+
// Simulating un-parsed data similar to Redis for consistency
|
|
25
|
+
if (data === undefined) return null;
|
|
26
|
+
return typeof data === 'string' ? JSON.parse(data) : data;
|
|
27
|
+
} catch (error) {
|
|
28
|
+
logger.error(`Memory Cache get error for key ${key}:`, error);
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public async set(key: string, value: unknown, ttl?: number): Promise<void> {
|
|
34
|
+
try {
|
|
35
|
+
const data = JSON.stringify(value);
|
|
36
|
+
if (ttl) {
|
|
37
|
+
this.cache.set(key, data, ttl);
|
|
38
|
+
} else {
|
|
39
|
+
this.cache.set(key, data);
|
|
40
|
+
}
|
|
41
|
+
} catch (error) {
|
|
42
|
+
logger.error(`Memory Cache set error for key ${key}:`, error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public async del(key: string): Promise<void> {
|
|
47
|
+
try {
|
|
48
|
+
this.cache.del(key);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
logger.error(`Memory Cache del error for key ${key}:`, error);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public async flush(): Promise<void> {
|
|
55
|
+
try {
|
|
56
|
+
this.cache.flushAll();
|
|
57
|
+
logger.info('Memory Cache flushed');
|
|
58
|
+
} catch (error) {
|
|
59
|
+
logger.error('Memory Cache flush error:', error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public async getOrSet<T>(key: string, fetcher: () => Promise<T>, ttl: number = 3600): Promise<T> {
|
|
64
|
+
const cached = await this.get<T>(key);
|
|
65
|
+
if (cached) return cached;
|
|
66
|
+
|
|
67
|
+
const data = await fetcher();
|
|
68
|
+
if (data) await this.set(key, data, ttl);
|
|
69
|
+
return data;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default MemoryCacheService.getInstance();
|
|
@@ -1,80 +1,89 @@
|
|
|
1
|
-
import Redis from 'ioredis';
|
|
2
|
-
import dotenv from 'dotenv';
|
|
3
|
-
import logger from '<%- loggerPath %>';
|
|
4
|
-
|
|
5
|
-
dotenv.config();
|
|
6
|
-
|
|
7
|
-
class RedisService {
|
|
8
|
-
private client: Redis;
|
|
9
|
-
private static instance: RedisService;
|
|
10
|
-
|
|
11
|
-
private constructor() {
|
|
12
|
-
this.client = new Redis({
|
|
13
|
-
host: process.env.REDIS_HOST || 'localhost',
|
|
14
|
-
port: Number(process.env.REDIS_PORT) || 6379,
|
|
15
|
-
password: process.env.REDIS_PASSWORD || undefined,
|
|
16
|
-
retryStrategy: (times) => Math.min(times * 50, 2000),
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
this.client.on('connect', () => {
|
|
20
|
-
logger.info('Redis connected');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
this.client.on('error', (err) => {
|
|
24
|
-
logger.error('Redis error:', err);
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
public static getInstance(): RedisService {
|
|
29
|
-
if (!RedisService.instance) {
|
|
30
|
-
RedisService.instance = new RedisService();
|
|
31
|
-
}
|
|
32
|
-
return RedisService.instance;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public async get<T>(key: string): Promise<T | null> {
|
|
36
|
-
try {
|
|
37
|
-
const data = await this.client.get(key);
|
|
38
|
-
return data ? JSON.parse(data) : null;
|
|
39
|
-
} catch (error) {
|
|
40
|
-
logger.error(`Redis get error for key ${key}:`, error);
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
public async set(key: string, value: unknown, ttl?: number): Promise<void> {
|
|
46
|
-
try {
|
|
47
|
-
const data = JSON.stringify(value);
|
|
48
|
-
if (ttl) {
|
|
49
|
-
await this.client.set(key, data, 'EX', ttl);
|
|
50
|
-
} else {
|
|
51
|
-
await this.client.set(key, data);
|
|
52
|
-
}
|
|
53
|
-
} catch (error) {
|
|
54
|
-
logger.error(`Redis set error for key ${key}:`, error);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
public async del(key: string): Promise<void> {
|
|
59
|
-
try {
|
|
60
|
-
await this.client.del(key);
|
|
61
|
-
} catch (error) {
|
|
62
|
-
logger.error(`Redis del error for key ${key}:`, error);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
public async
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
public async
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
1
|
+
import Redis from 'ioredis';
|
|
2
|
+
import dotenv from 'dotenv';
|
|
3
|
+
import logger from '<%- loggerPath %>';
|
|
4
|
+
|
|
5
|
+
dotenv.config();
|
|
6
|
+
|
|
7
|
+
class RedisService {
|
|
8
|
+
private client: Redis;
|
|
9
|
+
private static instance: RedisService;
|
|
10
|
+
|
|
11
|
+
private constructor() {
|
|
12
|
+
this.client = new Redis({
|
|
13
|
+
host: process.env.REDIS_HOST || 'localhost',
|
|
14
|
+
port: Number(process.env.REDIS_PORT) || 6379,
|
|
15
|
+
password: process.env.REDIS_PASSWORD || undefined,
|
|
16
|
+
retryStrategy: (times) => Math.min(times * 50, 2000),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
this.client.on('connect', () => {
|
|
20
|
+
logger.info('Redis connected');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
this.client.on('error', (err) => {
|
|
24
|
+
logger.error('Redis error:', err);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public static getInstance(): RedisService {
|
|
29
|
+
if (!RedisService.instance) {
|
|
30
|
+
RedisService.instance = new RedisService();
|
|
31
|
+
}
|
|
32
|
+
return RedisService.instance;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public async get<T>(key: string): Promise<T | null> {
|
|
36
|
+
try {
|
|
37
|
+
const data = await this.client.get(key);
|
|
38
|
+
return data ? JSON.parse(data) : null;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
logger.error(`Redis get error for key ${key}:`, error);
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public async set(key: string, value: unknown, ttl?: number): Promise<void> {
|
|
46
|
+
try {
|
|
47
|
+
const data = JSON.stringify(value);
|
|
48
|
+
if (ttl) {
|
|
49
|
+
await this.client.set(key, data, 'EX', ttl);
|
|
50
|
+
} else {
|
|
51
|
+
await this.client.set(key, data);
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
logger.error(`Redis set error for key ${key}:`, error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public async del(key: string): Promise<void> {
|
|
59
|
+
try {
|
|
60
|
+
await this.client.del(key);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
logger.error(`Redis del error for key ${key}:`, error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public async flush(): Promise<void> {
|
|
67
|
+
try {
|
|
68
|
+
await this.client.flushall();
|
|
69
|
+
logger.info('Redis flushed');
|
|
70
|
+
} catch (error) {
|
|
71
|
+
logger.error('Redis flush error:', error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public async getOrSet<T>(key: string, fetcher: () => Promise<T>, ttl: number = 3600): Promise<T> {
|
|
76
|
+
const cached = await this.get<T>(key);
|
|
77
|
+
if (cached) return cached;
|
|
78
|
+
|
|
79
|
+
const data = await fetcher();
|
|
80
|
+
if (data) await this.set(key, data, ttl);
|
|
81
|
+
return data;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public async quit(): Promise<'OK'> {
|
|
85
|
+
return await this.client.quit();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default RedisService.getInstance();
|
|
@@ -1,53 +1,79 @@
|
|
|
1
|
-
<% if (database === 'None') { -%>
|
|
2
|
-
class UserModel {
|
|
3
|
-
static mockData = [];
|
|
4
|
-
|
|
5
|
-
static async find() {
|
|
6
|
-
return this.mockData;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
static async findAll() {
|
|
10
|
-
return this.mockData;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
static async create(data) {
|
|
14
|
-
const { id, ...rest } = data;
|
|
15
|
-
const newUser = { id: String(this.mockData.length + 1), ...rest };
|
|
16
|
-
this.mockData.push(newUser);
|
|
17
|
-
return newUser;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
1
|
+
<% if (database === 'None') { -%>
|
|
2
|
+
class UserModel {
|
|
3
|
+
static mockData = [];
|
|
4
|
+
|
|
5
|
+
static async find() {
|
|
6
|
+
return this.mockData;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static async findAll() {
|
|
10
|
+
return this.mockData;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static async create(data) {
|
|
14
|
+
const { id, ...rest } = data;
|
|
15
|
+
const newUser = { id: String(this.mockData.length + 1), ...rest };
|
|
16
|
+
this.mockData.push(newUser);
|
|
17
|
+
return newUser;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static async findByPk(id) {
|
|
21
|
+
return this.mockData.find((u) => u.id === String(id));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static async update(id, data) {
|
|
25
|
+
const user = await this.findByPk(id);
|
|
26
|
+
if (user) {
|
|
27
|
+
Object.assign(user, data);
|
|
28
|
+
}
|
|
29
|
+
return user;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static async destroy(id) {
|
|
33
|
+
const index = this.mockData.findIndex((u) => u.id === String(id));
|
|
34
|
+
if (index !== -1) {
|
|
35
|
+
this.mockData.splice(index, 1);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = UserModel;
|
|
43
|
+
<% } else { -%>
|
|
44
|
+
const { DataTypes, Model } = require('sequelize');
|
|
45
|
+
<% if (architecture === 'MVC') { %>const sequelize = require('../config/database');<% } else { %>const sequelize = require('../database');<% } %>
|
|
46
|
+
|
|
47
|
+
class User extends Model {}
|
|
48
|
+
|
|
49
|
+
User.init(
|
|
50
|
+
{
|
|
51
|
+
id: {
|
|
52
|
+
type: DataTypes.INTEGER,
|
|
53
|
+
autoIncrement: true,
|
|
54
|
+
primaryKey: true,
|
|
55
|
+
},
|
|
56
|
+
name: {
|
|
57
|
+
type: DataTypes.STRING,
|
|
58
|
+
allowNull: false,
|
|
59
|
+
},
|
|
60
|
+
email: {
|
|
61
|
+
type: DataTypes.STRING,
|
|
62
|
+
allowNull: false,
|
|
63
|
+
unique: true,
|
|
64
|
+
},
|
|
65
|
+
deletedAt: {
|
|
66
|
+
type: DataTypes.DATE,
|
|
67
|
+
allowNull: true,
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
sequelize,
|
|
72
|
+
tableName: 'users',
|
|
73
|
+
underscored: true,
|
|
74
|
+
paranoid: true,
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
module.exports = User;
|
|
79
|
+
<% } -%>
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
-
const mongoose = require('mongoose');
|
|
2
|
-
|
|
3
|
-
const UserSchema = new mongoose.Schema({
|
|
4
|
-
name: {
|
|
5
|
-
type: String,
|
|
6
|
-
required: true
|
|
7
|
-
},
|
|
8
|
-
email: {
|
|
9
|
-
type: String,
|
|
10
|
-
required: true,
|
|
11
|
-
unique: true
|
|
12
|
-
},
|
|
13
|
-
createdAt: {
|
|
14
|
-
type: Date,
|
|
15
|
-
default: Date.now
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
const mongoose = require('mongoose');
|
|
2
|
+
|
|
3
|
+
const UserSchema = new mongoose.Schema({
|
|
4
|
+
name: {
|
|
5
|
+
type: String,
|
|
6
|
+
required: true
|
|
7
|
+
},
|
|
8
|
+
email: {
|
|
9
|
+
type: String,
|
|
10
|
+
required: true,
|
|
11
|
+
unique: true
|
|
12
|
+
},
|
|
13
|
+
createdAt: {
|
|
14
|
+
type: Date,
|
|
15
|
+
default: Date.now
|
|
16
|
+
},
|
|
17
|
+
deletedAt: {
|
|
18
|
+
type: Date,
|
|
19
|
+
default: null
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
module.exports = mongoose.model('User', UserSchema);
|