@ask-ell/back-end 0.2.5 → 0.2.6

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 (155) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/package.json +2 -2
  3. package/src/http/index.d.ts +2 -0
  4. package/src/http/index.d.ts.map +1 -0
  5. package/src/http/index.js +4 -0
  6. package/src/http/types.d.ts +5 -0
  7. package/src/http/types.d.ts.map +1 -0
  8. package/src/http/types.js +2 -0
  9. package/src/{index.ts → index.d.ts} +1 -0
  10. package/src/index.d.ts.map +1 -0
  11. package/src/index.js +10 -0
  12. package/src/keyv.store.adapter.factory.d.ts +11 -0
  13. package/src/keyv.store.adapter.factory.d.ts.map +1 -0
  14. package/src/keyv.store.adapter.factory.js +44 -0
  15. package/src/nest/add-ons/add-on.interface.d.ts +5 -0
  16. package/src/nest/add-ons/add-on.interface.d.ts.map +1 -0
  17. package/src/nest/add-ons/add-on.interface.js +2 -0
  18. package/src/nest/add-ons/add-on.wrapper.d.ts +11 -0
  19. package/src/nest/add-ons/add-on.wrapper.d.ts.map +1 -0
  20. package/src/nest/add-ons/add-on.wrapper.js +29 -0
  21. package/src/nest/add-ons/implementations/security/security.add-on.d.ts +6 -0
  22. package/src/nest/add-ons/implementations/security/security.add-on.d.ts.map +1 -0
  23. package/src/nest/add-ons/implementations/security/security.add-on.js +16 -0
  24. package/src/nest/add-ons/implementations/sentry/sentry.add-on.d.ts +8 -0
  25. package/src/nest/add-ons/implementations/sentry/sentry.add-on.d.ts.map +1 -0
  26. package/src/nest/add-ons/implementations/sentry/{sentry.add-on.interface.ts → sentry.add-on.interface.d.ts} +3 -5
  27. package/src/nest/add-ons/implementations/sentry/sentry.add-on.interface.d.ts.map +1 -0
  28. package/src/nest/add-ons/implementations/sentry/sentry.add-on.interface.js +2 -0
  29. package/src/nest/add-ons/implementations/sentry/sentry.add-on.js +19 -0
  30. package/src/nest/add-ons/implementations/sentry/sentry.add-on.state.interface.d.ts +6 -0
  31. package/src/nest/add-ons/implementations/sentry/sentry.add-on.state.interface.d.ts.map +1 -0
  32. package/src/nest/add-ons/implementations/sentry/sentry.add-on.state.interface.js +2 -0
  33. package/src/nest/add-ons/implementations/swagger/swagger.add-on.d.ts +10 -0
  34. package/src/nest/add-ons/implementations/swagger/swagger.add-on.d.ts.map +1 -0
  35. package/src/nest/add-ons/implementations/swagger/{swagger.add-on.interface.ts → swagger.add-on.interface.d.ts} +3 -5
  36. package/src/nest/add-ons/implementations/swagger/swagger.add-on.interface.d.ts.map +1 -0
  37. package/src/nest/add-ons/implementations/swagger/swagger.add-on.interface.js +2 -0
  38. package/src/nest/add-ons/implementations/swagger/swagger.add-on.js +32 -0
  39. package/src/nest/add-ons/implementations/swagger/swagger.add-on.state.interface.d.ts +7 -0
  40. package/src/nest/add-ons/implementations/swagger/swagger.add-on.state.interface.d.ts.map +1 -0
  41. package/src/nest/add-ons/implementations/swagger/swagger.add-on.state.interface.js +2 -0
  42. package/src/nest/add-ons/implementations/swagger/{types.ts → types.d.ts} +1 -0
  43. package/src/nest/add-ons/implementations/swagger/types.d.ts.map +1 -0
  44. package/src/nest/add-ons/implementations/swagger/types.js +2 -0
  45. package/src/nest/add-ons/{index.ts → index.d.ts} +1 -0
  46. package/src/nest/add-ons/index.d.ts.map +1 -0
  47. package/src/nest/add-ons/index.js +9 -0
  48. package/src/nest/add-ons/{types.ts → types.d.ts} +3 -3
  49. package/src/nest/add-ons/types.d.ts.map +1 -0
  50. package/src/nest/add-ons/types.js +2 -0
  51. package/src/nest/application.base.d.ts +5 -0
  52. package/src/nest/application.base.d.ts.map +1 -0
  53. package/src/nest/application.base.js +34 -0
  54. package/src/nest/application.factory.d.ts +9 -0
  55. package/src/nest/application.factory.d.ts.map +1 -0
  56. package/src/nest/application.factory.js +15 -0
  57. package/src/nest/filters/http.exception.filter.d.ts +5 -0
  58. package/src/nest/filters/http.exception.filter.d.ts.map +1 -0
  59. package/src/nest/filters/http.exception.filter.js +32 -0
  60. package/src/nest/filters/{index.ts → index.d.ts} +1 -0
  61. package/src/nest/filters/index.d.ts.map +1 -0
  62. package/src/nest/filters/index.js +4 -0
  63. package/src/nest/{index.ts → index.d.ts} +1 -0
  64. package/src/nest/index.d.ts.map +1 -0
  65. package/src/nest/index.js +9 -0
  66. package/src/nest/interceptors/error.interceptor.d.ts +11 -0
  67. package/src/nest/interceptors/error.interceptor.d.ts.map +1 -0
  68. package/src/nest/interceptors/error.interceptor.js +17 -0
  69. package/src/nest/interceptors/{index.ts → index.d.ts} +1 -0
  70. package/src/nest/interceptors/index.d.ts.map +1 -0
  71. package/src/nest/interceptors/index.js +5 -0
  72. package/src/nest/interceptors/response.format.interceptor.d.ts +7 -0
  73. package/src/nest/interceptors/response.format.interceptor.d.ts.map +1 -0
  74. package/src/nest/interceptors/response.format.interceptor.js +30 -0
  75. package/src/nest/modules/health/health.module.d.ts +5 -0
  76. package/src/nest/modules/health/health.module.d.ts.map +1 -0
  77. package/src/nest/modules/health/health.module.js +32 -0
  78. package/src/nest/modules/health/index.d.ts +2 -0
  79. package/src/nest/modules/health/index.d.ts.map +1 -0
  80. package/src/nest/modules/health/index.js +4 -0
  81. package/src/nest/modules/health/middlewares/{index.ts → index.d.ts} +1 -0
  82. package/src/nest/modules/health/middlewares/index.d.ts.map +1 -0
  83. package/src/nest/modules/health/middlewares/index.js +4 -0
  84. package/src/nest/modules/health/middlewares/ping.middleware.d.ts +6 -0
  85. package/src/nest/modules/health/middlewares/ping.middleware.d.ts.map +1 -0
  86. package/src/nest/modules/health/middlewares/ping.middleware.js +26 -0
  87. package/src/nest/modules/{index.ts → index.d.ts} +1 -0
  88. package/src/nest/modules/index.d.ts.map +1 -0
  89. package/src/nest/modules/index.js +5 -0
  90. package/src/nest/modules/requirement/{index.ts → index.d.ts} +1 -0
  91. package/src/nest/modules/requirement/index.d.ts.map +1 -0
  92. package/src/nest/modules/requirement/index.js +4 -0
  93. package/src/nest/modules/requirement/requirement.module.d.ts +3 -0
  94. package/src/nest/modules/requirement/requirement.module.d.ts.map +1 -0
  95. package/src/nest/modules/requirement/requirement.module.js +72 -0
  96. package/src/scripts/{index.ts → index.d.ts} +1 -0
  97. package/src/scripts/index.d.ts.map +1 -0
  98. package/src/scripts/index.js +5 -0
  99. package/src/scripts/move-keyv-data.program.d.ts +6 -0
  100. package/src/scripts/move-keyv-data.program.d.ts.map +1 -0
  101. package/src/scripts/move-keyv-data.program.js +65 -0
  102. package/src/scripts/update-dependencies-versions.program.d.ts +32 -0
  103. package/src/scripts/update-dependencies-versions.program.d.ts.map +1 -0
  104. package/src/scripts/update-dependencies-versions.program.js +112 -0
  105. package/src/secrets/docker.secret.getter.d.ts +3 -0
  106. package/src/secrets/docker.secret.getter.d.ts.map +1 -0
  107. package/src/secrets/docker.secret.getter.js +6 -0
  108. package/src/secrets/file.secret.getter.d.ts +5 -0
  109. package/src/secrets/file.secret.getter.d.ts.map +1 -0
  110. package/src/secrets/file.secret.getter.js +20 -0
  111. package/src/secrets/{index.ts → index.d.ts} +1 -0
  112. package/src/secrets/index.d.ts.map +1 -0
  113. package/src/secrets/index.js +5 -0
  114. package/src/secrets/local.secret.getter.d.ts +3 -0
  115. package/src/secrets/local.secret.getter.d.ts.map +1 -0
  116. package/src/secrets/local.secret.getter.js +6 -0
  117. package/src/secrets/{types.ts → types.d.ts} +1 -0
  118. package/src/secrets/types.d.ts.map +1 -0
  119. package/src/secrets/types.js +2 -0
  120. package/src/tmp.d.ts +4 -0
  121. package/src/tmp.d.ts.map +1 -0
  122. package/src/tmp.js +16 -0
  123. package/.spec.swcrc +0 -22
  124. package/dist/tsconfig.lib.tsbuildinfo +0 -1
  125. package/eslint.config.mjs +0 -22
  126. package/jest.config.ts +0 -20
  127. package/project.json +0 -26
  128. package/src/http/index.ts +0 -1
  129. package/src/http/types.ts +0 -4
  130. package/src/keyv.store.adapter.factory.ts +0 -43
  131. package/src/nest/add-ons/add-on.interface.ts +0 -5
  132. package/src/nest/add-ons/add-on.wrapper.ts +0 -31
  133. package/src/nest/add-ons/implementations/security/security.add-on.ts +0 -17
  134. package/src/nest/add-ons/implementations/sentry/sentry.add-on.state.interface.ts +0 -5
  135. package/src/nest/add-ons/implementations/sentry/sentry.add-on.ts +0 -24
  136. package/src/nest/add-ons/implementations/swagger/swagger.add-on.state.interface.ts +0 -7
  137. package/src/nest/add-ons/implementations/swagger/swagger.add-on.ts +0 -59
  138. package/src/nest/application.base.ts +0 -18
  139. package/src/nest/application.factory.ts +0 -23
  140. package/src/nest/filters/http.exception.filter.ts +0 -23
  141. package/src/nest/interceptors/error.interceptor.ts +0 -25
  142. package/src/nest/interceptors/response.format.interceptor.ts +0 -29
  143. package/src/nest/modules/health/health.module.ts +0 -20
  144. package/src/nest/modules/health/index.ts +0 -1
  145. package/src/nest/modules/health/middlewares/ping.middleware.ts +0 -9
  146. package/src/nest/modules/requirement/requirement.module.ts +0 -56
  147. package/src/scripts/move-keyv-data.program.ts +0 -88
  148. package/src/scripts/update-dependencies-versions.program.ts +0 -201
  149. package/src/secrets/docker.secret.getter.ts +0 -9
  150. package/src/secrets/file.secret.getter.ts +0 -27
  151. package/src/secrets/local.secret.getter.ts +0 -9
  152. package/src/tmp.ts +0 -15
  153. package/tsconfig.json +0 -16
  154. package/tsconfig.lib.json +0 -18
  155. package/tsconfig.spec.json +0 -23
