@diia-inhouse/scaffold 2.24.0 → 2.52.2

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.
Files changed (116) hide show
  1. package/LICENCE.md +59 -59
  2. package/dist/_sharedTemplates/actionTest.t +11 -10
  3. package/dist/_templates/add/action/01-action.ts.t +6 -3
  4. package/dist/_templates/add/action/01-test.ts.t +1 -33
  5. package/dist/_templates/add/action/prompt.js +18 -9
  6. package/dist/_templates/add/action/prompt.js.map +1 -1
  7. package/dist/_templates/add/eventListener/01-event.ts.t +2 -2
  8. package/dist/_templates/add/generator/prompt.js +2 -1
  9. package/dist/_templates/add/generator/prompt.js.map +1 -1
  10. package/dist/_templates/add/model/01-interfaces.model.ts.t +1 -1
  11. package/dist/_templates/add/model/01-model.ts.t +1 -1
  12. package/dist/_templates/add/test/prompt.js +2 -1
  13. package/dist/_templates/add/test/prompt.js.map +1 -1
  14. package/dist/_templates/add/view/01-index.ts.t +7 -0
  15. package/dist/_templates/add/view/01-interface.ts.t +11 -0
  16. package/dist/_templates/add/view/01-view.ts.t +15 -0
  17. package/dist/_templates/add/view/02-scriptRunner.t +3 -0
  18. package/dist/_templates/add/view/prompt.js +30 -0
  19. package/dist/_templates/add/view/prompt.js.map +1 -0
  20. package/dist/_templates/init/admin/01-adminActionsService.ts.t +26 -0
  21. package/dist/_templates/init/admin/01-adminExecuteCustom.ts.t +34 -0
  22. package/dist/_templates/init/admin/01-adminExecuteCustomInterface.ts.t +10 -0
  23. package/dist/_templates/init/admin/01-adminExecuteQuery.ts.t +22 -0
  24. package/dist/_templates/init/admin/01-adminExecuteQueryInterface.ts.t +10 -0
  25. package/dist/_templates/init/admin/01-adminGetMeta.ts.t +22 -0
  26. package/dist/_templates/init/admin/01-adminGetMetaInterface.ts.t +7 -0
  27. package/dist/_templates/init/admin/01-adminService.ts.t +23 -0
  28. package/dist/_templates/init/admin/02-scriptRunner.ts.t +3 -0
  29. package/dist/_templates/init/admin/prompt.js +76 -0
  30. package/dist/_templates/init/admin/prompt.js.map +1 -0
  31. package/dist/_templates/init/matchers/01-matcher.ts.t +1 -1
  32. package/dist/_templates/init/matchers/01-vitest.d.ts.t +16 -0
  33. package/dist/_templates/init/matchers/02-scriptRunner.ts.t +1 -1
  34. package/dist/_templates/init/matchers/prompt.js +23 -17
  35. package/dist/_templates/init/matchers/prompt.js.map +1 -1
  36. package/dist/_templates/init/package/01-.gitignore.t +6 -0
  37. package/dist/_templates/init/package/01-.gitlab-ci.yml.t +7 -6
  38. package/dist/_templates/init/package/01-codeowners.t +5 -0
  39. package/dist/_templates/init/package/01-eslint.config.mjs.t +22 -0
  40. package/dist/_templates/init/package/01-package.json.t +8 -17
  41. package/dist/_templates/init/package/01-readme.md.t +4 -0
  42. package/dist/_templates/init/package/01-test.tsconfig.json.t +5 -1
  43. package/dist/_templates/init/package/01-vitest.config.mts.t +19 -0
  44. package/dist/_templates/init/package/prompt.js +8 -2
  45. package/dist/_templates/init/package/prompt.js.map +1 -1
  46. package/dist/_templates/init/service/01-.env.example.t +24 -19
  47. package/dist/_templates/init/service/01-.env.test.t +3 -0
  48. package/dist/_templates/init/service/01-.gitignore.t +1 -0
  49. package/dist/_templates/init/service/01-.gitlab-ci.yml.t +3 -7
  50. package/dist/_templates/init/service/01-.prettierignore.t +1 -0
  51. package/dist/_templates/init/service/01-codeowners.t +5 -0
  52. package/dist/_templates/init/service/01-eslint.config.mjs.t +21 -0
  53. package/dist/_templates/init/service/01-package.json.t +14 -28
  54. package/dist/_templates/init/service/01-proto.service.proto.t +15 -1
  55. package/dist/_templates/init/service/01-readme.md.t +11 -0
  56. package/dist/_templates/init/service/01-src.actions.v1.getAddResult.ts.t +12 -2
  57. package/dist/_templates/init/service/01-src.bootstrap.ts.t +5 -4
  58. package/dist/_templates/init/service/01-src.configs.config.ts.t +150 -0
  59. package/dist/_templates/init/service/01-src.configs.logger.ts.t +11 -0
  60. package/dist/_templates/init/service/01-src.configs.queue.ts.t +46 -0
  61. package/dist/_templates/init/service/01-src.deps.ts.t +1 -1
  62. package/dist/_templates/init/service/01-src.index.ts.t +3 -4
  63. package/dist/_templates/init/service/01-src.interfaces.config.ts.t +1 -1
  64. package/dist/_templates/init/service/01-src.interfaces.queue.ts.t +23 -0
  65. package/dist/_templates/init/service/01-src.services.add.ts.t +9 -0
  66. package/dist/_templates/init/service/01-src.views.exampleViews.index.ts.t +7 -0
  67. package/dist/_templates/init/service/01-src.views.exampleViews.interface.ts.t +11 -0
  68. package/dist/_templates/init/service/01-src.views.exampleViews.view.ts.t +15 -0
  69. package/dist/_templates/init/service/01-tests.integration.actionts.getAddResult.spec.ts.t +4 -12
  70. package/dist/_templates/init/service/01-tests.interfaces.ts.t +3 -0
  71. package/dist/_templates/init/service/01-tests.tsconfig.json.t +6 -2
  72. package/dist/_templates/init/service/01-tests.utils.getApp.ts.t +18 -5
  73. package/dist/_templates/init/service/01-tests.vitest.d.ts.t +11 -0
  74. package/dist/_templates/init/service/01-tsconfig.json.t +2 -2
  75. package/dist/_templates/init/service/01-vitest.config.mts.t +42 -0
  76. package/dist/_templates/init/service/02-scriptRunner.ts.t +1 -1
  77. package/dist/_templates/init/service/prompt.js +44 -5
  78. package/dist/_templates/init/service/prompt.js.map +1 -1
  79. package/dist/_templates/init/temporal/01-worker.activity.activity-example.ts.t +14 -0
  80. package/dist/_templates/init/temporal/01-worker.activity.index.ts.t +9 -0
  81. package/dist/_templates/init/temporal/01-worker.index.ts.t +32 -0
  82. package/dist/_templates/init/temporal/01-worker.workflow.index.ts.t +9 -0
  83. package/dist/_templates/init/temporal/01-worker.workflow.workflow-example.ts.t +25 -0
  84. package/dist/_templates/init/temporal/02-scriptRunner.ts.t +3 -0
  85. package/dist/_templates/init/temporal/prompt.js +15 -0
  86. package/dist/_templates/init/temporal/prompt.js.map +1 -0
  87. package/dist/depsNames.js +28 -27
  88. package/dist/depsNames.js.map +1 -1
  89. package/dist/index.js +2 -2
  90. package/dist/index.js.map +1 -1
  91. package/dist/interfaces/_templates/add/view.js +3 -0
  92. package/dist/interfaces/_templates/add/view.js.map +1 -0
  93. package/dist/interfaces/_templates/init/admin.js +3 -0
  94. package/dist/interfaces/_templates/init/admin.js.map +1 -0
  95. package/dist/interfaces/_templates/init/matcher.js +6 -6
  96. package/dist/interfaces/_templates/init/service.js +3 -8
  97. package/dist/interfaces/_templates/init/service.js.map +1 -1
  98. package/dist/interfaces/_templates/init/temporal.js +3 -0
  99. package/dist/interfaces/_templates/init/temporal.js.map +1 -0
  100. package/dist/prompt/autocomplete.js +1 -3
  101. package/dist/prompt/autocomplete.js.map +1 -1
  102. package/dist/prompt/select/baseSelect.js +1 -3
  103. package/dist/prompt/select/baseSelect.js.map +1 -1
  104. package/dist/prompt/select/multiselect.js +1 -3
  105. package/dist/prompt/select/multiselect.js.map +1 -1
  106. package/dist/prompt/select/yesNoSelect.js +1 -2
  107. package/dist/prompt/select/yesNoSelect.js.map +1 -1
  108. package/dist/utils.js +3 -4
  109. package/dist/utils.js.map +1 -1
  110. package/package.json +17 -19
  111. package/dist/_templates/init/matchers/01-jest.d.ts.t +0 -16
  112. package/dist/_templates/init/package/01-.eslintignore.t +0 -7
  113. package/dist/_templates/init/service/01-.eslintignore.t +0 -9
  114. package/dist/_templates/init/service/01-dockerfile.t +0 -38
  115. package/dist/_templates/init/service/01-src.config.ts.t +0 -163
  116. package/dist/_templates/init/service/01-tests.jest.d.ts.t +0 -5
