@ask-ell/back-end 0.1.1 → 0.2.3
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 +11 -0
- package/jest.config.ts +0 -1
- package/package.json +4 -2
- package/project.json +4 -7
- package/src/http/index.ts +1 -0
- package/src/http/types.ts +4 -0
- package/src/index.ts +2 -2
- package/src/keyv.store.adapter.factory.ts +31 -25
- package/src/nest/add-ons/add-on.interface.ts +5 -0
- package/src/nest/add-ons/add-on.wrapper.ts +31 -0
- package/src/{add-ons → nest/add-ons}/implementations/security/security.add-on.ts +3 -4
- package/src/nest/add-ons/implementations/sentry/sentry.add-on.interface.ts +8 -0
- package/src/{add-ons → nest/add-ons}/implementations/sentry/sentry.add-on.state.interface.ts +1 -1
- package/src/{add-ons → nest/add-ons}/implementations/sentry/sentry.add-on.ts +8 -9
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.interface.ts +8 -0
- package/src/{add-ons → nest/add-ons}/implementations/swagger/swagger.add-on.state.interface.ts +3 -2
- package/src/nest/add-ons/implementations/swagger/swagger.add-on.ts +59 -0
- package/src/nest/add-ons/implementations/swagger/types.ts +1 -0
- package/src/nest/add-ons/index.ts +6 -0
- package/src/nest/add-ons/types.ts +7 -0
- package/src/nest/application.base.ts +18 -0
- package/src/nest/application.factory.ts +23 -0
- package/src/nest/filters/http.exception.filter.ts +23 -0
- package/src/nest/filters/index.ts +1 -0
- package/src/nest/index.ts +6 -0
- package/src/nest/interceptors/error.interceptor.ts +25 -0
- package/src/nest/interceptors/index.ts +2 -0
- package/src/nest/interceptors/response.format.interceptor.ts +29 -0
- package/src/nest/modules/health/health.module.ts +20 -0
- package/src/nest/modules/health/index.ts +1 -0
- package/src/nest/modules/health/middlewares/index.ts +1 -0
- package/src/nest/modules/health/middlewares/ping.middleware.ts +9 -0
- package/src/nest/modules/index.ts +2 -0
- package/src/nest/modules/requirement/index.ts +1 -0
- package/src/nest/modules/requirement/requirement.module.ts +56 -0
- package/src/scripts/move-keyv-data.script.ts +69 -48
- package/src/scripts/update-dependencies-versions.script.ts +164 -130
- package/src/secrets/docker.secret.getter.ts +6 -5
- package/src/secrets/file.secret.getter.ts +19 -16
- package/src/secrets/index.ts +2 -2
- package/src/secrets/local.secret.getter.ts +6 -5
- package/src/tmp.ts +15 -0
- package/src/add-ons/add-on.interface.ts +0 -5
- package/src/add-ons/add-on.wrapper.ts +0 -36
- package/src/add-ons/implementations/sentry/sentry.add-on.interface.ts +0 -8
- package/src/add-ons/implementations/swagger/swagger.add-on.interface.ts +0 -7
- package/src/add-ons/implementations/swagger/swagger.add-on.ts +0 -43
- package/src/add-ons/implementations/swagger/types.ts +0 -1
- package/src/add-ons/index.ts +0 -1
- package/src/add-ons/types.ts +0 -7
- package/src/application.base.ts +0 -15
- package/src/requirement.module.ts +0 -57
- package/src/utils/index.ts +0 -1
- package/src/utils/tmp.ts +0 -16
|
@@ -3,65 +3,86 @@ import { Script, ExecuteOptions } from '@ask-ell/node';
|
|
|
3
3
|
import { NestLogger } from '@ask-ell/nest';
|
|
4
4
|
import { Client, QueryResult } from 'pg';
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
type KeyvRowData<Value = unknown> = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
7
|
+
key: string;
|
|
8
|
+
value: Value;
|
|
9
|
+
};
|
|
11
10
|
|
|
12
11
|
export class MoveKeyvDataScript extends Script {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
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(MoveKeyvDataScript),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
22
29
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
async execute({
|
|
31
|
+
logger,
|
|
32
|
+
arguments: { origin, target },
|
|
33
|
+
prompts: { confirm },
|
|
34
|
+
}: ExecuteOptions): Promise<void> {
|
|
35
|
+
const originPostgresClient: Client = new Client(origin);
|
|
36
|
+
const targetPostgresClient: Client = new Client(target);
|
|
26
37
|
|
|
27
|
-
|
|
38
|
+
logger.log('Reading databases...');
|
|
28
39
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
await Promise.all([
|
|
41
|
+
originPostgresClient.connect(),
|
|
42
|
+
targetPostgresClient.connect(),
|
|
43
|
+
]);
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
try {
|
|
46
|
+
const { rows }: QueryResult<KeyvRowData> =
|
|
47
|
+
await originPostgresClient.query('SELECT * FROM keyv');
|
|
36
48
|
|
|
37
|
-
|
|
38
|
-
|
|
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
|
+
);
|
|
39
53
|
|
|
40
|
-
|
|
54
|
+
const confirmed: boolean = await confirm(
|
|
55
|
+
'Are you sure you want to proceed?'
|
|
56
|
+
);
|
|
41
57
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
await targetPostgresClient.query('INSERT INTO keyv (key, value) VALUES ($1, $2)', [key, value]);
|
|
51
|
-
incrementor.increment();
|
|
52
|
-
}
|
|
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
|
+
});
|
|
53
66
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
await Promise.all([
|
|
61
|
-
originPostgresClient.end(),
|
|
62
|
-
targetPostgresClient.end()
|
|
63
|
-
]);
|
|
64
|
-
logger.log('Database connections closed.');
|
|
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();
|
|
65
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.');
|
|
66
86
|
}
|
|
87
|
+
}
|
|
67
88
|
}
|
|
@@ -1,167 +1,201 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
MaybeUndefined,
|
|
3
|
+
StringDictionnary,
|
|
4
|
+
UnknownEnvironmentVariableError,
|
|
5
|
+
} from '@ask-ell/core';
|
|
6
|
+
import { NestLogger } from '@ask-ell/nest';
|
|
7
|
+
import { ExecuteOptions, Script } from '@ask-ell/node';
|
|
4
8
|
import { spawnSync } from 'node:child_process';
|
|
5
|
-
import { writeFileSync } from
|
|
9
|
+
import { writeFileSync } from 'node:fs';
|
|
6
10
|
import { mkdir } from 'node:fs/promises';
|
|
7
11
|
import { join } from 'node:path';
|
|
8
12
|
|
|
9
|
-
|
|
10
13
|
const PROJECT_ROOT_PATH: MaybeUndefined<string> = process.env['PWD'];
|
|
11
14
|
|
|
12
|
-
function makeSureThatProjectRootPathIsDefined(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
function makeSureThatProjectRootPathIsDefined(
|
|
16
|
+
projectRootPath: MaybeUndefined<string>
|
|
17
|
+
): asserts projectRootPath is string {
|
|
18
|
+
if (!projectRootPath) {
|
|
19
|
+
throw new UnknownEnvironmentVariableError('PWD');
|
|
20
|
+
}
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
makeSureThatProjectRootPathIsDefined(PROJECT_ROOT_PATH);
|
|
19
24
|
|
|
20
25
|
const NX_GRAPH_FILE_PATH: string = join(PROJECT_ROOT_PATH, 'tmp/graph.json');
|
|
21
26
|
|
|
22
|
-
type PackageContent = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
export type PackageContent = {
|
|
28
|
+
version: string;
|
|
29
|
+
dependencies: StringDictionnary;
|
|
30
|
+
devDependencies: StringDictionnary;
|
|
26
31
|
};
|
|
27
32
|
|
|
28
33
|
const ROOT_PACKAGE_FILE_PATH: string = join(PROJECT_ROOT_PATH, `package.json`);
|
|
29
34
|
const ROOT_PACKAGE_CONTENT: PackageContent = require(ROOT_PACKAGE_FILE_PATH);
|
|
30
35
|
|
|
31
|
-
|
|
32
36
|
function getOrganisationPackageFile(packageId: string): PackageContent {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
makeSureThatProjectRootPathIsDefined(PROJECT_ROOT_PATH);
|
|
38
|
+
const packageFilePath = join(
|
|
39
|
+
PROJECT_ROOT_PATH,
|
|
40
|
+
`packages/${packageId}/package.json`
|
|
41
|
+
);
|
|
42
|
+
return require(packageFilePath);
|
|
36
43
|
}
|
|
37
44
|
|
|
38
|
-
type UpdateDependenciesVersionsScriptParams = {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
45
|
+
export type UpdateDependenciesVersionsScriptParams = {
|
|
46
|
+
organisationPackagePrefix: string;
|
|
47
|
+
blackListedPackages: string[];
|
|
48
|
+
};
|
|
42
49
|
|
|
43
|
-
type WorkspaceDependenciesMapElement = {
|
|
50
|
+
export type WorkspaceDependenciesMapElement = {
|
|
51
|
+
id: string;
|
|
52
|
+
dependencies: string[];
|
|
53
|
+
source: PackageContent;
|
|
54
|
+
};
|
|
44
55
|
|
|
45
|
-
type WorkspaceDependenciesMap = {
|
|
46
|
-
|
|
56
|
+
export type WorkspaceDependenciesMap = {
|
|
57
|
+
[id: string]: WorkspaceDependenciesMapElement;
|
|
47
58
|
};
|
|
48
59
|
|
|
49
60
|
export class UpdateDependenciesVersionsScript extends Script {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
61
|
+
private organisationPackagePrefix: string;
|
|
62
|
+
private blackListedPackages: string[];
|
|
63
|
+
private workspaceDependenciesMap: WorkspaceDependenciesMap =
|
|
64
|
+
this.getWorkspaceDependenciesMap();
|
|
65
|
+
|
|
66
|
+
constructor({
|
|
67
|
+
organisationPackagePrefix,
|
|
68
|
+
blackListedPackages,
|
|
69
|
+
}: UpdateDependenciesVersionsScriptParams) {
|
|
70
|
+
super({
|
|
71
|
+
logger: NestLogger.fromClass(UpdateDependenciesVersionsScript),
|
|
72
|
+
arguments: [
|
|
73
|
+
{
|
|
74
|
+
name: 'targetedPackage',
|
|
75
|
+
description: 'Target package',
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
this.organisationPackagePrefix = organisationPackagePrefix;
|
|
80
|
+
this.blackListedPackages = blackListedPackages;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async execute({
|
|
84
|
+
logger,
|
|
85
|
+
arguments: { targetedPackage },
|
|
86
|
+
}: ExecuteOptions): Promise<void> {
|
|
87
|
+
const workspaceDependenciesMapElements: WorkspaceDependenciesMapElement[] =
|
|
88
|
+
Object.values(this.workspaceDependenciesMap).filter(
|
|
89
|
+
({ id }: WorkspaceDependenciesMapElement): boolean =>
|
|
90
|
+
this.isTargetedPackage(targetedPackage)(id)
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
for (const {
|
|
94
|
+
id,
|
|
95
|
+
dependencies,
|
|
96
|
+
source,
|
|
97
|
+
} of workspaceDependenciesMapElements) {
|
|
98
|
+
logger.log(`package.json file updating for project "${id}"...`);
|
|
99
|
+
|
|
100
|
+
if (!PROJECT_ROOT_PATH) {
|
|
101
|
+
throw new UnknownEnvironmentVariableError('PWD');
|
|
102
|
+
}
|
|
103
|
+
const packagePath: string = join(
|
|
104
|
+
PROJECT_ROOT_PATH,
|
|
105
|
+
`dist/packages/${id}`
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
await mkdir(packagePath, { recursive: true });
|
|
109
|
+
const packageFilePath: string = join(PROJECT_ROOT_PATH, 'package.json');
|
|
110
|
+
|
|
111
|
+
const packageFileContent: PackageContent = { ...source };
|
|
112
|
+
|
|
113
|
+
if (dependencies.length && !packageFileContent.dependencies) {
|
|
114
|
+
packageFileContent.dependencies = {};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
dependencies.forEach((dependency: string): void => {
|
|
118
|
+
const versionTag = this.isAOrganisationPackage(dependency)
|
|
119
|
+
? `^${
|
|
120
|
+
this.workspaceDependenciesMap[
|
|
121
|
+
dependency.replace(this.organisationPackagePrefix, '')
|
|
122
|
+
].source.version
|
|
123
|
+
}`
|
|
124
|
+
: ROOT_PACKAGE_CONTENT.devDependencies[dependency];
|
|
125
|
+
packageFileContent.dependencies[dependency] = versionTag;
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
writeFileSync(
|
|
129
|
+
packageFilePath,
|
|
130
|
+
JSON.stringify(packageFileContent, null, 2) + '\n'
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
console.log(`package.json file updated for project "${id}"`);
|
|
69
134
|
}
|
|
70
135
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
arguments: {
|
|
74
|
-
targetedPackage
|
|
75
|
-
}
|
|
76
|
-
}: ExecuteOptions): Promise<void> {
|
|
77
|
-
const workspaceDependenciesMapElements: WorkspaceDependenciesMapElement[] = Object
|
|
78
|
-
.values(this.workspaceDependenciesMap)
|
|
79
|
-
.filter(({ id }: WorkspaceDependenciesMapElement): boolean => this.isTargetedPackage(targetedPackage)(id));
|
|
80
|
-
|
|
81
|
-
for (const { id, dependencies, source } of workspaceDependenciesMapElements) {
|
|
82
|
-
logger.log(`package.json file updating for project "${id}"...`);
|
|
83
|
-
|
|
84
|
-
if (!PROJECT_ROOT_PATH) {
|
|
85
|
-
throw new UnknownEnvironmentVariableError('PWD');
|
|
86
|
-
}
|
|
87
|
-
const packagePath: string = join(PROJECT_ROOT_PATH, `dist/packages/${id}`);
|
|
88
|
-
|
|
89
|
-
await mkdir(packagePath, { recursive: true });
|
|
90
|
-
const packageFilePath: string = join(PROJECT_ROOT_PATH, 'package.json');
|
|
91
|
-
|
|
92
|
-
const packageFileContent: PackageContent = { ...source };
|
|
93
|
-
|
|
94
|
-
if (dependencies.length && !packageFileContent.dependencies) {
|
|
95
|
-
packageFileContent.dependencies = {};
|
|
96
|
-
}
|
|
136
|
+
console.log('Package files updated.');
|
|
137
|
+
}
|
|
97
138
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
? `^${this.workspaceDependenciesMap[dependency.replace(this.organisationPackagePrefix, '')].source.version}`
|
|
101
|
-
: ROOT_PACKAGE_CONTENT.devDependencies[dependency];
|
|
102
|
-
packageFileContent.dependencies[dependency] = versionTag;
|
|
103
|
-
});
|
|
139
|
+
getWorkspaceDependenciesMap(): WorkspaceDependenciesMap {
|
|
140
|
+
const workspaceDependenciesMap: WorkspaceDependenciesMap = {};
|
|
104
141
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
console.log('Package files updated.')
|
|
142
|
+
const nxGraphResult = spawnSync(
|
|
143
|
+
'npx',
|
|
144
|
+
['nx', 'graph', '--file', NX_GRAPH_FILE_PATH],
|
|
145
|
+
{ stdio: 'inherit' }
|
|
146
|
+
);
|
|
147
|
+
if (nxGraphResult.status !== 0) {
|
|
148
|
+
throw new Error(`"nx graph" failed with status ${nxGraphResult.status}`);
|
|
114
149
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
for (const dependency of dependencies) {
|
|
139
|
-
workspaceDependenciesMap[packageId].dependencies.push(dependency);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
150
|
+
const nxGraph = require(NX_GRAPH_FILE_PATH);
|
|
151
|
+
|
|
152
|
+
const packageIds = Object.entries(nxGraph.graph.dependencies).map(
|
|
153
|
+
([packageId]) => packageId
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
for (const packageId of packageIds.filter(this.isNotBlackListed)) {
|
|
157
|
+
console.log(`Scanning dependencies for package ${packageId}...`);
|
|
158
|
+
const packageFileContent = getOrganisationPackageFile(packageId);
|
|
159
|
+
const dependencies = packageFileContent.dependencies
|
|
160
|
+
? Object.entries(packageFileContent.dependencies).map(
|
|
161
|
+
([dependency]) => dependency
|
|
162
|
+
)
|
|
163
|
+
: [];
|
|
164
|
+
|
|
165
|
+
workspaceDependenciesMap[packageId] = {
|
|
166
|
+
id: packageId,
|
|
167
|
+
dependencies: [],
|
|
168
|
+
source: packageFileContent,
|
|
169
|
+
};
|
|
170
|
+
if (packageFileContent.dependencies) {
|
|
171
|
+
for (const dependency of dependencies) {
|
|
172
|
+
workspaceDependenciesMap[packageId].dependencies.push(dependency);
|
|
142
173
|
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
143
176
|
|
|
144
|
-
|
|
177
|
+
console.log('Dependencies scan done.');
|
|
145
178
|
|
|
146
|
-
|
|
147
|
-
|
|
179
|
+
return workspaceDependenciesMap;
|
|
180
|
+
}
|
|
148
181
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
182
|
+
private isTargetedPackage =
|
|
183
|
+
(targetPackageId: MaybeUndefined<string>) => (packageId: string) => {
|
|
184
|
+
if (targetPackageId) {
|
|
185
|
+
return packageId === targetPackageId;
|
|
186
|
+
}
|
|
187
|
+
return true;
|
|
188
|
+
};
|
|
155
189
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
190
|
+
private isAOrganisationPackage(packageName: string): boolean {
|
|
191
|
+
return packageName.includes(this.organisationPackagePrefix);
|
|
192
|
+
}
|
|
159
193
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
194
|
+
private isBlackListed(packageId: string): boolean {
|
|
195
|
+
return this.blackListedPackages.includes(packageId);
|
|
196
|
+
}
|
|
163
197
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
198
|
+
private isNotBlackListed(packageId: string): boolean {
|
|
199
|
+
return !this.isBlackListed(packageId);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { FileSecretGetter, fileSecretGetter } from
|
|
2
|
-
|
|
1
|
+
import { FileSecretGetter, fileSecretGetter } from './file.secret.getter';
|
|
3
2
|
|
|
4
3
|
const DOCKER_SECRETS_DIRECTORY = '/run/secrets';
|
|
5
4
|
|
|
6
|
-
export const dockerSecretGetter: FileSecretGetter = fileSecretGetter
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
export const dockerSecretGetter: FileSecretGetter = fileSecretGetter(
|
|
6
|
+
DOCKER_SECRETS_DIRECTORY
|
|
7
|
+
)(
|
|
8
|
+
'Application is not running inside Docker container. Docker secrets will be unavailable.'
|
|
9
|
+
);
|
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
import { Dirent, existsSync, readdirSync, readFileSync } from
|
|
2
|
-
import { join } from
|
|
3
|
-
import { ILogger } from
|
|
4
|
-
|
|
5
|
-
import { SecretGetter } from "./types";
|
|
1
|
+
import { Dirent, existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { ILogger } from '@ask-ell/core';
|
|
6
4
|
|
|
5
|
+
import { SecretGetter } from './types';
|
|
7
6
|
|
|
8
7
|
export type FileSecretGetter = (logger: ILogger) => SecretGetter;
|
|
9
8
|
|
|
10
|
-
export const fileSecretGetter =
|
|
9
|
+
export const fileSecretGetter =
|
|
10
|
+
(rootDirectoryPath: string) =>
|
|
11
|
+
(warningMessage: string): FileSecretGetter =>
|
|
12
|
+
(logger: ILogger): SecretGetter =>
|
|
13
|
+
(): object => {
|
|
11
14
|
const isDirectoryExists: boolean = existsSync(rootDirectoryPath);
|
|
12
|
-
if(!isDirectoryExists){
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
if (!isDirectoryExists) {
|
|
16
|
+
logger.warn(warningMessage);
|
|
17
|
+
return {};
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
return readdirSync(rootDirectoryPath, { withFileTypes: true })
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
21
|
+
.filter((entry: Dirent<string>): boolean => entry.isFile())
|
|
22
|
+
.reduce((secrets: Record<string, string>, entry): object => {
|
|
23
|
+
const filePath: string = join(rootDirectoryPath, entry.name);
|
|
24
|
+
secrets[entry.name] = readFileSync(filePath, 'utf-8').trim();
|
|
25
|
+
return secrets;
|
|
26
|
+
}, {});
|
|
27
|
+
};
|
package/src/secrets/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './docker.secret.getter'
|
|
2
|
-
export * from './local.secret.getter'
|
|
1
|
+
export * from './docker.secret.getter';
|
|
2
|
+
export * from './local.secret.getter';
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { fileSecretGetter, FileSecretGetter } from
|
|
2
|
-
|
|
1
|
+
import { fileSecretGetter, FileSecretGetter } from './file.secret.getter';
|
|
3
2
|
|
|
4
3
|
const LOCAL_SECRETS_DIRECTORY = '.secrets';
|
|
5
4
|
|
|
6
|
-
export const localSecretGetter: FileSecretGetter = fileSecretGetter
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
export const localSecretGetter: FileSecretGetter = fileSecretGetter(
|
|
6
|
+
LOCAL_SECRETS_DIRECTORY
|
|
7
|
+
)(
|
|
8
|
+
'Secrets directory not exists on this project. Local secrets will be unavailable.'
|
|
9
|
+
);
|
package/src/tmp.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ILogger } from '@ask-ell/core';
|
|
2
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
|
|
5
|
+
export const TMP_FOLDER_PATH: string = join(process.cwd(), 'tmp');
|
|
6
|
+
|
|
7
|
+
export const createTmpFolder = (logger: ILogger): void => {
|
|
8
|
+
const isTmpFolderExists: boolean = existsSync(TMP_FOLDER_PATH);
|
|
9
|
+
if (isTmpFolderExists) {
|
|
10
|
+
logger.info(`"${TMP_FOLDER_PATH}" folder already exists.`);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
mkdirSync(TMP_FOLDER_PATH);
|
|
14
|
+
logger.info(`"${TMP_FOLDER_PATH}" folder created.`);
|
|
15
|
+
};
|
|
@@ -1,36 +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
|
-
|
|
10
|
-
export class AddOnWrapper<T> implements IAddOn<T> {
|
|
11
|
-
private implementations: IAddOn<T>[] = [
|
|
12
|
-
new SecurityAddOn()
|
|
13
|
-
];
|
|
14
|
-
|
|
15
|
-
constructor(
|
|
16
|
-
private params: AddOnWrapperParams
|
|
17
|
-
) {
|
|
18
|
-
this.appendImplementations();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
apply(application: INestApplication<T>): void {
|
|
22
|
-
this.implementations.forEach((addOn: IAddOn<T>): void => {
|
|
23
|
-
addOn.apply(application);
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
private appendImplementations(): void {
|
|
28
|
-
const { sentry, swagger } = this.params;
|
|
29
|
-
if(swagger){
|
|
30
|
-
this.implementations.push(new SwaggerAddon(swagger));
|
|
31
|
-
}
|
|
32
|
-
if(sentry){
|
|
33
|
-
this.implementations.push(new SentryAddon(sentry));
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|