nodejs-quickstart-structure 1.19.0 → 1.19.1
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 +309 -301
- package/LICENSE +15 -15
- package/lib/generator.js +139 -139
- package/lib/modules/app-setup.js +401 -401
- package/lib/modules/config-files.js +151 -151
- package/lib/modules/database-setup.js +116 -116
- package/lib/modules/project-setup.js +32 -32
- package/lib/prompts.js +100 -100
- package/package.json +78 -78
- package/templates/clean-architecture/js/src/domain/models/User.js +9 -9
- package/templates/clean-architecture/js/src/errors/ApiError.js +14 -14
- package/templates/clean-architecture/js/src/index.js.ejs +55 -55
- package/templates/clean-architecture/js/src/infrastructure/config/env.js.ejs +47 -47
- package/templates/clean-architecture/js/src/infrastructure/log/logger.js +36 -36
- package/templates/clean-architecture/js/src/infrastructure/log/logger.spec.js.ejs +63 -63
- package/templates/clean-architecture/js/src/infrastructure/webserver/middleware/errorMiddleware.js +30 -30
- package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +89 -89
- package/templates/clean-architecture/js/src/infrastructure/webserver/swagger.js.ejs +6 -6
- package/templates/clean-architecture/js/src/interfaces/graphql/context.js.ejs +13 -13
- package/templates/clean-architecture/js/src/interfaces/graphql/context.spec.js.ejs +31 -31
- package/templates/clean-architecture/js/src/interfaces/graphql/index.js.ejs +5 -5
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/index.js.ejs +6 -6
- package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/index.js.ejs +6 -6
- package/templates/clean-architecture/js/src/interfaces/routes/api.spec.js.ejs +38 -38
- package/templates/clean-architecture/js/src/usecases/CreateUser.js +14 -14
- package/templates/clean-architecture/js/src/usecases/CreateUser.spec.js.ejs +51 -51
- package/templates/clean-architecture/js/src/usecases/GetAllUsers.js +12 -12
- package/templates/clean-architecture/js/src/usecases/GetAllUsers.spec.js.ejs +61 -61
- package/templates/clean-architecture/js/src/utils/httpCodes.js +9 -9
- package/templates/clean-architecture/ts/src/config/env.ts.ejs +46 -46
- package/templates/clean-architecture/ts/src/config/swagger.ts.ejs +6 -6
- package/templates/clean-architecture/ts/src/domain/user.ts +7 -7
- package/templates/clean-architecture/ts/src/errors/ApiError.ts +15 -15
- package/templates/clean-architecture/ts/src/index.ts.ejs +139 -139
- package/templates/clean-architecture/ts/src/infrastructure/log/logger.spec.ts.ejs +63 -63
- package/templates/clean-architecture/ts/src/infrastructure/log/logger.ts +36 -36
- package/templates/clean-architecture/ts/src/interfaces/graphql/context.spec.ts.ejs +32 -32
- package/templates/clean-architecture/ts/src/interfaces/graphql/context.ts.ejs +17 -17
- package/templates/clean-architecture/ts/src/interfaces/graphql/index.ts.ejs +3 -3
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/index.ts.ejs +4 -4
- package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/index.ts.ejs +4 -4
- package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.spec.ts.ejs +40 -40
- package/templates/clean-architecture/ts/src/usecases/createUser.spec.ts.ejs +51 -51
- package/templates/clean-architecture/ts/src/usecases/createUser.ts +13 -13
- package/templates/clean-architecture/ts/src/usecases/getAllUsers.spec.ts.ejs +63 -63
- package/templates/clean-architecture/ts/src/usecases/getAllUsers.ts +10 -10
- package/templates/clean-architecture/ts/src/utils/errorMiddleware.ts.ejs +27 -27
- package/templates/clean-architecture/ts/src/utils/httpCodes.ts +7 -7
- package/templates/common/.cursorrules.ejs +60 -60
- package/templates/common/.dockerignore +12 -12
- package/templates/common/.env.example.ejs +41 -41
- package/templates/common/.gitlab-ci.yml.ejs +86 -86
- package/templates/common/.lintstagedrc +6 -6
- package/templates/common/.prettierrc +7 -7
- package/templates/common/Dockerfile +73 -73
- package/templates/common/Jenkinsfile.ejs +87 -87
- package/templates/common/SECURITY.md +20 -20
- package/templates/common/_github/workflows/ci.yml.ejs +46 -46
- package/templates/common/_github/workflows/security.yml.ejs +36 -36
- package/templates/common/_gitignore +5 -5
- package/templates/common/_husky/pre-commit +4 -4
- package/templates/common/caching/clean/js/CreateUser.js.ejs +29 -29
- package/templates/common/caching/clean/js/GetAllUsers.js.ejs +37 -37
- package/templates/common/caching/clean/ts/createUser.ts.ejs +27 -27
- package/templates/common/caching/clean/ts/getAllUsers.ts.ejs +34 -34
- package/templates/common/caching/js/memoryCache.js.ejs +60 -60
- package/templates/common/caching/js/memoryCache.spec.js.ejs +101 -101
- package/templates/common/caching/js/redisClient.js.ejs +75 -75
- package/templates/common/caching/js/redisClient.spec.js.ejs +147 -147
- package/templates/common/caching/ts/memoryCache.spec.ts.ejs +102 -102
- package/templates/common/caching/ts/redisClient.spec.ts.ejs +157 -157
- package/templates/common/database/js/database.js.ejs +19 -19
- package/templates/common/database/js/database.spec.js.ejs +56 -56
- package/templates/common/database/js/mongoose.js.ejs +33 -33
- package/templates/common/database/js/mongoose.spec.js.ejs +43 -43
- package/templates/common/database/ts/database.spec.ts.ejs +56 -56
- package/templates/common/database/ts/database.ts.ejs +21 -21
- package/templates/common/database/ts/mongoose.spec.ts.ejs +42 -42
- package/templates/common/database/ts/mongoose.ts.ejs +28 -28
- package/templates/common/docker-compose.yml.ejs +159 -159
- package/templates/common/ecosystem.config.js.ejs +40 -40
- package/templates/common/eslint.config.mjs.ejs +77 -77
- package/templates/common/health/js/healthRoute.spec.js.ejs +70 -70
- package/templates/common/health/ts/healthRoute.spec.ts.ejs +76 -76
- package/templates/common/jest.config.js.ejs +32 -32
- package/templates/common/kafka/js/config/kafka.js +9 -9
- package/templates/common/kafka/js/config/kafka.spec.js.ejs +27 -27
- package/templates/common/kafka/js/messaging/baseConsumer.spec.js.ejs +58 -58
- package/templates/common/kafka/js/messaging/userEventSchema.spec.js.ejs +27 -27
- package/templates/common/kafka/js/services/kafkaService.spec.js.ejs +106 -106
- package/templates/common/kafka/ts/config/kafka.spec.ts.ejs +27 -27
- package/templates/common/kafka/ts/config/kafka.ts +7 -7
- package/templates/common/kafka/ts/messaging/baseConsumer.spec.ts.ejs +50 -50
- package/templates/common/kafka/ts/messaging/baseConsumer.ts.ejs +27 -27
- package/templates/common/kafka/ts/services/kafkaService.spec.ts.ejs +81 -81
- package/templates/common/migrate-mongo-config.js.ejs +31 -31
- package/templates/common/migrations/init.js.ejs +23 -23
- package/templates/common/package.json.ejs +119 -118
- package/templates/common/prompts/add-feature.md.ejs +26 -26
- package/templates/common/prompts/project-context.md.ejs +43 -43
- package/templates/common/prompts/troubleshoot.md.ejs +28 -28
- package/templates/common/public/css/style.css +147 -147
- package/templates/common/scripts/run-e2e.js.ejs +63 -63
- package/templates/common/sonar-project.properties.ejs +27 -27
- package/templates/common/src/utils/errorMiddleware.spec.js.ejs +79 -79
- package/templates/common/src/utils/errorMiddleware.spec.ts.ejs +94 -94
- package/templates/common/tsconfig.json +22 -22
- package/templates/common/views/ejs/index.ejs +55 -55
- package/templates/common/views/pug/index.pug +40 -40
- package/templates/mvc/js/src/config/env.js.ejs +46 -46
- package/templates/mvc/js/src/config/swagger.js.ejs +6 -6
- package/templates/mvc/js/src/errors/ApiError.js +14 -14
- package/templates/mvc/js/src/graphql/context.js.ejs +7 -7
- package/templates/mvc/js/src/graphql/context.spec.js.ejs +29 -29
- package/templates/mvc/js/src/graphql/index.js.ejs +5 -5
- package/templates/mvc/js/src/graphql/resolvers/index.js.ejs +6 -6
- package/templates/mvc/js/src/graphql/typeDefs/index.js.ejs +6 -6
- package/templates/mvc/js/src/index.js.ejs +136 -136
- package/templates/mvc/js/src/utils/errorMiddleware.js +29 -29
- package/templates/mvc/js/src/utils/httpCodes.js +9 -9
- package/templates/mvc/js/src/utils/logger.js +40 -40
- package/templates/mvc/js/src/utils/logger.spec.js.ejs +63 -63
- package/templates/mvc/ts/src/config/env.ts.ejs +45 -45
- package/templates/mvc/ts/src/config/swagger.ts.ejs +6 -6
- package/templates/mvc/ts/src/errors/ApiError.ts +15 -15
- package/templates/mvc/ts/src/graphql/context.spec.ts.ejs +30 -30
- package/templates/mvc/ts/src/graphql/context.ts.ejs +12 -12
- package/templates/mvc/ts/src/graphql/index.ts.ejs +3 -3
- package/templates/mvc/ts/src/graphql/resolvers/index.ts.ejs +4 -4
- package/templates/mvc/ts/src/graphql/typeDefs/index.ts.ejs +4 -4
- package/templates/mvc/ts/src/utils/errorMiddleware.ts.ejs +27 -27
- package/templates/mvc/ts/src/utils/httpCodes.ts +7 -7
- package/templates/mvc/ts/src/utils/logger.spec.ts.ejs +63 -63
- package/templates/mvc/ts/src/utils/logger.ts +36 -36
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
name: Node.js CI
|
|
2
|
-
|
|
3
|
-
env:
|
|
4
|
-
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
|
|
5
|
-
|
|
6
|
-
on:
|
|
7
|
-
push:
|
|
8
|
-
branches: [ "main" ]
|
|
9
|
-
pull_request:
|
|
10
|
-
branches: [ "main" ]
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
build:
|
|
14
|
-
|
|
15
|
-
runs-on: ubuntu-latest
|
|
16
|
-
|
|
17
|
-
steps:
|
|
18
|
-
- uses: actions/checkout@v4
|
|
19
|
-
|
|
20
|
-
- name: Use Node.js 22.x
|
|
21
|
-
uses: actions/setup-node@v4
|
|
22
|
-
with:
|
|
23
|
-
node-version: 22.x
|
|
24
|
-
cache: 'npm'
|
|
25
|
-
|
|
26
|
-
- name: Install Dependencies
|
|
27
|
-
run: npm ci
|
|
28
|
-
|
|
29
|
-
- name: Lint Code
|
|
30
|
-
run: npm run lint
|
|
31
|
-
|
|
32
|
-
- name: Run Unit Tests
|
|
33
|
-
run: npm run test:coverage
|
|
34
|
-
|
|
35
|
-
- name: Run E2E Tests
|
|
36
|
-
run: npm run test:e2e
|
|
37
|
-
|
|
38
|
-
- name: Build
|
|
39
|
-
run: npm run build --if-present
|
|
40
|
-
<% if (includeSecurity) { %>
|
|
41
|
-
- name: SonarQube Scan
|
|
42
|
-
uses: SonarSource/sonarqube-scan-action@master
|
|
43
|
-
env:
|
|
44
|
-
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
45
|
-
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
|
46
|
-
<% } %>
|
|
1
|
+
name: Node.js CI
|
|
2
|
+
|
|
3
|
+
env:
|
|
4
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [ "main" ]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [ "main" ]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Use Node.js 22.x
|
|
21
|
+
uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version: 22.x
|
|
24
|
+
cache: 'npm'
|
|
25
|
+
|
|
26
|
+
- name: Install Dependencies
|
|
27
|
+
run: npm ci
|
|
28
|
+
|
|
29
|
+
- name: Lint Code
|
|
30
|
+
run: npm run lint
|
|
31
|
+
|
|
32
|
+
- name: Run Unit Tests
|
|
33
|
+
run: npm run test:coverage
|
|
34
|
+
|
|
35
|
+
- name: Run E2E Tests
|
|
36
|
+
run: npm run test:e2e
|
|
37
|
+
|
|
38
|
+
- name: Build
|
|
39
|
+
run: npm run build --if-present
|
|
40
|
+
<% if (includeSecurity) { %>
|
|
41
|
+
- name: SonarQube Scan
|
|
42
|
+
uses: SonarSource/sonarqube-scan-action@master
|
|
43
|
+
env:
|
|
44
|
+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
45
|
+
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
|
46
|
+
<% } %>
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
name: Enterprise Security Scan
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [ "main" ]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [ "main" ]
|
|
8
|
-
schedule:
|
|
9
|
-
- cron: '0 0 * * 1' # Weekly scan
|
|
10
|
-
|
|
11
|
-
jobs:
|
|
12
|
-
node-security:
|
|
13
|
-
runs-on: ubuntu-latest
|
|
14
|
-
steps:
|
|
15
|
-
- uses: actions/checkout@v4
|
|
16
|
-
|
|
17
|
-
- name: Run Snyk to check for vulnerabilities
|
|
18
|
-
uses: snyk/actions/node@master
|
|
19
|
-
env:
|
|
20
|
-
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
|
21
|
-
with:
|
|
22
|
-
args: --severity-threshold=high
|
|
23
|
-
|
|
24
|
-
container-security:
|
|
25
|
-
runs-on: ubuntu-latest
|
|
26
|
-
steps:
|
|
27
|
-
- uses: actions/checkout@v4
|
|
28
|
-
- name: Build Docker image
|
|
29
|
-
run: docker build -t <%= projectName %>:latest .
|
|
30
|
-
- name: Run Snyk to check Docker image for vulnerabilities
|
|
31
|
-
uses: snyk/actions/docker@master
|
|
32
|
-
env:
|
|
33
|
-
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
|
34
|
-
with:
|
|
35
|
-
image: <%= projectName %>:latest
|
|
36
|
-
args: --file=Dockerfile --severity-threshold=high --skip-unused-projects
|
|
1
|
+
name: Enterprise Security Scan
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ "main" ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ "main" ]
|
|
8
|
+
schedule:
|
|
9
|
+
- cron: '0 0 * * 1' # Weekly scan
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
node-security:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Run Snyk to check for vulnerabilities
|
|
18
|
+
uses: snyk/actions/node@master
|
|
19
|
+
env:
|
|
20
|
+
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
|
21
|
+
with:
|
|
22
|
+
args: --severity-threshold=high
|
|
23
|
+
|
|
24
|
+
container-security:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- name: Build Docker image
|
|
29
|
+
run: docker build -t <%= projectName %>:latest .
|
|
30
|
+
- name: Run Snyk to check Docker image for vulnerabilities
|
|
31
|
+
uses: snyk/actions/docker@master
|
|
32
|
+
env:
|
|
33
|
+
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
|
34
|
+
with:
|
|
35
|
+
image: <%= projectName %>:latest
|
|
36
|
+
args: --file=Dockerfile --severity-threshold=high --skip-unused-projects
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
node_modules
|
|
2
|
-
dist
|
|
3
|
-
.env
|
|
4
|
-
.DS_Store
|
|
5
|
-
coverage
|
|
1
|
+
node_modules
|
|
2
|
+
dist
|
|
3
|
+
.env
|
|
4
|
+
.DS_Store
|
|
5
|
+
coverage
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env sh
|
|
2
|
-
. "$(dirname -- "$0")/_/husky.sh"
|
|
3
|
-
|
|
4
|
-
npx lint-staged
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
. "$(dirname -- "$0")/_/husky.sh"
|
|
3
|
+
|
|
4
|
+
npx lint-staged
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
const User = require('../domain/models/User');
|
|
2
|
-
<%_ if (caching === 'Redis') { -%>
|
|
3
|
-
const cacheService = require('../infrastructure/caching/redisClient');
|
|
4
|
-
<%_ } else if (caching === 'Memory Cache') { -%>
|
|
5
|
-
const cacheService = require('../infrastructure/caching/memoryCache');
|
|
6
|
-
<%_ } -%>
|
|
7
|
-
const logger = require('../infrastructure/log/logger');
|
|
8
|
-
|
|
9
|
-
class CreateUser {
|
|
10
|
-
constructor(userRepository) {
|
|
11
|
-
this.userRepository = userRepository;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async execute(name, email) {
|
|
15
|
-
const user = new User(null, name, email);
|
|
16
|
-
const savedUser = await this.userRepository.save(user);
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
await cacheService.del('users:all');
|
|
20
|
-
logger.info('Invalidated users:all cache');
|
|
21
|
-
} catch (error) {
|
|
22
|
-
logger.error('Cache error (del):', error);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return savedUser;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
module.exports = CreateUser;
|
|
1
|
+
const User = require('../domain/models/User');
|
|
2
|
+
<%_ if (caching === 'Redis') { -%>
|
|
3
|
+
const cacheService = require('../infrastructure/caching/redisClient');
|
|
4
|
+
<%_ } else if (caching === 'Memory Cache') { -%>
|
|
5
|
+
const cacheService = require('../infrastructure/caching/memoryCache');
|
|
6
|
+
<%_ } -%>
|
|
7
|
+
const logger = require('../infrastructure/log/logger');
|
|
8
|
+
|
|
9
|
+
class CreateUser {
|
|
10
|
+
constructor(userRepository) {
|
|
11
|
+
this.userRepository = userRepository;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async execute(name, email) {
|
|
15
|
+
const user = new User(null, name, email);
|
|
16
|
+
const savedUser = await this.userRepository.save(user);
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
await cacheService.del('users:all');
|
|
20
|
+
logger.info('Invalidated users:all cache');
|
|
21
|
+
} catch (error) {
|
|
22
|
+
logger.error('Cache error (del):', error);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return savedUser;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = CreateUser;
|
|
@@ -1,37 +1,37 @@
|
|
|
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 GetAllUsers {
|
|
9
|
-
constructor(userRepository) {
|
|
10
|
-
this.userRepository = userRepository;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async execute() {
|
|
14
|
-
const cacheKey = 'users:all';
|
|
15
|
-
try {
|
|
16
|
-
const cachedUsers = await cacheService.get(cacheKey);
|
|
17
|
-
if (cachedUsers) {
|
|
18
|
-
logger.info('Serving users from cache');
|
|
19
|
-
return cachedUsers;
|
|
20
|
-
}
|
|
21
|
-
} catch (error) {
|
|
22
|
-
logger.error('Cache error (get):', error);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const users = await this.userRepository.getUsers();
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
await cacheService.set(cacheKey, users, 60);
|
|
29
|
-
} catch (error) {
|
|
30
|
-
logger.error('Cache error (set):', error);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return users;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
module.exports = GetAllUsers;
|
|
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 GetAllUsers {
|
|
9
|
+
constructor(userRepository) {
|
|
10
|
+
this.userRepository = userRepository;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async execute() {
|
|
14
|
+
const cacheKey = 'users:all';
|
|
15
|
+
try {
|
|
16
|
+
const cachedUsers = await cacheService.get(cacheKey);
|
|
17
|
+
if (cachedUsers) {
|
|
18
|
+
logger.info('Serving users from cache');
|
|
19
|
+
return cachedUsers;
|
|
20
|
+
}
|
|
21
|
+
} catch (error) {
|
|
22
|
+
logger.error('Cache error (get):', error);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const users = await this.userRepository.getUsers();
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
await cacheService.set(cacheKey, users, 60);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
logger.error('Cache error (set):', error);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return users;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = GetAllUsers;
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { User } from '@/domain/user';
|
|
2
|
-
|
|
3
|
-
import { UserRepository } from '@/infrastructure/repositories/UserRepository';
|
|
4
|
-
<%_ if (caching === 'Redis') { -%>
|
|
5
|
-
import cacheService from '@/infrastructure/caching/redisClient';
|
|
6
|
-
<%_ } else if (caching === 'Memory Cache') { -%>
|
|
7
|
-
import cacheService from '@/infrastructure/caching/memoryCache';
|
|
8
|
-
<%_ } -%>
|
|
9
|
-
import logger from '@/infrastructure/log/logger';
|
|
10
|
-
|
|
11
|
-
export default class CreateUser {
|
|
12
|
-
constructor(private userRepository: UserRepository) {}
|
|
13
|
-
|
|
14
|
-
async execute(name: string, email: string) {
|
|
15
|
-
const user = new User(null, name, email);
|
|
16
|
-
const savedUser = await this.userRepository.save(user);
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
await cacheService.del('users:all');
|
|
20
|
-
logger.info('Invalidated users:all cache');
|
|
21
|
-
} catch (error) {
|
|
22
|
-
logger.error('Cache error (del):', error);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return savedUser;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
1
|
+
import { User } from '@/domain/user';
|
|
2
|
+
|
|
3
|
+
import { UserRepository } from '@/infrastructure/repositories/UserRepository';
|
|
4
|
+
<%_ if (caching === 'Redis') { -%>
|
|
5
|
+
import cacheService from '@/infrastructure/caching/redisClient';
|
|
6
|
+
<%_ } else if (caching === 'Memory Cache') { -%>
|
|
7
|
+
import cacheService from '@/infrastructure/caching/memoryCache';
|
|
8
|
+
<%_ } -%>
|
|
9
|
+
import logger from '@/infrastructure/log/logger';
|
|
10
|
+
|
|
11
|
+
export default class CreateUser {
|
|
12
|
+
constructor(private userRepository: UserRepository) {}
|
|
13
|
+
|
|
14
|
+
async execute(name: string, email: string) {
|
|
15
|
+
const user = new User(null, name, email);
|
|
16
|
+
const savedUser = await this.userRepository.save(user);
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
await cacheService.del('users:all');
|
|
20
|
+
logger.info('Invalidated users:all cache');
|
|
21
|
+
} catch (error) {
|
|
22
|
+
logger.error('Cache error (del):', error);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return savedUser;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -1,34 +1,34 @@
|
|
|
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 GetAllUsers {
|
|
10
|
-
constructor(private userRepository: UserRepository) {}
|
|
11
|
-
|
|
12
|
-
async execute() {
|
|
13
|
-
const cacheKey = 'users:all';
|
|
14
|
-
try {
|
|
15
|
-
const cachedUsers = await cacheService.get(cacheKey);
|
|
16
|
-
if (cachedUsers) {
|
|
17
|
-
logger.info('Serving users from cache');
|
|
18
|
-
return cachedUsers;
|
|
19
|
-
}
|
|
20
|
-
} catch (error) {
|
|
21
|
-
logger.error('Cache error (get):', error);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const users = await this.userRepository.getUsers();
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
await cacheService.set(cacheKey, users, 60);
|
|
28
|
-
} catch (error) {
|
|
29
|
-
logger.error('Cache error (set):', error);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return users;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
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 GetAllUsers {
|
|
10
|
+
constructor(private userRepository: UserRepository) {}
|
|
11
|
+
|
|
12
|
+
async execute() {
|
|
13
|
+
const cacheKey = 'users:all';
|
|
14
|
+
try {
|
|
15
|
+
const cachedUsers = await cacheService.get(cacheKey);
|
|
16
|
+
if (cachedUsers) {
|
|
17
|
+
logger.info('Serving users from cache');
|
|
18
|
+
return cachedUsers;
|
|
19
|
+
}
|
|
20
|
+
} catch (error) {
|
|
21
|
+
logger.error('Cache error (get):', error);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const users = await this.userRepository.getUsers();
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
await cacheService.set(cacheKey, users, 60);
|
|
28
|
+
} catch (error) {
|
|
29
|
+
logger.error('Cache error (set):', error);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return users;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
const NodeCache = require('node-cache');
|
|
2
|
-
const logger = require('<%- loggerPath %>');
|
|
3
|
-
|
|
4
|
-
class MemoryCacheService {
|
|
5
|
-
constructor() {
|
|
6
|
-
// Default TTL of 0 (unlimited), check period of 120s
|
|
7
|
-
this.cache = new NodeCache({ stdTTL: 0, checkperiod: 120 });
|
|
8
|
-
logger.info('Memory Cache initialized');
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
static getInstance() {
|
|
12
|
-
if (!MemoryCacheService.instance) {
|
|
13
|
-
MemoryCacheService.instance = new MemoryCacheService();
|
|
14
|
-
}
|
|
15
|
-
return MemoryCacheService.instance;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async get(key) {
|
|
19
|
-
try {
|
|
20
|
-
const data = this.cache.get(key);
|
|
21
|
-
if (data === undefined) return null;
|
|
22
|
-
return typeof data === 'string' ? JSON.parse(data) : data;
|
|
23
|
-
} catch (error) {
|
|
24
|
-
logger.error(`Memory Cache get error for key ${key}:`, error);
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async set(key, value, ttl) {
|
|
30
|
-
try {
|
|
31
|
-
const data = JSON.stringify(value);
|
|
32
|
-
if (ttl) {
|
|
33
|
-
this.cache.set(key, data, ttl);
|
|
34
|
-
} else {
|
|
35
|
-
this.cache.set(key, data);
|
|
36
|
-
}
|
|
37
|
-
} catch (error) {
|
|
38
|
-
logger.error(`Memory Cache set error for key ${key}:`, error);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async del(key) {
|
|
43
|
-
try {
|
|
44
|
-
this.cache.del(key);
|
|
45
|
-
} catch (error) {
|
|
46
|
-
logger.error(`Memory Cache del error for key ${key}:`, error);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async getOrSet(key, fetcher, ttl = 3600) {
|
|
51
|
-
const cached = await this.get(key);
|
|
52
|
-
if (cached) return cached;
|
|
53
|
-
|
|
54
|
-
const data = await fetcher();
|
|
55
|
-
if (data) await this.set(key, data, ttl);
|
|
56
|
-
return data;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
module.exports = MemoryCacheService.getInstance();
|
|
1
|
+
const NodeCache = require('node-cache');
|
|
2
|
+
const logger = require('<%- loggerPath %>');
|
|
3
|
+
|
|
4
|
+
class MemoryCacheService {
|
|
5
|
+
constructor() {
|
|
6
|
+
// Default TTL of 0 (unlimited), check period of 120s
|
|
7
|
+
this.cache = new NodeCache({ stdTTL: 0, checkperiod: 120 });
|
|
8
|
+
logger.info('Memory Cache initialized');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static getInstance() {
|
|
12
|
+
if (!MemoryCacheService.instance) {
|
|
13
|
+
MemoryCacheService.instance = new MemoryCacheService();
|
|
14
|
+
}
|
|
15
|
+
return MemoryCacheService.instance;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async get(key) {
|
|
19
|
+
try {
|
|
20
|
+
const data = this.cache.get(key);
|
|
21
|
+
if (data === undefined) return null;
|
|
22
|
+
return typeof data === 'string' ? JSON.parse(data) : data;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
logger.error(`Memory Cache get error for key ${key}:`, error);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async set(key, value, ttl) {
|
|
30
|
+
try {
|
|
31
|
+
const data = JSON.stringify(value);
|
|
32
|
+
if (ttl) {
|
|
33
|
+
this.cache.set(key, data, ttl);
|
|
34
|
+
} else {
|
|
35
|
+
this.cache.set(key, data);
|
|
36
|
+
}
|
|
37
|
+
} catch (error) {
|
|
38
|
+
logger.error(`Memory Cache set error for key ${key}:`, error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async del(key) {
|
|
43
|
+
try {
|
|
44
|
+
this.cache.del(key);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
logger.error(`Memory Cache del error for key ${key}:`, error);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async getOrSet(key, fetcher, ttl = 3600) {
|
|
51
|
+
const cached = await this.get(key);
|
|
52
|
+
if (cached) return cached;
|
|
53
|
+
|
|
54
|
+
const data = await fetcher();
|
|
55
|
+
if (data) await this.set(key, data, ttl);
|
|
56
|
+
return data;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = MemoryCacheService.getInstance();
|