@@ -12,18 +12,19 @@ to: <%= serviceName %>/package.json
12
12
  "prepare": "ts-patch install -s",
13
13
  "build": "rimraf dist/ && mkdir dist && npm run genproto && tsc",
14
14
  "start": "node dist/index.js",
15
- "semantic-release": "semantic-release",
16
- "lint": "eslint --ext .ts . && prettier --check .",
17
- "lint-fix": "eslint --ext .ts --fix && prettier --write .",
15
+ "semantic-release": "semantic-release -e @diia-inhouse/configs/dist/semantic-release/service-stage --debug --ci",
16
+ "semantic-release-prod": "semantic-release -e @diia-inhouse/configs/dist/semantic-release/service-prod --debug --ci",
17
+ "lint": "eslint . && prettier --check . && buf format ./proto --diff --exit-code ",
18
+ "lint-fix": "eslint . --fix && prettier --write . && buf format ./proto --write",
18
19
  "lint:lockfile": "lockfile-lint --path package-lock.json --allowed-hosts registry.npmjs.org gitlab.diia.org.ua --validate-https",
19
- "test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest",
20
- "test:integration": "npm run test --selectProjects integration --",
21
- <%if (h.isOptionSelected(selectedOptions, 'database')) {%>
22
- "migrate-deploy": "npm run migrate up",
23
- "migrate-ci": "npm run migrate up",
20
+ "pretest": "npm run genproto -- --generateClient=true",
21
+ "test": "tsc --project tests/tsconfig.json --noEmit && vitest run",
22
+ "test:watch": "vitest watch",
23
+ "test:coverage": "vitest run --coverage",
24
+ <%if (h.isOptionSelected(selectedDependencies, 'database')) {%>
24
25
  "migrate-test": "NODE_ENV=test npm run migrate up",
25
26
  "migrate": "sh -c 'ts-node --project migrations/tsconfig.json node_modules/.bin/migrate-mongo $0 $1 -f migrate-mongo-config.ts'",
26
- "indexes:sync": "MONGO_INDEXES_SYNC=true MONGO_INDEXES_EXIT_AFTER_SYNC=true npm run start",
27
+ "indexes:sync": "node -r module-alias/register ./node_modules/.bin/diia-db sync-indexes",
27
28
  <%}%>
28
29
  "find-circulars": "madge --circular --extensions ts ./",
29
30
  "scaffold": "scaffold",
@@ -31,7 +32,7 @@ to: <%= serviceName %>/package.json
31
32
  },
