Replace DB object with typed class field

This commit is contained in:
Iván Ovejero 2021-04-16 18:15:14 +02:00
parent ea93518636
commit efd34a6768

View file

@ -107,13 +107,15 @@ import * as querystring from 'querystring';
import * as Queue from '../src/Queue'; import * as Queue from '../src/Queue';
import { OptionsWithUrl } from 'request-promise-native'; import { OptionsWithUrl } from 'request-promise-native';
import { Registry } from 'prom-client'; import { Registry } from 'prom-client';
import { ITagDb, IWorkflowRequest } from './Interfaces'; import { ExactDatabaseCollections, ITagDb, IWorkflowRequest } from './Interfaces';
import * as TagHelpers from './TagHelpers'; import * as TagHelpers from './TagHelpers';
import { hasNonNullableContents } from './Db';
class App { class App {
app: express.Application; app: express.Application;
dbCollections: ExactDatabaseCollections;
activeWorkflowRunner: ActiveWorkflowRunner.ActiveWorkflowRunner; activeWorkflowRunner: ActiveWorkflowRunner.ActiveWorkflowRunner;
testWebhooks: TestWebhooks.TestWebhooks; testWebhooks: TestWebhooks.TestWebhooks;
endpointWebhook: string; endpointWebhook: string;
@ -429,12 +431,13 @@ class App {
this.app.use((req: express.Request, res: express.Response, next: express.NextFunction) => { this.app.use((req: express.Request, res: express.Response, next: express.NextFunction) => {
if (Db.collections.Workflow === null) { if (hasNonNullableContents(Db.collections)) {
this.dbCollections = Db.collections;
next();
} else {
const error = new ResponseHelper.ResponseError('Database is not ready!', undefined, 503); const error = new ResponseHelper.ResponseError('Database is not ready!', undefined, 503);
return ResponseHelper.sendErrorResponse(res, error); return ResponseHelper.sendErrorResponse(res, error);
} }
next();
}); });
@ -498,7 +501,7 @@ class App {
await this.externalHooks.run('workflow.create', [newWorkflowData]); await this.externalHooks.run('workflow.create', [newWorkflowData]);
// Save the workflow in DB // Save the workflow in DB
const result = await Db.collections.Workflow!.save(newWorkflowData); const result = await this.dbCollections.Workflow.save(newWorkflowData);
const { tags } = req.body; const { tags } = req.body;
@ -509,7 +512,7 @@ class App {
await TagHelpers.validateTags(tagIds); await TagHelpers.validateTags(tagIds);
await TagHelpers.createRelations(workflowId, tagIds); await TagHelpers.createRelations(workflowId, tagIds);
const found = await Db.collections.Tag!.find({ const found = await this.dbCollections.Tag.find({
select: ['id', 'name'], select: ['id', 'name'],
where: { id: In(tagIds) }, where: { id: In(tagIds) },
}); });
@ -563,7 +566,7 @@ class App {
findQuery.where = JSON.parse(req.query.filter as string); findQuery.where = JSON.parse(req.query.filter as string);
} }
const results = await Db.collections.Workflow!.find(findQuery); const results = await this.dbCollections.Workflow.find(findQuery);
results.forEach(workflow => { results.forEach(workflow => {
if (workflow.tags) { if (workflow.tags) {
workflow.tags = TagHelpers.getTagsResponse(workflow.tags); workflow.tags = TagHelpers.getTagsResponse(workflow.tags);
@ -580,7 +583,7 @@ class App {
// Returns a specific workflow // Returns a specific workflow
this.app.get(`/${this.restEndpoint}/workflows/:id`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<IWorkflowResponse | undefined> => { this.app.get(`/${this.restEndpoint}/workflows/:id`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<IWorkflowResponse | undefined> => {
const result = await Db.collections.Workflow!.findOne(req.params.id); const result = await this.dbCollections.Workflow.findOne(req.params.id);
if (result === undefined) { if (result === undefined) {
return undefined; return undefined;
@ -645,12 +648,12 @@ class App {
newWorkflowData.updatedAt = this.getCurrentDate(); newWorkflowData.updatedAt = this.getCurrentDate();
await Db.collections.Workflow!.update(id, newWorkflowData); await this.dbCollections.Workflow.update(id, newWorkflowData);
await this.externalHooks.run('workflow.afterUpdate', [newWorkflowData]); await this.externalHooks.run('workflow.afterUpdate', [newWorkflowData]);
// We sadly get nothing back from "update". Neither if it updated a record // We sadly get nothing back from "update". Neither if it updated a record
// nor the new value. So query now the hopefully updated entry. // nor the new value. So query now the hopefully updated entry.
const responseData = await Db.collections.Workflow!.findOne(id); const responseData = await this.dbCollections.Workflow.findOne(id);
if (responseData === undefined) { if (responseData === undefined) {
throw new ResponseHelper.ResponseError(`Workflow with id "${id}" could not be found to be updated.`, undefined, 400); throw new ResponseHelper.ResponseError(`Workflow with id "${id}" could not be found to be updated.`, undefined, 400);
@ -665,7 +668,7 @@ class App {
} catch (error) { } catch (error) {
// If workflow could not be activated set it again to inactive // If workflow could not be activated set it again to inactive
newWorkflowData.active = false; newWorkflowData.active = false;
await Db.collections.Workflow!.update(id, newWorkflowData); await this.dbCollections.Workflow.update(id, newWorkflowData);
// Also set it in the returned data // Also set it in the returned data
responseData.active = false; responseData.active = false;
@ -679,7 +682,7 @@ class App {
await TagHelpers.removeRelations(req.params.id); await TagHelpers.removeRelations(req.params.id);
await TagHelpers.createRelations(req.params.id, tagIds); await TagHelpers.createRelations(req.params.id, tagIds);
const found = await Db.collections.Tag!.find({ const found = await this.dbCollections.Tag.find({
select: ['id', 'name'], select: ['id', 'name'],
where: { id: In(tagIds) }, where: { id: In(tagIds) },
}); });
@ -706,7 +709,7 @@ class App {
await this.activeWorkflowRunner.remove(id); await this.activeWorkflowRunner.remove(id);
} }
await Db.collections.Workflow!.delete(id); await this.dbCollections.Workflow.delete(id);
await this.externalHooks.run('workflow.afterDelete', [id]); await this.externalHooks.run('workflow.afterDelete', [id]);
return true; return true;
@ -766,7 +769,7 @@ class App {
return foundTags.map(({ id, name, usageCount }) => ({ id: id.toString(), name, usageCount })); return foundTags.map(({ id, name, usageCount }) => ({ id: id.toString(), name, usageCount }));
} }
const foundTags = await Db.collections.Tag!.find({ select: ['id', 'name'] }); const foundTags = await this.dbCollections.Tag.find({ select: ['id', 'name'] });
return foundTags.map(({ id, name }) => ({ id: id.toString(), name })); return foundTags.map(({ id, name }) => ({ id: id.toString(), name }));
})); }));
@ -781,7 +784,7 @@ class App {
updatedAt: this.getCurrentDate(), updatedAt: this.getCurrentDate(),
}; };
const { id } = await Db.collections.Tag!.save(newTag); const { id } = await this.dbCollections.Tag.save(newTag);
return { id: id.toString(), name }; return { id: id.toString(), name };
})); }));
@ -790,7 +793,7 @@ class App {
this.app.delete(`/${this.restEndpoint}/tags/:id`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<boolean> => { this.app.delete(`/${this.restEndpoint}/tags/:id`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<boolean> => {
const { id } = req.params; const { id } = req.params;
await TagHelpers.exists(id); await TagHelpers.exists(id);
await Db.collections.Tag!.delete({ id }); await this.dbCollections.Tag.delete({ id });
return true; return true;
})); }));
@ -807,7 +810,7 @@ class App {
updatedAt: this.getCurrentDate(), updatedAt: this.getCurrentDate(),
}; };
await Db.collections.Tag!.update(id, updatedTag); await this.dbCollections.Tag.update(id, updatedTag);
return { id, name }; return { id, name };
})); }));
@ -941,7 +944,7 @@ class App {
await this.externalHooks.run('credentials.delete', [id]); await this.externalHooks.run('credentials.delete', [id]);
await Db.collections.Credentials!.delete({ id }); await this.dbCollections.Credentials.delete({ id });
return true; return true;
})); }));
@ -976,7 +979,7 @@ class App {
}, },
} as FindOneOptions; } as FindOneOptions;
const checkResult = await Db.collections.Credentials!.findOne(findQuery); const checkResult = await this.dbCollections.Credentials.findOne(findQuery);
if (checkResult !== undefined) { if (checkResult !== undefined) {
throw new ResponseHelper.ResponseError(`Credentials with the same type and name exist already.`, undefined, 400); throw new ResponseHelper.ResponseError(`Credentials with the same type and name exist already.`, undefined, 400);
} }
@ -995,7 +998,7 @@ class App {
// TODO: also add user automatically depending on who is logged in, if anybody is logged in // TODO: also add user automatically depending on who is logged in, if anybody is logged in
// Save the credentials in DB // Save the credentials in DB
const result = await Db.collections.Credentials!.save(newCredentialsData); const result = await this.dbCollections.Credentials.save(newCredentialsData);
result.data = incomingData.data; result.data = incomingData.data;
// Convert to response format in which the id is a string // Convert to response format in which the id is a string
@ -1030,7 +1033,7 @@ class App {
}, },
} as FindOneOptions; } as FindOneOptions;
const checkResult = await Db.collections.Credentials!.findOne(findQuery); const checkResult = await this.dbCollections.Credentials.findOne(findQuery);
if (checkResult !== undefined) { if (checkResult !== undefined) {
throw new ResponseHelper.ResponseError(`Credentials with the same type and name exist already.`, undefined, 400); throw new ResponseHelper.ResponseError(`Credentials with the same type and name exist already.`, undefined, 400);
} }
@ -1041,7 +1044,7 @@ class App {
} }
// Load the currently saved credentials to be able to persist some of the data if // Load the currently saved credentials to be able to persist some of the data if
const result = await Db.collections.Credentials!.findOne(id); const result = await this.dbCollections.Credentials.findOne(id);
if (result === undefined) { if (result === undefined) {
throw new ResponseHelper.ResponseError(`Credentials with the id "${id}" do not exist.`, undefined, 400); throw new ResponseHelper.ResponseError(`Credentials with the id "${id}" do not exist.`, undefined, 400);
} }
@ -1066,11 +1069,11 @@ class App {
await this.externalHooks.run('credentials.update', [newCredentialsData]); await this.externalHooks.run('credentials.update', [newCredentialsData]);
// Update the credentials in DB // Update the credentials in DB
await Db.collections.Credentials!.update(id, newCredentialsData); await this.dbCollections.Credentials.update(id, newCredentialsData);
// We sadly get nothing back from "update". Neither if it updated a record // We sadly get nothing back from "update". Neither if it updated a record
// nor the new value. So query now the hopefully updated entry. // nor the new value. So query now the hopefully updated entry.
const responseData = await Db.collections.Credentials!.findOne(id); const responseData = await this.dbCollections.Credentials.findOne(id);
if (responseData === undefined) { if (responseData === undefined) {
throw new ResponseHelper.ResponseError(`Credentials with id "${id}" could not be found to be updated.`, undefined, 400); throw new ResponseHelper.ResponseError(`Credentials with id "${id}" could not be found to be updated.`, undefined, 400);
@ -1097,7 +1100,7 @@ class App {
findQuery.select = ['id', 'name', 'type', 'nodesAccess', 'createdAt', 'updatedAt']; findQuery.select = ['id', 'name', 'type', 'nodesAccess', 'createdAt', 'updatedAt'];
} }
const result = await Db.collections.Credentials!.findOne(req.params.id); const result = await this.dbCollections.Credentials.findOne(req.params.id);
if (result === undefined) { if (result === undefined) {
return result; return result;
@ -1135,7 +1138,7 @@ class App {
findQuery.select = ['id', 'name', 'type', 'nodesAccess', 'createdAt', 'updatedAt']; findQuery.select = ['id', 'name', 'type', 'nodesAccess', 'createdAt', 'updatedAt'];
const results = await Db.collections.Credentials!.find(findQuery) as unknown as ICredentialsResponse[]; const results = await this.dbCollections.Credentials.find(findQuery) as unknown as ICredentialsResponse[];
let encryptionKey = undefined; let encryptionKey = undefined;
@ -1187,7 +1190,7 @@ class App {
return ''; return '';
} }
const result = await Db.collections.Credentials!.findOne(req.query.id as string); const result = await this.dbCollections.Credentials.findOne(req.query.id as string);
if (result === undefined) { if (result === undefined) {
res.status(404).send('The credential is not known.'); res.status(404).send('The credential is not known.');
return ''; return '';
@ -1264,7 +1267,7 @@ class App {
newCredentialsData.updatedAt = this.getCurrentDate(); newCredentialsData.updatedAt = this.getCurrentDate();
// Update the credentials in DB // Update the credentials in DB
await Db.collections.Credentials!.update(req.query.id as string, newCredentialsData); await this.dbCollections.Credentials.update(req.query.id as string, newCredentialsData);
return returnUri; return returnUri;
})); }));
@ -1278,7 +1281,7 @@ class App {
return ResponseHelper.sendErrorResponse(res, errorResponse); return ResponseHelper.sendErrorResponse(res, errorResponse);
} }
const result = await Db.collections.Credentials!.findOne(cid as any); // tslint:disable-line:no-any const result = await this.dbCollections.Credentials.findOne(cid as any); // tslint:disable-line:no-any
if (result === undefined) { if (result === undefined) {
const errorResponse = new ResponseHelper.ResponseError('The credential is not known.', undefined, 404); const errorResponse = new ResponseHelper.ResponseError('The credential is not known.', undefined, 404);
return ResponseHelper.sendErrorResponse(res, errorResponse); return ResponseHelper.sendErrorResponse(res, errorResponse);
@ -1332,7 +1335,7 @@ class App {
// Add special database related data // Add special database related data
newCredentialsData.updatedAt = this.getCurrentDate(); newCredentialsData.updatedAt = this.getCurrentDate();
// Save the credentials in DB // Save the credentials in DB
await Db.collections.Credentials!.update(cid as any, newCredentialsData); // tslint:disable-line:no-any await this.dbCollections.Credentials.update(cid as any, newCredentialsData); // tslint:disable-line:no-any
res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html')); res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html'));
}); });
@ -1350,7 +1353,7 @@ class App {
return ''; return '';
} }
const result = await Db.collections.Credentials!.findOne(req.query.id as string); const result = await this.dbCollections.Credentials.findOne(req.query.id as string);
if (result === undefined) { if (result === undefined) {
res.status(404).send('The credential is not known.'); res.status(404).send('The credential is not known.');
return ''; return '';
@ -1408,7 +1411,7 @@ class App {
newCredentialsData.updatedAt = this.getCurrentDate(); newCredentialsData.updatedAt = this.getCurrentDate();
// Update the credentials in DB // Update the credentials in DB
await Db.collections.Credentials!.update(req.query.id as string, newCredentialsData); await this.dbCollections.Credentials.update(req.query.id as string, newCredentialsData);
const authQueryParameters = _.get(oauthCredentials, 'authQueryParameters', '') as string; const authQueryParameters = _.get(oauthCredentials, 'authQueryParameters', '') as string;
let returnUri = oAuthObj.code.getUri(); let returnUri = oAuthObj.code.getUri();
@ -1450,7 +1453,7 @@ class App {
return ResponseHelper.sendErrorResponse(res, errorResponse); return ResponseHelper.sendErrorResponse(res, errorResponse);
} }
const result = await Db.collections.Credentials!.findOne(state.cid); const result = await this.dbCollections.Credentials.findOne(state.cid);
if (result === undefined) { if (result === undefined) {
const errorResponse = new ResponseHelper.ResponseError('The credential is not known.', undefined, 404); const errorResponse = new ResponseHelper.ResponseError('The credential is not known.', undefined, 404);
return ResponseHelper.sendErrorResponse(res, errorResponse); return ResponseHelper.sendErrorResponse(res, errorResponse);
@ -1535,7 +1538,7 @@ class App {
// Add special database related data // Add special database related data
newCredentialsData.updatedAt = this.getCurrentDate(); newCredentialsData.updatedAt = this.getCurrentDate();
// Save the credentials in DB // Save the credentials in DB
await Db.collections.Credentials!.update(state.cid, newCredentialsData); await this.dbCollections.Credentials.update(state.cid, newCredentialsData);
res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html')); res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html'));
}); });
@ -1602,7 +1605,7 @@ class App {
const resultsPromise = resultsQuery.getMany(); const resultsPromise = resultsQuery.getMany();
const countPromise = Db.collections.Execution!.count(countFilter); const countPromise = this.dbCollections.Execution.count(countFilter);
const results: IExecutionFlattedDb[] = await resultsPromise; const results: IExecutionFlattedDb[] = await resultsPromise;
const count = await countPromise; const count = await countPromise;
@ -1632,7 +1635,7 @@ class App {
// Returns a specific execution // Returns a specific execution
this.app.get(`/${this.restEndpoint}/executions/:id`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<IExecutionResponse | IExecutionFlattedResponse | undefined> => { this.app.get(`/${this.restEndpoint}/executions/:id`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<IExecutionResponse | IExecutionFlattedResponse | undefined> => {
const result = await Db.collections.Execution!.findOne(req.params.id); const result = await this.dbCollections.Execution.findOne(req.params.id);
if (result === undefined) { if (result === undefined) {
return undefined; return undefined;
@ -1652,7 +1655,7 @@ class App {
// Retries a failed execution // Retries a failed execution
this.app.post(`/${this.restEndpoint}/executions/:id/retry`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<boolean> => { this.app.post(`/${this.restEndpoint}/executions/:id/retry`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<boolean> => {
// Get the data to execute // Get the data to execute
const fullExecutionDataFlatted = await Db.collections.Execution!.findOne(req.params.id); const fullExecutionDataFlatted = await this.dbCollections.Execution.findOne(req.params.id);
if (fullExecutionDataFlatted === undefined) { if (fullExecutionDataFlatted === undefined) {
throw new ResponseHelper.ResponseError(`The execution with the id "${req.params.id}" does not exist.`, 404, 404); throw new ResponseHelper.ResponseError(`The execution with the id "${req.params.id}" does not exist.`, 404, 404);
@ -1697,7 +1700,7 @@ class App {
// Loads the currently saved workflow to execute instead of the // Loads the currently saved workflow to execute instead of the
// one saved at the time of the execution. // one saved at the time of the execution.
const workflowId = fullExecutionData.workflowData.id; const workflowId = fullExecutionData.workflowData.id;
const workflowData = await Db.collections.Workflow!.findOne(workflowId) as IWorkflowBase; const workflowData = await this.dbCollections.Workflow.findOne(workflowId) as IWorkflowBase;
if (workflowData === undefined) { if (workflowData === undefined) {
throw new Error(`The workflow with the ID "${workflowId}" could not be found and so the data not be loaded for the retry.`); throw new Error(`The workflow with the ID "${workflowId}" could not be found and so the data not be loaded for the retry.`);
@ -1747,10 +1750,10 @@ class App {
Object.assign(filters, deleteData.filters); Object.assign(filters, deleteData.filters);
} }
await Db.collections.Execution!.delete(filters); await this.dbCollections.Execution.delete(filters);
} else if (deleteData.ids !== undefined) { } else if (deleteData.ids !== undefined) {
// Deletes all executions with the given ids // Deletes all executions with the given ids
await Db.collections.Execution!.delete(deleteData.ids); await this.dbCollections.Execution.delete(deleteData.ids);
} else { } else {
throw new Error('Required body-data "ids" or "deleteBefore" is missing!'); throw new Error('Required body-data "ids" or "deleteBefore" is missing!');
} }
@ -1778,7 +1781,7 @@ class App {
return []; return [];
} }
const resultsQuery = await Db.collections.Execution! const resultsQuery = await this.dbCollections.Execution
.createQueryBuilder("execution") .createQueryBuilder("execution")
.select([ .select([
'execution.id', 'execution.id',