@@ -0,0 +1,3 @@
1
+ import { FileSecretGetter } from './file.secret.getter';
2
+ export declare const localSecretGetter: FileSecretGetter;
3
+ //# sourceMappingURL=local.secret.getter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.secret.getter.d.ts","sourceRoot":"","sources":["../../../../../packages/back-end/src/secrets/local.secret.getter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAI1E,eAAO,MAAM,iBAAiB,EAAE,gBAI/B,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.localSecretGetter = void 0;
4
+ const file_secret_getter_1 = require("./file.secret.getter");
5
+ const LOCAL_SECRETS_DIRECTORY = '.secrets';
6
+ exports.localSecretGetter = (0, file_secret_getter_1.fileSecretGetter)(LOCAL_SECRETS_DIRECTORY)('Secrets directory not exists on this project. Local secrets will be unavailable.');
@@ -1 +1,2 @@
1
1
  export type SecretGetter = () => object;
2
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../packages/back-end/src/secrets/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/src/tmp.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { ILogger } from '@ask-ell/core';
2
+ export declare const TMP_FOLDER_PATH: string;
3
+ export declare const createTmpFolder: (logger: ILogger) => void;
4
+ //# sourceMappingURL=tmp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmp.d.ts","sourceRoot":"","sources":["../../../../packages/back-end/src/tmp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAIxC,eAAO,MAAM,eAAe,EAAE,MAAmC,CAAC;AAElE,eAAO,MAAM,eAAe,GAAI,QAAQ,OAAO,KAAG,IAQjD,CAAC"}
package/src/tmp.js ADDED
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTmpFolder = exports.TMP_FOLDER_PATH = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ exports.TMP_FOLDER_PATH = (0, node_path_1.join)(process.cwd(), 'tmp');
7
+ const createTmpFolder = (logger) => {
8
+ const isTmpFolderExists = (0, node_fs_1.existsSync)(exports.TMP_FOLDER_PATH);
9
+ if (isTmpFolderExists) {
10
+ logger.info(`"${exports.TMP_FOLDER_PATH}" folder already exists.`);
11
+ return;
12
+ }
13
+ (0, node_fs_1.mkdirSync)(exports.TMP_FOLDER_PATH);
14
+ logger.info(`"${exports.TMP_FOLDER_PATH}" folder created.`);
15
+ };
16
+ exports.createTmpFolder = createTmpFolder;
package/.spec.swcrc DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "jsc": {
3
- "target": "es2017",
4
- "parser": {
5
- "syntax": "typescript",
6
- "decorators": true,
7
- "dynamicImport": true
8
- },
9
- "transform": {
10
- "decoratorMetadata": true,
11
- "legacyDecorator": true
12
- },
13
- "keepClassNames": true,
14
- "externalHelpers": true,
15
- "loose": true
16
- },
17
- "module": {
18
- "type": "es6"
19
- },
20
- "sourceMaps": true,
21
- "exclude": []
22
- }
@@ -1 +0,0 @@
1
- {"version":"6.0.3"}
package/eslint.config.mjs DELETED
@@ -1,22 +0,0 @@
1
- import baseConfig from '../../eslint.config.mjs';
2
-
3
- export default [
4
- ...baseConfig,
5
- {
6
- files: ['**/*.json'],
7
- rules: {
8
- '@nx/dependency-checks': [
9
- 'error',
10
- {
11
- ignoredFiles: ['{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}'],
12
- },
13
- ],
14
- },
15
- languageOptions: {
16
- parser: await import('jsonc-eslint-parser'),
17
- },
18
- },
19
- {
20
- ignores: ['**/out-tsc'],
21
- },
22
- ];
package/jest.config.ts DELETED
@@ -1,20 +0,0 @@
1
- import { readFileSync } from 'fs';
2
-
3
- // Reading the SWC compilation config for the spec files
4
- const swcJestConfig = JSON.parse(
5
- readFileSync(`${__dirname}/.spec.swcrc`, 'utf-8')
6
- );
7
-
8
- // Disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves
9
- swcJestConfig.swcrc = false;
10
-
11
- export default {
12
- displayName: '@ask-ell/back-end',
13
- preset: '../../jest.preset.js',
14
- testEnvironment: 'node',
15
- transform: {
16
- '^.+\\.[tj]s$': ['@swc/jest', swcJestConfig],
17
- },
18
- moduleFileExtensions: ['ts', 'js', 'html'],
19
- coverageDirectory: 'test-output/jest/coverage',
20
- };
package/project.json DELETED
@@ -1,26 +0,0 @@
1
- {
2
- "name": "back-end",
3
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
- "sourceRoot": "packages/back-end/src",
5
- "projectType": "library",
6
- "tags": [],
7
- "targets": {
8
- "build": {
9
- "executor": "@nx/js:tsc",
10
- "dependsOn": ["^build"],
11
- "outputs": ["{options.outputPath}"],
12
- "options": {
13
- "outputPath": "dist/packages/back-end",
14
- "main": "packages/back-end/src/index.ts",
15
- "tsConfig": "packages/back-end/tsconfig.lib.json",
16
- "assets": ["packages/back-end/*.md"]
17
- }
18
- },
19
- "test": {
20
- "options": {
21
- "passWithNoTests": true
22
- }
23
- },
24
- "format": {}
25
- }
26
- }
package/src/http/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './types';
package/src/http/types.ts DELETED
@@ -1,4 +0,0 @@
1
- export type HttpResponseBody<Data = unknown> = {
2
- message: string;
3
- data?: Data;
4
- };
@@ -1,43 +0,0 @@
1
- import { Injectable } from '@nestjs/common';
2
- import { KeyvStoreAdapter } from 'keyv';
3
- import KeyvSqlite from '@keyv/sqlite';
4
- import KeyvPostgres from '@keyv/postgres';
5
- import { ILogger, MaybeUndefined } from '@ask-ell/core';
6
- import { NestLogger } from '@ask-ell/nest';
7
- import { join } from 'node:path';
8
-
9
- import { createTmpFolder, TMP_FOLDER_PATH } from './tmp';
10
-
11
- export type CreateKeyvStoreAdapterOptions = {
12
- postgresUri: MaybeUndefined<string>;
13
- };
14
-
15
- @Injectable()
16
- export class KeyvStoreAdapterFactory {
17
- private logger: ILogger = NestLogger.fromClass(KeyvStoreAdapterFactory);
18
-
19
- create(options: CreateKeyvStoreAdapterOptions): KeyvStoreAdapter {
20
- const adapter: KeyvStoreAdapter = this.getKeyvStoreAdapter(options);
21
- this.logger.log(
22
- `Connected to database with adapter "${adapter.constructor.name}"`
23
- );
24
- return adapter;
25
- }
26
-
27
- private getKeyvStoreAdapter({
28
- postgresUri,
29
- }: CreateKeyvStoreAdapterOptions): KeyvStoreAdapter {
30
- if (!postgresUri) {
31
- createTmpFolder(this.logger);
32
- const localDatabaseFilePath: string = join(
33
- TMP_FOLDER_PATH,
34
- 'database.sqlite'
35
- );
36
- return new KeyvSqlite(localDatabaseFilePath);
37
- }
38
-
39
- return new KeyvPostgres({
40
- uri: postgresUri,
41
- });
42
- }
43
- }
@@ -1,5 +0,0 @@
1
- import { INestApplication } from '@nestjs/common';
2
-
3
- export interface IAddOn<T> {
4
- apply(application: INestApplication<T>): void;
5
- }
@@ -1,31 +0,0 @@
1
- import { INestApplication } from '@nestjs/common';
2
-
3
- import { IAddOn } from './add-on.interface';
4
- import { SecurityAddOn } from './implementations/security/security.add-on';
5
- import { AddOnWrapperParams } from './types';
6
- import { SwaggerAddon } from './implementations/swagger/swagger.add-on';
7
- import { SentryAddon } from './implementations/sentry/sentry.add-on';
8
-
9
- export class AddOnWrapper<T> implements IAddOn<T> {
10
- private implementations: IAddOn<T>[] = [new SecurityAddOn()];
11
-
12
- constructor(private params: AddOnWrapperParams) {
13
- this.appendImplementations();
14
- }
15
-
16
- apply(application: INestApplication<T>): void {
17
- this.implementations.forEach((addOn: IAddOn<T>): void => {
18
- addOn.apply(application);
19
- });
20
- }
21
-
22
- private appendImplementations(): void {
23
- const { sentry, swagger } = this.params;
24
- if (swagger) {
25
- this.implementations.push(new SwaggerAddon(swagger));
26
- }
27
- if (sentry) {
28
- this.implementations.push(new SentryAddon(sentry));
29
- }
30
- }
31
- }
@@ -1,17 +0,0 @@
1
- import { INestApplication, ValidationPipe } from '@nestjs/common';
2
- import helmet from 'helmet';
3
-
4
- import { IAddOn } from '../../add-on.interface';
5
-
6
- export class SecurityAddOn<T> implements IAddOn<T> {
7
- apply(application: INestApplication<T>): void {
8
- application.enableCors();
9
- application.use(helmet());
10
- application.useGlobalPipes(
11
- new ValidationPipe({
12
- transform: true,
13
- whitelist: false,
14
- })
15
- );
16
- }
17
- }
@@ -1,5 +0,0 @@
1
- export interface ISentryAddOnState {
2
- publicKey: string;
3
- host: string;
4
- projectId: string;
5
- }
@@ -1,24 +0,0 @@
1
- import { Entity, type IResult, ok } from '@ask-ell/core';
2
- import { NestSentryConfiguration } from '@ask-ell/nest';
3
-
4
- import { ISentryAddOnState } from './sentry.add-on.state.interface';
5
- import { ISentryAddOn } from './sentry.add-on.interface';
6
-
7
- export class SentryAddon<T>
8
- extends Entity<ISentryAddOnState>
9
- implements ISentryAddOn<T>
10
- {
11
- checkStateValidity(): IResult<void> {
12
- return ok();
13
- }
14
-
15
- apply(): void {
16
- const { host, projectId, publicKey } = this.getSnapshot();
17
-
18
- new NestSentryConfiguration({
19
- publicKey,
20
- host,
21
- projectId,
22
- }).init();
23
- }
24
- }
@@ -1,7 +0,0 @@
1
- import { AuthMethod } from './types';
2
-
3
- export interface ISwaggerAddOnState {
4
- title: string;
5
- auths?: AuthMethod[];
6
- enabledInProduction?: boolean;
7
- }
@@ -1,59 +0,0 @@
1
- import {
2
- Entity,
3
- ILogger,
4
- type IResult,
5
- isOnDevelopmentMode,
6
- ok,
7
- } from '@ask-ell/core';
8
- import { NestLogger } from '@ask-ell/nest';
9
- import { type INestApplication } from '@nestjs/common';
10
- import {
11
- DocumentBuilder,
12
- type OpenAPIObject,
13
- SwaggerModule,
14
- } from '@nestjs/swagger';
15
-
16
- import { ISwaggerAddOnState } from './swagger.add-on.state.interface';
17
- import { ISwaggerAddOn } from './swagger.add-on.interface';
18
- import { AuthMethod } from './types';
19
-
20
- export class SwaggerAddon<T>
21
- extends Entity<ISwaggerAddOnState>
22
- implements ISwaggerAddOn<T>
23
- {
24
- private logger: ILogger = NestLogger.fromClass(SwaggerAddon);
25
-
26
- checkStateValidity(): IResult<void> {
27
- return ok();
28
- }
29
-
30
- apply(application: INestApplication<T>): void {
31
- const { title, auths, enabledInProduction } = this.getSnapshot();
32
-
33
- if (!enabledInProduction && !isOnDevelopmentMode()) {
34
- return;
35
- }
36
-
37
- const documentBuilder: DocumentBuilder = new DocumentBuilder().setTitle(
38
- title
39
- );
40
-
41
- auths?.forEach((auth: AuthMethod): void => {
42
- if (auth === 'bearer') {
43
- documentBuilder.addBearerAuth();
44
- }
45
- });
46
-
47
- const documentBuild: Omit<OpenAPIObject, 'paths'> = documentBuilder.build();
48
-
49
- const documentFactory = (): OpenAPIObject =>
50
- SwaggerModule.createDocument(application, documentBuild);
51
-
52
- SwaggerModule.setup('/swagger', application, documentFactory, {
53
- customSiteTitle: title,
54
- jsonDocumentUrl: '/swagger/json',
55
- });
56
-
57
- this.logger.log('Swagger initialized');
58
- }
59
- }
@@ -1,18 +0,0 @@
1
- import { DynamicModule, Provider, Module, Global } from '@nestjs/common';
2
-
3
- import { RequirementModule } from './modules';
4
-
5
- @Global()
6
- @Module({
7
- imports: [RequirementModule],
8
- })
9
- export class ApplicationBase {
10
- static withProviders(providers: Provider[]): DynamicModule {
11
- const providersAndExports: Provider[] = [...providers];
12
- return {
13
- module: this,
14
- providers: providersAndExports,
15
- exports: [...providersAndExports],
16
- };
17
- }
18
- }
@@ -1,23 +0,0 @@
1
- import { ConsoleLogger, DynamicModule, INestApplication } from '@nestjs/common';
2
- import { NestFactory } from '@nestjs/core';
3
- import { IServerProvider } from '@ask-ell/node';
4
-
5
- import { AddOnWrapper, AddOnWrapperParams } from './add-ons';
6
-
7
- export type NestApplicationFactoryParams = {
8
- addons: AddOnWrapperParams;
9
- module: DynamicModule;
10
- };
11
-
12
- export async function createNestApplication({
13
- module,
14
- addons: addonsParams,
15
- }: NestApplicationFactoryParams): Promise<IServerProvider> {
16
- const application: INestApplication = await NestFactory.create(module, {
17
- logger: new ConsoleLogger({
18
- json: true,
19
- }),
20
- });
21
- new AddOnWrapper(addonsParams).apply(application);
22
- return application;
23
- }
@@ -1,23 +0,0 @@
1
- import {
2
- type ExceptionFilter,
3
- type ArgumentsHost,
4
- Catch,
5
- HttpException,
6
- } from '@nestjs/common';
7
- import type { HttpArgumentsHost } from '@nestjs/common/interfaces';
8
- import type { Response } from 'express';
9
-
10
- import type { HttpResponseBody } from '../../http';
11
-
12
- @Catch(HttpException)
13
- export class HttpExceptionFilter implements ExceptionFilter {
14
- catch(exception: HttpException, host: ArgumentsHost): void {
15
- const context: HttpArgumentsHost = host.switchToHttp();
16
- const response: Response = context.getResponse<Response>();
17
- const status: number = exception.getStatus();
18
- const responseData: HttpResponseBody = {
19
- message: exception.message,
20
- };
21
- response.status(status).json(responseData);
22
- }
23
- }
@@ -1,25 +0,0 @@
1
- import { Entity, IResult, ok } from '@ask-ell/core';
2
- import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
3
- import { catchError, Observable, throwError } from 'rxjs';
4
-
5
- export type ErrorInterceptorProps = {
6
- errorConvertor: (error: unknown) => unknown;
7
- };
8
-
9
- export class ErrorInterceptor
10
- extends Entity<ErrorInterceptorProps>
11
- implements NestInterceptor
12
- {
13
- override checkStateValidity(): IResult {
14
- return ok();
15
- }
16
-
17
- intercept(_: ExecutionContext, next: CallHandler): Observable<unknown> {
18
- const { errorConvertor } = this.getSnapshot();
19
- return next.handle().pipe(
20
- catchError((error: unknown): Observable<never> => {
21
- return throwError((): unknown => errorConvertor(error));
22
- })
23
- );
24
- }
25
- }
@@ -1,29 +0,0 @@
1
- import {
2
- Injectable,
3
- NestInterceptor,
4
- ExecutionContext,
5
- CallHandler,
6
- } from '@nestjs/common';
7
- import { Observable } from 'rxjs';
8
- import { map } from 'rxjs/operators';
9
-
10
- import { HttpResponseBody } from '../../http/types';
11
-
12
- @Injectable()
13
- export class ResponseFormatInterceptor<T>
14
- implements NestInterceptor<T, HttpResponseBody<T>>
15
- {
16
- intercept(
17
- _context: ExecutionContext,
18
- next: CallHandler
19
- ): Observable<HttpResponseBody<T>> {
20
- return next.handle().pipe(
21
- map(
22
- (data: T): HttpResponseBody<T> => ({
23
- data,
24
- message: 'ok',
25
- })
26
- )
27
- );
28
- }
29
- }
@@ -1,20 +0,0 @@
1
- import {
2
- MiddlewareConsumer,
3
- Module,
4
- NestModule,
5
- RequestMethod,
6
- } from '@nestjs/common';
7
-
8
- import { PingMiddleware } from './middlewares';
9
-
10
- @Module({
11
- providers: [PingMiddleware],
12
- })
13
- export class HealthModule implements NestModule {
14
- configure(consumer: MiddlewareConsumer): void {
15
- consumer.apply(PingMiddleware).forRoutes({
16
- path: '/health/ping',
17
- method: RequestMethod.GET,
18
- });
19
- }
20
- }
@@ -1 +0,0 @@
1
- export * from './health.module';
@@ -1,9 +0,0 @@
1
- import { Injectable, NestMiddleware } from '@nestjs/common';
2
- import type { Request, Response } from 'express';
3
-
4
- @Injectable()
5
- export class PingMiddleware implements NestMiddleware {
6
- use(_request: Request, response: Response): void {
7
- response.end('Pong');
8
- }
9
- }
@@ -1,56 +0,0 @@
1
- import { Module } from '@nestjs/common';
2
- import { ConfigModule } from '@nestjs/config';
3
- import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
4
- import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler';
5
- import type { ILogger } from '@ask-ell/core';
6
- import { NestLogger } from '@ask-ell/nest';
7
- import { SentryGlobalFilter, SentryModule } from '@sentry/nestjs/setup';
8
-
9
- import { KeyvStoreAdapterFactory } from '../../../keyv.store.adapter.factory';
10
- import { dockerSecretGetter, localSecretGetter } from '../../../secrets';
11
- import { HealthModule } from '../health';
12
- import { ResponseFormatInterceptor } from '../../interceptors';
13
- import { HttpExceptionFilter } from '../../filters';
14
-
15
- const configModuleLogger: ILogger = NestLogger.fromClass(ConfigModule);
16
-
17
- @Module({
18
- imports: [
19
- HealthModule,
20
- SentryModule.forRoot(),
21
- ThrottlerModule.forRoot([
22
- {
23
- ttl: 60000,
24
- limit: 30,
25
- },
26
- ]),
27
- ConfigModule.forRoot({
28
- isGlobal: true,
29
- load: [
30
- dockerSecretGetter(configModuleLogger),
31
- localSecretGetter(configModuleLogger),
32
- ],
33
- }),
34
- ],
35
- providers: [
36
- KeyvStoreAdapterFactory,
37
- {
38
- provide: APP_GUARD,
39
- useClass: ThrottlerGuard,
40
- },
41
- {
42
- provide: APP_INTERCEPTOR,
43
- useClass: ResponseFormatInterceptor,
44
- },
45
- {
46
- provide: APP_FILTER,
47
- useClass: HttpExceptionFilter,
48
- },
49
- {
50
- provide: APP_FILTER,
51
- useClass: SentryGlobalFilter,
52
- },
53
- ],
54
- exports: [ConfigModule, SentryModule, KeyvStoreAdapterFactory],
55
- })
56
- export class RequirementModule {}
@@ -1,88 +0,0 @@
1
- import { PercentageIncrementor } from '@ask-ell/core';
2
- import { Program, ProgramExecutionOptions } from '@ask-ell/node';
3
- import { NestLogger } from '@ask-ell/nest';
4
- import { Client, QueryResult } from 'pg';
5
-
6
- type KeyvRowData<Value = unknown> = {
7
- key: string;
8
- value: Value;
9
- };
10
-
11
- export class MoveKeyvDataProgram extends Program {
12
- constructor() {
13
- super({
14
- arguments: [
15
- {
16
- name: 'origin',
17
- description: 'Origin Postgres database URI',
18
- required: true,
19
- },
20
- {
21
- name: 'target',
22
- description: 'Target Postgres database URI',
23
- required: true,
24
- },
25
- ],
26
- logger: NestLogger.fromClass(MoveKeyvDataProgram),
27
- });
28
- }
29
-
30
- async execute({
31
- logger,
32
- arguments: { origin, target },
33
- prompts: { confirm },
34
- }: ProgramExecutionOptions): Promise<void> {
35
- const originPostgresClient: Client = new Client(origin);
36
- const targetPostgresClient: Client = new Client(target);
37
-
38
- logger.log('Reading databases...');
39
-
40
- await Promise.all([
41
- originPostgresClient.connect(),
42
- targetPostgresClient.connect(),
43
- ]);
44
-
45
- try {
46
- const { rows }: QueryResult<KeyvRowData> =
47
- await originPostgresClient.query('SELECT * FROM keyv');
48
-
49
- const rowsCount: number = rows.length;
50
- logger.log(
51
- `You're going to insert ${rowsCount} keyv entries from the original database to the target database.`
52
- );
53
-
54
- const confirmed: boolean = await confirm(
55
- 'Are you sure you want to proceed?'
56
- );
57
-
58
- if (confirmed) {
59
- logger.log('Inserting entries into the target database...');
60
- const incrementor: PercentageIncrementor = new PercentageIncrementor(
61
- rowsCount
62
- );
63
- incrementor.onIncrement(({ achivmentOnPercent }): void => {
64
- logger.log(`Progress: ${achivmentOnPercent}%`);
65
- });
66
-
67
- for (const { key, value } of rows) {
68
- await targetPostgresClient.query(
69
- 'INSERT INTO keyv (key, value) VALUES ($1, $2)',
70
- [key, value]
71
- );
72
- incrementor.increment();
73
- }
74
-
75
- logger.log(`${rowsCount} entries inserted into the target database.`);
76
- logger.log('Migration completed successfully.');
77
- } else {
78
- logger.log('Migration cancelled.');
79
- }
80
- } finally {
81
- await Promise.all([
82
- originPostgresClient.end(),
83
- targetPostgresClient.end(),
84
- ]);
85
- logger.log('Database connections closed.');
86
- }
87
- }
88
- }