32
33
  "keywords": [],
33
34
  "engines": {
34
- "node": ">=20"
35
+ "node": ">=22"
35
36
  },
36
37
  "files": [
37
38
  "dist"
@@ -43,29 +44,14 @@ to: <%= serviceName %>/package.json
43
44
  "@src": "dist",
44
45
  "@tests": "tests"
45
46
  },
46
- "jest": {
47
- "preset": "@diia-inhouse/configs/dist/jest"
48
- },
49
47
  "commitlint": {
50
48
  "extends": "@diia-inhouse/configs/dist/commitlint"
51
49
  },
52
- "eslintConfig": {
53
- "extends": "@diia-inhouse/eslint-config",
54
- "parserOptions": {
55
- "project": [
56
- "./tsconfig.json",
57
- "./tests/tsconfig.json"
58
- <%if (h.isOptionSelected(selectedOptions, 'database')) {%>
59
- ,"./migrations/tsconfig.json"
60
- <%}%>
61
- ]
62
- }
63
- },
64
- "release": {
65
- "extends": "@diia-inhouse/configs/dist/semantic-release/service"
66
- },
67
50
  "prettier": "@diia-inhouse/eslint-config/prettier",
68
51
  "madge": {
69
52
  "tsConfig": "./tsconfig.json"
53
+ },
54
+ "overrides": {
55
+ "protobufjs": "7.2.5"
70
56
  }
71
57
  }
@@ -1,10 +1,14 @@
1
1
  ---
2
- to: <%= serviceName %>/proto/<%= h.changeCase.snakeCase(serviceName) %>.proto
2
+ to: <%= serviceName %>/proto/<%= h.changeCase.paramCase(serviceName) %>.proto
3
3
  ---
4
4
 
5
5
  syntax = "proto3";
6
6
 
7
7
  package ua.gov.diia.<%= h.changeCase.pascalCase(serviceName).toLowerCase() %>;
8
+
9
+ import "google/api/annotations.proto";
10
+ import "google/protobuf/empty.proto";
11
+
8
12
  option java_multiple_files = true;
9
13
  option java_package = "ua.gov.diia.<%= h.changeCase.pascalCase(serviceName).toLowerCase() %>";
10
14
 
@@ -12,6 +16,12 @@ service <%= h.changeCase.pascalCase(serviceName) %> {
12
16
  rpc GetAddResult(GetAddResultReq) returns (GetAddResultRes);
13
17
  }
14
18
 
