@ask-ell/back-end 0.2.4 → 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.
- package/CHANGELOG.md +20 -0
- package/package.json +2 -2
- package/src/http/index.d.ts +2 -0
- package/src/http/index.d.ts.map +1 -0
- package/src/http/index.js +4 -0
- package/src/http/types.d.ts +5 -0
- package/src/http/types.d.ts.map +1 -0
- package/src/http/types.js +2 -0
- package/src/{index.ts → index.d.ts} +1 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +10 -0
- package/src/keyv.store.adapter.factory.d.ts +11 -0
- package/src/keyv.store.adapter.factory.d.ts.map +1 -0
- package/src/keyv.store.adapter.factory.js +44 -0
- package/src/nest/add-ons/add-on.interface.d.ts +5 -0
- package/src/nest/add-ons/add-on.interface.d.ts.map +1 -0
- package/src/nest/add-ons/add-on.interface.js +2 -0
- package/src/nest/add-ons/add-on.wrapper.d.ts +11 -0
- package/src/nest/add-ons/add-on.wrapper.d.ts.map +1 -0
- package/src/nest/add-ons/add-on.wrapper.js +29 -0
- package/src/nest/add-ons/implementations/security/security.add-on.d.ts +6 -0
- package/src/nest/add-ons/implementations/security/security.add-on.d.ts.map +1 -0
- package/src/nest/add-ons/implementations/security/security.add-on.js +16 -0
- package/src/nest/add-ons/implementations/sentry/sentry.add-on.d.ts +8 -0
- package/src/nest/add-ons/implementations/sentry/sentry.add-on.d.ts.map +1 -0
- package/src/nest/add-ons/implementations/sentry/{sentry.add-on.interface.ts → sentry.add-on.interface.d.ts} +3 -5
- package/src/nest/add-ons/implementations/sentry/sentry.add-on.interface.d.ts.map +1 -0
- package/src/nest/add-ons/implementations/sentry/sentry.add-on.interface.js +2 -0
- package/src/nest/add-ons/implementations/sentry/sentry.add-on.js +19 -0
- package/src/nest/add-ons/implementations/sentry/sentry.add-on.state.interface.d.ts +6 -0
- package/src/nest/add-ons/implementations/sentry/sentry.add-on.state.interface.d.ts.map +1 -0
- package/src/nest/add-ons/implementations/sentry/sentry.add-on.state.interface.js +2 -0
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.d.ts +10 -0
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.d.ts.map +1 -0
- package/src/nest/add-ons/implementations/swagger/{swagger.add-on.interface.ts → swagger.add-on.interface.d.ts} +3 -5
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.interface.d.ts.map +1 -0
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.interface.js +2 -0
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.js +32 -0
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.state.interface.d.ts +7 -0
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.state.interface.d.ts.map +1 -0
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.state.interface.js +2 -0
- package/src/nest/add-ons/implementations/swagger/{types.ts → types.d.ts} +1 -0
- package/src/nest/add-ons/implementations/swagger/types.d.ts.map +1 -0
- package/src/nest/add-ons/implementations/swagger/types.js +2 -0
- package/src/nest/add-ons/{index.ts → index.d.ts} +1 -0
- package/src/nest/add-ons/index.d.ts.map +1 -0
- package/src/nest/add-ons/index.js +9 -0
- package/src/nest/add-ons/{types.ts → types.d.ts} +3 -3
- package/src/nest/add-ons/types.d.ts.map +1 -0
- package/src/nest/add-ons/types.js +2 -0
- package/src/nest/application.base.d.ts +5 -0
- package/src/nest/application.base.d.ts.map +1 -0
- package/src/nest/application.base.js +34 -0
- package/src/nest/application.factory.d.ts +9 -0
- package/src/nest/application.factory.d.ts.map +1 -0
- package/src/nest/application.factory.js +15 -0
- package/src/nest/filters/http.exception.filter.d.ts +5 -0
- package/src/nest/filters/http.exception.filter.d.ts.map +1 -0
- package/src/nest/filters/http.exception.filter.js +32 -0
- package/src/nest/filters/{index.ts → index.d.ts} +1 -0
- package/src/nest/filters/index.d.ts.map +1 -0
- package/src/nest/filters/index.js +4 -0
- package/src/nest/{index.ts → index.d.ts} +1 -0
- package/src/nest/index.d.ts.map +1 -0
- package/src/nest/index.js +9 -0
- package/src/nest/interceptors/error.interceptor.d.ts +11 -0
- package/src/nest/interceptors/error.interceptor.d.ts.map +1 -0
- package/src/nest/interceptors/error.interceptor.js +17 -0
- package/src/nest/interceptors/{index.ts → index.d.ts} +1 -0
- package/src/nest/interceptors/index.d.ts.map +1 -0
- package/src/nest/interceptors/index.js +5 -0
- package/src/nest/interceptors/response.format.interceptor.d.ts +7 -0
- package/src/nest/interceptors/response.format.interceptor.d.ts.map +1 -0
- package/src/nest/interceptors/response.format.interceptor.js +30 -0
- package/src/nest/modules/health/health.module.d.ts +5 -0
- package/src/nest/modules/health/health.module.d.ts.map +1 -0
- package/src/nest/modules/health/health.module.js +32 -0
- package/src/nest/modules/health/index.d.ts +2 -0
- package/src/nest/modules/health/index.d.ts.map +1 -0
- package/src/nest/modules/health/index.js +4 -0
- package/src/nest/modules/health/middlewares/{index.ts → index.d.ts} +1 -0
- package/src/nest/modules/health/middlewares/index.d.ts.map +1 -0
- package/src/nest/modules/health/middlewares/index.js +4 -0
- package/src/nest/modules/health/middlewares/ping.middleware.d.ts +6 -0
- package/src/nest/modules/health/middlewares/ping.middleware.d.ts.map +1 -0
- package/src/nest/modules/health/middlewares/ping.middleware.js +26 -0
- package/src/nest/modules/{index.ts → index.d.ts} +1 -0
- package/src/nest/modules/index.d.ts.map +1 -0
- package/src/nest/modules/index.js +5 -0
- package/src/nest/modules/requirement/{index.ts → index.d.ts} +1 -0
- package/src/nest/modules/requirement/index.d.ts.map +1 -0
- package/src/nest/modules/requirement/index.js +4 -0
- package/src/nest/modules/requirement/requirement.module.d.ts +3 -0
- package/src/nest/modules/requirement/requirement.module.d.ts.map +1 -0
- package/src/nest/modules/requirement/requirement.module.js +72 -0
- package/src/scripts/{index.ts → index.d.ts} +1 -0
- package/src/scripts/index.d.ts.map +1 -0
- package/src/scripts/index.js +5 -0
- package/src/scripts/move-keyv-data.program.d.ts +6 -0
- package/src/scripts/move-keyv-data.program.d.ts.map +1 -0
- package/src/scripts/move-keyv-data.program.js +65 -0
- package/src/scripts/update-dependencies-versions.program.d.ts +32 -0
- package/src/scripts/update-dependencies-versions.program.d.ts.map +1 -0
- package/src/scripts/update-dependencies-versions.program.js +112 -0
- package/src/secrets/docker.secret.getter.d.ts +3 -0
- package/src/secrets/docker.secret.getter.d.ts.map +1 -0
- package/src/secrets/docker.secret.getter.js +6 -0
- package/src/secrets/file.secret.getter.d.ts +5 -0
- package/src/secrets/file.secret.getter.d.ts.map +1 -0
- package/src/secrets/file.secret.getter.js +20 -0
- package/src/secrets/{index.ts → index.d.ts} +1 -0
- package/src/secrets/index.d.ts.map +1 -0
- package/src/secrets/index.js +5 -0
- package/src/secrets/local.secret.getter.d.ts +3 -0
- package/src/secrets/local.secret.getter.d.ts.map +1 -0
- package/src/secrets/local.secret.getter.js +6 -0
- package/src/secrets/{types.ts → types.d.ts} +1 -0
- package/src/secrets/types.d.ts.map +1 -0
- package/src/secrets/types.js +2 -0
- package/src/tmp.d.ts +4 -0
- package/src/tmp.d.ts.map +1 -0
- package/src/tmp.js +16 -0
- package/.spec.swcrc +0 -22
- package/dist/tsconfig.lib.tsbuildinfo +0 -1
- package/eslint.config.mjs +0 -22
- package/jest.config.ts +0 -20
- package/project.json +0 -26
- package/src/http/index.ts +0 -1
- package/src/http/types.ts +0 -4
- package/src/keyv.store.adapter.factory.ts +0 -43
- package/src/nest/add-ons/add-on.interface.ts +0 -5
- package/src/nest/add-ons/add-on.wrapper.ts +0 -31
- package/src/nest/add-ons/implementations/security/security.add-on.ts +0 -17
- package/src/nest/add-ons/implementations/sentry/sentry.add-on.state.interface.ts +0 -5
- package/src/nest/add-ons/implementations/sentry/sentry.add-on.ts +0 -24
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.state.interface.ts +0 -7
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.ts +0 -59
- package/src/nest/application.base.ts +0 -18
- package/src/nest/application.factory.ts +0 -23
- package/src/nest/filters/http.exception.filter.ts +0 -23
- package/src/nest/interceptors/error.interceptor.ts +0 -25
- package/src/nest/interceptors/response.format.interceptor.ts +0 -29
- package/src/nest/modules/health/health.module.ts +0 -20
- package/src/nest/modules/health/index.ts +0 -1
- package/src/nest/modules/health/middlewares/ping.middleware.ts +0 -9
- package/src/nest/modules/requirement/requirement.module.ts +0 -56
- package/src/scripts/move-keyv-data.program.ts +0 -88
- package/src/scripts/update-dependencies-versions.program.ts +0 -201
- package/src/secrets/docker.secret.getter.ts +0 -9
- package/src/secrets/file.secret.getter.ts +0 -27
- package/src/secrets/local.secret.getter.ts +0 -9
- package/src/tmp.ts +0 -15
- package/tsconfig.json +0 -16
- package/tsconfig.lib.json +0 -18
- package/tsconfig.spec.json +0 -23
|
@@ -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.');
|
|
@@ -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"}
|
package/src/tmp.d.ts
ADDED
package/src/tmp.d.ts.map
ADDED
|
@@ -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,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,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,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,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
|
-
}
|