19
+ service <%= h.changeCase.pascalCase(serviceName) %>Public {
20
+ rpc GetPublicResult(google.protobuf.Empty) returns (GetAddResultRes) {
21
+ option (google.api.http) = {get: "/api/v1/public-service/<%= h.changeCase.snakeCase(serviceName) %>/{param}/data"};
22
+ }
23
+ }
24
+
15
25
  message GetAddResultReq {
16
26
  int32 a = 1;
17
27
  int32 b = 2;
@@ -20,3 +30,7 @@ message GetAddResultReq {
20
30
  message GetAddResultRes {
21
31
  int32 result = 1;
22
32
  }
33
+
34
+ message DesignSystemResponse {
35
+
36
+ }
@@ -2,6 +2,17 @@
2
2
  to: <%= serviceName %>/README.md
3
3
  ---
4
4
 
5
+ # Service setup instructions. Remove after setup.
6
+
7
+ - [ ] Init git repo and push separate branch "semantic-dummy-release". It's needed for semantic release mechanism.
8
+ - [ ] Ask DevOps to add service to the infra repo
9
+ - [ ] Create an mr to setup envoy to proxy grpc requests to this service - [example](https://gitlab.diia.org.ua/diia-devops/master-core/-/merge_requests/589/diffs)
10
+
11
+
5
12
  ### <%= serviceName %>
6
13
 
7
14
  <%= description %>
15
+
16
+ <%= selectedReadmePointValues.has('figma') ? `🖼️ [Figma](${selectedReadmePointValues.get('figma')})` : '' %>
17
+ <%= selectedReadmePointValues.has('api') ? `🚪 [API](${selectedReadmePointValues.get('api')})` : '' %>
18
+ <%= selectedReadmePointValues.has('docs') ? `📄 [Docs](${selectedReadmePointValues.get('docs')})` : '' %>
@@ -3,22 +3,32 @@ to: <%= serviceName %>/src/actions/v1/getAddResult.ts
3
3
  ---
4
4
 
5
5
  import { GrpcAppAction } from '@diia-inhouse/diia-app'
6
-
6
+ import { SessionType } from '@diia-inhouse/types'
7
7
  import { ValidationSchema } from '@diia-inhouse/validators'
8
8
 
9
+ import { GetAddResultReq } from '@src/generated'
10
+
11
+ import AddService from '@services/add'
12
+
9
13
  import { ActionResult, Context } from '@interfaces/actions/v1/getAddResult'
10
14
 
11
15
  export default class GetAddResultAction implements GrpcAppAction<Context> {
12
16
  readonly name = 'getAddResult'
13
17
 
18
+ readonly sessionType = SessionType.None
19
+
14
20
  readonly validationRules: ValidationSchema<GetAddResultReq> = {
15
21
  a: {type: 'number'},
16
22
  b: {type: 'number'}
17
23
  }
18
24
 
25
+ constructor(private readonly addService: AddService) {}
26
+
19
27
  async handler(args: Context): Promise<ActionResult> {
20
28
  const { params: { a, b } } = args
21
29
 
22
- return { result: a + b }
30
+ const result = this.addService.add(a, b)
31
+
32
+ return { result }
23
33
  }
24
34
  }
@@ -2,16 +2,17 @@
2
2
  to: <%= serviceName %>/src/bootstrap.ts
3
3
  ---
4
4
 
5
- import { Application, ServiceContext } from '@diia-inhouse/diia-app'
5
+ import { Application, NodeTracerProvider, ServiceContext } from '@diia-inhouse/diia-app'
6
6
 
7
- import configFactory from '@src/config'
7
+ import configFactory from '@src/configs/config'
8
+ import { loggerConfig } from '@src/configs/logger'
8
9
  import deps from '@src/deps'
9
10
 
10
11
  import { AppConfig } from '@interfaces/config'
11
12
  import { AppDeps } from '@interfaces/deps'
12
13
 
13
- export async function bootstrap(serviceName: string): Promise<void> {
14
- const app = new Application<ServiceContext<AppConfig, AppDeps>>(serviceName)
14
+ export async function bootstrap(serviceName: string, nodeTracerProvider: NodeTracerProvider): Promise<void> {
15
+ const app = new Application<ServiceContext<AppConfig, AppDeps>>(serviceName, nodeTracerProvider, loggerConfig)
15
16
 
16
17
  await app.setConfig(configFactory)
17
18
  await app.setDeps(deps)
@@ -0,0 +1,150 @@
1
+ ---
2
+ to: <%= serviceName %>/src/configs/config.ts
3
+ ---
4
+
5
+ import { BaseConfig } from '@diia-inhouse/diia-app'
6
+
7
+ import { EnvService } from '@diia-inhouse/env'
8
+ <%if (h.isOptionSelected(selectedDependencies, ['redis'])) {%>
9
+ import { RedisOptions } from '@diia-inhouse/redis'
10
+ <%}%>
11
+ <%if (h.isOptionSelected(selectedDependencies, ['internal', 'external'])) {%>
12
+ import { QueueConnectionType, QueueTypes } from '@diia-inhouse/diia-queue'
13
+
14
+ import serviceRulesConfig from '@src/configs/queue'
15
+ <%}%>
16
+
17
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
18
+ export default async (<%= h.isOptionSelected(selectedDependencies, ['database', 'internal', 'external']) ? "envService: EnvService, " : '' %> <%= h.isOptionSelected(selectedDependencies, ['internal', 'external']) ? "serviceName: string" : '' %>) => ({
19
+ healthCheck: {
20
+ isEnabled: EnvService.getVar('HEALTH_CHECK_IS_ENABLED', 'boolean'),
21
+ port: EnvService.getVar('HEALTH_CHECK_IS_PORT', 'number', 4545),
22
+ },
23
+
24
+ metrics: {
25
+ custom: {
26
+ disabled: EnvService.getVar('METRICS_CUSTOM_DISABLED', 'boolean', false),
27
+ port: EnvService.getVar('METRICS_CUSTOM_PORT', 'number', 3030),
28
+ disableDefaultMetrics: EnvService.getVar('METRICS_CUSTOM_DISABLE_DEFAULT_METRICS', 'boolean', false),
29
+ defaultLabels: EnvService.getVar('METRICS_CUSTOM_DEFAULT_LABELS', 'object', {}),
30
+ pushGateway: {
31
+ isEnabled: EnvService.getVar('METRICS_PUSH_GATEWAY_IS_ENABLED', 'boolean', false),
32
+ url: EnvService.getVar('METRICS_PUSH_GATEWAY_URL', 'string', null),
33
+ intervalMs: EnvService.getVar('METRICS_PUSH_GATEWAY_INTERVAL_MS', 'number', null),
34
+ },
35
+ },
36
+ },
37
+
38
+ grpcServer: {
39
+ isEnabled: EnvService.getVar('GRPC_SERVER_ENABLED', 'boolean', false),
40
+ port: EnvService.getVar('GRPC_SERVER_PORT', 'number', 5000),
41
+ services: EnvService.getVar('GRPC_SERVICES', 'object'),
42
+ isReflectionEnabled: EnvService.getVar('GRPC_REFLECTION_ENABLED', 'boolean', false),
43
+ maxReceiveMessageLength: EnvService.getVar('GRPC_SERVER_MAX_RECEIVE_MESSAGE_LENGTH', 'number', 1024 * 1024 * 4),
44
+ },
45
+
46
+ grpc: {},
47
+
48
+ <%if (h.isOptionSelected(selectedDependencies, 'database')) {%>
49
+ db: {
50
+ database: EnvService.getVar('MONGO_DATABASE', 'string'),
51
+ replicaSet: EnvService.getVar('MONGO_REPLICA_SET', 'string'),
52
+ user: await envService.getSecret('MONGO_USER', { accessor: 'username', nullable: true }),
53
+ password: await envService.getSecret('MONGO_PASSWORD', { accessor: 'password', nullable: true }),
54
+ authSource: EnvService.getVar('MONGO_AUTH_SOURCE', 'string', null),
55
+ port: EnvService.getVar('MONGO_PORT', 'number'),
56
+ replicaSetNodes: EnvService
57
+ .getVar('MONGO_HOSTS', 'string')
58
+ .split(',')
59
+ .map((replicaHost: string) => ({ replicaHost })),
60
+ readPreference: EnvService.getVar('MONGO_READ_PREFERENCE', 'string'),
61
+ metrics: {
62
+ enabled: EnvService.getVar('MONGO_METRICS_ENABLED', 'boolean'),
63
+ },
64
+ },
65
+ <%}%>
66
+
67
+ <%if (h.isOptionSelected(selectedDependencies, 'redis')) {%>
68
+ store: {
69
+ readWrite: EnvService.getVar('STORE_READ_WRITE_OPTIONS', 'object') as RedisOptions,
70
+ readOnly: EnvService.getVar('STORE_READ_ONLY_OPTIONS', 'object') as RedisOptions,
71
+ },
72
+ <%}%>
73
+
74
+ <%if (h.isOptionSelected(selectedDependencies, ['internal', 'external'])) {%>
75
+ rabbit: {
76
+ serviceRulesConfig,
77
+ <%if (h.isOptionSelected(selectedDependencies, 'internal')) {%>
78
+ [QueueConnectionType.Internal]: {
79
+ connection: {
80
+ hostname: EnvService.getVar('RABBIT_HOST', 'string'),
81
+ port: EnvService.getVar('RABBIT_PORT', 'number'),
82
+ username: await envService.getSecret('RABBIT_USERNAME', { accessor: 'username' }),
83
+ password: await envService.getSecret('RABBIT_PASSWORD', { accessor: 'password' }),
84
+ heartbeat: EnvService.getVar('RABBIT_HEARTBEAT', 'number'),
85
+ },
86
+ socketOptions: {
87
+ clientProperties: {
88
+ applicationName: `${serviceName} Service`,
89
+ },
90
+ },
91
+ reconnectOptions: {
92
+ reconnectEnabled: true,
93
+ },
94
+ listenerOptions: {
95
+ prefetchCount: EnvService.getVar('RABBIT_QUEUE_PREFETCH_COUNT', 'number', 10),
96
+ },
97
+ declareOptions: {
98
+ assertQueues: EnvService.getVar('RABBIT_ASSERT_QUEUES', 'boolean'),
99
+ assertExchanges: EnvService.getVar('RABBIT_ASSERT_EXCHANGES', 'boolean'),
100
+ queuesOptions: {
101
+ type: QueueTypes.Quorum,
102
+ options: {
103
+ durable: true,
104
+ },
105
+ },
106
+ },
107
+ // Uncomment if listening to scheduled tasks needed
108
+ // scheduledTaskQueueName: ScheduledTaskQueueName.,
109
+ // Uncomment if listening to internal bus events needed
110
+ // queueName: InternalQueueName.,
111
+ },
112
+ <%}%>
113
+ <%if (h.isOptionSelected(selectedDependencies, 'external')) {%>
114
+ [QueueConnectionType.External]: {
115
+ connection: {
116
+ hostname: EnvService.getVar('EXTERNAL_RABBIT_HOST', 'string'),
117
+ port: EnvService.getVar('EXTERNAL_RABBIT_PORT', 'number'),
118
+ username: await envService.getSecret('EXTERNAL_RABBIT_USERNAME', { accessor: 'username' }),
119
+ password: await envService.getSecret('EXTERNAL_RABBIT_PASSWORD', { accessor: 'password' }),
120
+ heartbeat: EnvService.getVar('EXTERNAL_RABBIT_HEARTBEAT', 'number'),
121
+ },
122
+ socketOptions: {
123
+ clientProperties: {
124
+ applicationName: `${serviceName} Service`,
125
+ },
126
+ },
127
+ reconnectOptions: {
128
+ reconnectEnabled: true,
129
+ },
130
+ listenerOptions: {
131
+ prefetchCount: EnvService.getVar('EXTERNAL_RABBIT_QUEUE_PREFETCH_COUNT', 'number', 1),
132
+ },
133
+ declareOptions: {
134
+ assertQueues: EnvService.getVar('EXTERNAL_RABBIT_ASSERT_QUEUES', 'boolean'),
135
+ assertExchanges: EnvService.getVar('EXTERNAL_RABBIT_ASSERT_EXCHANGES', 'boolean'),
136
+ queuesOptions: {
137
+ type: QueueTypes.Quorum,
138
+ options: {
139
+ durable: true,
140
+ },
141
+ },
142
+ },
143
+ custom: {
144
+ responseRoutingKeyPrefix: EnvService.getVar('EXTERNAL_RABBIT_RESPONSE_ROUTING_KEY_PREFIX', 'string', null),
145
+ },
146
+ },
147
+ <%}%>
148
+ },
149
+ <%}%>
150
+ }) satisfies BaseConfig & Record<string, unknown>
@@ -0,0 +1,11 @@
1
+ ---
2
+ to: <%= serviceName %>/src/configs/logger.ts
3
+ ---
4
+
5
+ import { defaultOptions } from '@diia-inhouse/diia-logger'
6
+ import { EnvService } from '@diia-inhouse/env'
7
+ import { LogLevel, LoggerOptions } from '@diia-inhouse/types'
8
+
9
+ export const loggerConfig: LoggerOptions = {
10
+ logLevel: EnvService.getVar('LOG_LEVEL', 'string', defaultOptions.logLevel) as LogLevel,
11
+ }
@@ -0,0 +1,46 @@
1
+ ---
2
+ to: "<%= h.isOptionSelected(selectedDependencies, ['internal', 'external']) ? `${serviceName}/src/configs/queue.ts` : null %>"
3
+ ---
4
+ import { ServiceRulesConfig, QueueConfigType } from '@diia-inhouse/diia-queue'
5
+
6
+ import {
7
+ InternalQueueNames,
8
+ InternalTopics,
9
+ ScheduledTaskEvents,
10
+ ScheduledTaskQueueNames,
11
+ } from '@interfaces/queue'
12
+
13
+ export default {
14
+ portalEvents: [],
15
+ queuesConfig: {
16
+ [QueueConfigType.Internal]: {
17
+ [InternalQueueNames.Queue<%= h.changeCase.pascalCase(serviceName) %>]: {
18
+ topics: [],
19
+ },
20
+ [ScheduledTaskQueueNames.ScheduledTasksQueue<%= h.changeCase.pascalCase(serviceName) %>]: {
21
+ topics: [InternalTopics.TopicScheduledTasks],
22
+ },
23
+ },
24
+ },
25
+ servicesConfig: {
26
+ [QueueConfigType.Internal]: {
27
+ subscribe: [
28
+ ScheduledTaskQueueNames.ScheduledTasksQueue<%= h.changeCase.pascalCase(serviceName) %>,
29
+ InternalQueueNames.Queue<%= h.changeCase.pascalCase(serviceName) %>
30
+ ],
31
+ publish: [],
32
+ },
33
+ [QueueConfigType.External]: {
34
+ subscribe: [],
35
+ publish: [],
36
+ },
37
+ },
38
+ topicsConfig: {
39
+ [QueueConfigType.Internal]: {
40
+ [InternalTopics.TopicScheduledTasks]: {
41
+ events: Object.values(ScheduledTaskEvents),
42
+ },
43
+ },
44
+ [QueueConfigType.External]: {},
45
+ },
46
+ } satisfies ServiceRulesConfig
@@ -4,8 +4,8 @@ to: <%= serviceName %>/src/deps.ts
4
4
 
5
5
  import { DepsFactoryFn } from "@diia-inhouse/diia-app";
6
6
 
7
+ import { AppConfig } from '@interfaces/config'
7
8
  import { AppDeps } from "@interfaces/deps";
8
- import { AppConfig } from "@interfaces/config";
9
9
 
10
10
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
11
11
  export default async (_config: AppConfig): ReturnType<DepsFactoryFn<AppConfig, AppDeps>> => {
@@ -3,12 +3,11 @@ to: <%= serviceName %>/src/index.ts
3
3
  ---
4
4
 
5
5
  import { initTracing } from '@diia-inhouse/diia-app'
6
+ import { utils } from '@diia-inhouse/utils'
6
7
 
7
- const serviceName = '<%= h.changeCase.pascalCase(serviceName) %>'
8
-
9
- initTracing(serviceName)
8
+ const nodeTracerProvider = initTracing()
10
9
 
11
10
  import 'module-alias/register'
12
11
  import { bootstrap } from './bootstrap'
13
12
 
14
- bootstrap(serviceName)
13
+ void bootstrap(utils.getServiceName(), nodeTracerProvider)
@@ -2,6 +2,6 @@
2
2
  to: <%= serviceName %>/src/interfaces/config.ts
3
3
  ---
4
4
 
5
- import config from '@src/config'
5
+ import config from '@src/configs/config'
6
6
 
7
7
  export type AppConfig = Awaited<ReturnType<typeof config>>
@@ -0,0 +1,23 @@
1
+ ---
2
+ to: "<%= h.isOptionSelected(selectedDependencies, ['internal', 'external']) ? `${serviceName}/src/interfaces/queue.ts` : null %>"
3
+ ---
4
+
5
+ export const InternalQueueNames = {
6
+ Queue<%= h.changeCase.pascalCase(serviceName) %>: 'Queue<%= h.changeCase.pascalCase(serviceName) %>',
7
+ } as const
8
+
9
+ export const ScheduledTaskQueueNames = {
10
+ ScheduledTasksQueue<%= h.changeCase.pascalCase(serviceName) %>: 'ScheduledTasksQueue<%= h.changeCase.pascalCase(serviceName) %>',
11
+ } as const
12
+
13
+ export const InternalTopics = {
14
+ TopicScheduledTasks: 'TopicScheduledTasks'
15
+ } as const
16
+
17
+ export const ExternalTopics = {} as const
18
+
19
+ export const InternalEvents = {} as const
20
+
21
+ export const ExternalEvents = {} as const
22
+
23
+ export const ScheduledTaskEvents = {} as const
@@ -0,0 +1,9 @@
1
+ ---
2
+ to: <%= serviceName %>/src/services/add.ts
3
+ ---
4
+
5
+ export default class AddService {
6
+ add(a: number, b: number): number {
7
+ return a + b
8
+ }
9
+ }
@@ -0,0 +1,7 @@
1
+ ---
2
+ to: <%= serviceName %>/src/views/exampleViews/index.ts
3
+ ---
4
+
5
+ export { <%= h.changeCase.pascalCase(serviceName) %>InfoViews as default } from './view'
6
+
7
+ export * from './interface'
@@ -0,0 +1,11 @@
1
+ ---
2
+ to: <%= serviceName %>/src/views/exampleViews/interface.ts
3
+ ---
4
+
5
+ import { DesignSystemResponse } from '@diia-inhouse/design-system'
6
+
7
+ export interface ViewParams {
8
+
9
+ }
10
+
11
+ export type ViewScreen = DesignSystemResponse
@@ -0,0 +1,15 @@
1
+ ---
2
+ to: <%= serviceName %>/src/views/exampleViews/view.ts
3
+ ---
4
+
5
+ import { ViewParams, ViewScreen } from './interface'
6
+
7
+ export class <%= h.changeCase.pascalCase(serviceName) %>InfoViews {
8
+ toScreen(_params: ViewParams): ViewScreen {
9
+ return {
10
+ topGroup: [],
11
+ body: [],
12
+ bottomGroup: [],
13
+ }
14
+ }
15
+ }
@@ -2,7 +2,7 @@
2
2
  to: <%= serviceName %>/tests/integration/actions/v1/getAddResult.spec.ts
3
3
  ---
4
4
 
5
- import TestKit from '@diia-inhouse/test'
5
+ import { <%= h.changeCase.pascal(serviceName) %>Client } from '@src/generated'
6
6
 
7
7
  import { ActionResult } from '@interfaces/actions/v1/getAddResult'
8
8
 
@@ -12,28 +12,20 @@ import { getApp } from '@tests/utils/getApp'
12
12
 
13
13
  describe(`Action ${GetAddResultAction.name}`, () => {
14
14
  let app: Awaited<ReturnType<typeof getApp>>
15
- let action: GetAddResultAction
16
- const testKit = new TestKit()
15
+ let <%= h.changeCase.camel(serviceName) %>Client: <%= h.changeCase.pascal(serviceName) %>Client
17
16
 
18
17
  beforeAll(async () => {
19
18
  app = await getApp()
20
- action = app.container.build(GetAddResultAction)
21
- })
22
-
23
- afterAll(async () => {
24
- await app.stop()
19
+ <%= h.changeCase.camel(serviceName) %>Client = app.container.resolve('<%= h.changeCase.camel(serviceName) %>Client')
25
20
  })
26
21
 
27
22
  it('should return correct result', async () => {
28
23
  // Arrange
29
- const session = testKit.session.getUserSession()
30
- const headers = testKit.session.getHeaders()
31
-
32
24
  const a = 2;
33
25
  const b = 3;
34
26
 
35
27
  // Act
36
- const result = await action.handler({ params: { a, b }, session, headers })
28
+ const result = await <%= h.changeCase.camel(serviceName) %>Client.getAddResult({ a, b })
37
29
 
38
30
  // Assert
39
31
  expect(result).toEqual<ActionResult>({ result: 5 })
@@ -4,6 +4,9 @@ to: <%= serviceName %>/tests/interfaces.ts
4
4
 
5
5
  import TestKit from '@diia-inhouse/test'
6
6
 
7
+ import { <%= h.changeCase.pascal(serviceName) %>Client } from '@src/generated'
8
+
7
9
  export interface TestDeps {
8
10
  testKit: TestKit
11
+ <%= h.changeCase.camel(serviceName) %>Client: <%= h.changeCase.pascal(serviceName) %>Client
9
12
  }
@@ -6,10 +6,14 @@ to: <%= serviceName %>/tests/tsconfig.json
6
6
  "extends": "@diia-inhouse/configs/tsconfig",
7
7
  "compilerOptions": {
8
8
  "baseUrl": "../",
9
+ "types": ["vite/client", "vitest/globals", "./vitest.d.ts"],
10
+ "module": "ESNext",
11
+ "moduleResolution": "Bundler",
12
+ "isolatedModules": true,
9
13
  "paths": {
10
14
  "@services/*": ["src/services/*"],
11
15
  "@interfaces/*": ["src/interfaces/*"],
12
- <%if (h.isOptionSelected(selectedOptions, 'database')) {%>
16
+ <%if (h.isOptionSelected(selectedDependencies, 'database')) {%>
13
17
  "@models/*": ["src/models/*"],
14
18
  <%}%>
15
19
  "@dataMappers/*": ["src/dataMappers/*"],
@@ -19,5 +23,5 @@ to: <%= serviceName %>/tests/tsconfig.json
19
23
  },
20
24
  "noEmit": true
21
25
  },
22
- "include": ["./**/*"]
26
+ "include": ["./**/*", "../vitest.config.mts"]
23
27
  }
@@ -2,9 +2,11 @@
2
2
  to: <%= serviceName %>/tests/utils/getApp.ts
3
3
  ---
4
4
 
5
- import { Application, ServiceContext, ServiceOperator } from '@diia-inhouse/diia-app'
5
+ import { Application, GrpcClientFactory, ServiceContext, ServiceOperator, NodeTracerProvider, asFunction } from '@diia-inhouse/diia-app'
6
6
 
7
- import config from '@src/config'
7
+ import config from '@src/configs/config'
8
+ import { loggerConfig } from '@src/configs/logger'
9
+ import { <%= h.changeCase.pascal(serviceName) %>Definition } from '@src/generated'
8
10
 
9
11
  import { TestDeps } from '@tests/interfaces'
10
12
  import deps from '@tests/utils/getDeps'
@@ -12,15 +14,26 @@ import deps from '@tests/utils/getDeps'
12
14
  import { AppConfig } from '@interfaces/config'
13
15
  import { AppDeps } from '@interfaces/deps'
14
16
 
17
+ const modules = {
18
+ actions: import.meta.glob('/src/actions/**/*.ts'),
19
+ services: import.meta.glob('/src/services/**/*.ts'),
20
+ }
21
+
15
22
  export async function getApp(): Promise<ServiceOperator<AppConfig, AppDeps & TestDeps>> {
16
- const app = new Application<ServiceContext<AppConfig, AppDeps & TestDeps>>('<%= h.changeCase.pascal(serviceName) %>')
23
+ const app = new Application<ServiceContext<AppConfig, AppDeps & TestDeps>>('<%= h.changeCase.pascal(serviceName) %>', new NodeTracerProvider(), loggerConfig)
17
24
 
18
25
  await app.setConfig(config)
19
26
  await app.setDeps(deps)
20
27
 
21
- const appOperator = await app.initialize()
28
+ const dynamicDeps = await app.extractDependenciesFromModules(modules, 'src')
29
+ const appOperator = await app.initialize(dynamicDeps)
30
+ const { grpcService } = await appOperator.start()
22
31
 
23
- await appOperator.start()
32
+ appOperator.container.register({
33
+ <%= h.changeCase.camel(serviceName) %>Client: asFunction((grpcClientFactory: GrpcClientFactory) =>
34
+ grpcClientFactory.createGrpcClient(<%= h.changeCase.pascal(serviceName) %>Definition, `localhost:${grpcService.serverPort}`),
35
+ ).singleton(),
36
+ })
24
37
 
25
38
  return appOperator
26
39
  }
@@ -0,0 +1,11 @@
1
+ ---
2
+ to: <%= serviceName %>/tests/vitest.d.ts
3
+ ---
4
+
5
+ import 'vitest'
6
+ import { CustomMatchers } from '@diia-inhouse/test/vitest'
7
+
8
+ declare module 'vitest' {
9
+ interface Assertion<T> extends CustomMatchers<T> {}
10
+ interface AsymmetricMatchersContaining extends CustomMatchers {}
11
+ }
@@ -11,7 +11,7 @@ to: <%= serviceName %>/tsconfig.json
11
11
  "paths": {
12
12
  "@services/*": ["src/services/*"],
13
13
  "@interfaces/*": ["src/interfaces/*"],
14
- <%if (h.isOptionSelected(selectedOptions, 'database')) {%>
14
+ <%if (h.isOptionSelected(selectedDependencies, 'database')) {%>
15
15
  "@models/*": ["src/models/*"],
16
16
  <%}%>
17
17
  "@dataMappers/*": ["src/dataMappers/*"],
@@ -20,5 +20,5 @@ to: <%= serviceName %>/tsconfig.json
20
20
  "@tests/*": ["tests/*"]
21
21
  }
22
22
  },
23
- "include": ["src/**/*", "tests/jest.d.ts"]
23
+ "include": ["src/**/*"]
24
24
  }