n8n/packages/nodes-base/nodes/MongoDb/mongo.node.utils.ts
Michael Kret b5511e5ac7
feature: add MongoDB credential testing and two operations: findOneAndReplace and findOneAndUpdate (#3901)
* feature: add MongoDB credential testing and two operations: findOneAndReplace and findOneAndUpdate
Co-authored-by: Anas Naim <anas.naim@hotmail.com>
2022-09-01 10:23:15 +02:00

134 lines
3.5 KiB
TypeScript

import { IExecuteFunctions } from 'n8n-core';
import {
ICredentialDataDecryptedObject,
IDataObject,
INodeExecutionData,
NodeOperationError,
} from 'n8n-workflow';
import {
IMongoCredentials,
IMongoCredentialsType,
IMongoParametricCredentials,
} from './mongo.node.types';
import { get, set } from 'lodash';
/**
* Standard way of building the MongoDB connection string, unless overridden with a provided string
*
* @param {ICredentialDataDecryptedObject} credentials MongoDB credentials to use, unless conn string is overridden
*/
export function buildParameterizedConnString(credentials: IMongoParametricCredentials): string {
if (credentials.port) {
return `mongodb://${credentials.user}:${credentials.password}@${credentials.host}:${credentials.port}`;
} else {
return `mongodb+srv://${credentials.user}:${credentials.password}@${credentials.host}`;
}
}
/**
* Build mongoDb connection string and resolve database name.
* If a connection string override value is provided, that will be used in place of individual args
*
* @param {IExecuteFunctions} self
* @param {ICredentialDataDecryptedObject} credentials raw/input MongoDB credentials to use
*/
export function buildMongoConnectionParams(
self: IExecuteFunctions,
credentials: IMongoCredentialsType,
): IMongoCredentials {
const sanitizedDbName =
credentials.database && credentials.database.trim().length > 0
? credentials.database.trim()
: '';
if (credentials.configurationType === 'connectionString') {
if (credentials.connectionString && credentials.connectionString.trim().length > 0) {
return {
connectionString: credentials.connectionString.trim(),
database: sanitizedDbName,
};
} else {
throw new NodeOperationError(
self.getNode(),
'Cannot override credentials: valid MongoDB connection string not provided ',
);
}
} else {
return {
connectionString: buildParameterizedConnString(credentials),
database: sanitizedDbName,
};
}
}
/**
* Verify credentials. If ok, build mongoDb connection string and resolve database name.
*
* @param {IExecuteFunctions} self
* @param {ICredentialDataDecryptedObject} credentials raw/input MongoDB credentials to use
*/
export function validateAndResolveMongoCredentials(
self: IExecuteFunctions,
credentials?: ICredentialDataDecryptedObject,
): IMongoCredentials {
if (credentials === undefined) {
throw new NodeOperationError(self.getNode(), 'No credentials got returned!');
} else {
return buildMongoConnectionParams(self, credentials as unknown as IMongoCredentialsType);
}
}
export function prepareItems(
items: INodeExecutionData[],
fields: string[],
updateKey = '',
useDotNotation = false,
dateFields: string[] = [],
) {
let data = items;
if (updateKey) {
if (!fields.includes(updateKey)) {
fields.push(updateKey);
}
data = items.filter((item) => item.json[updateKey] !== undefined);
}
const preperedItems = data.map(({ json }) => {
const updateItem: IDataObject = {};
for (const field of fields) {
let fieldData;
if (useDotNotation) {
fieldData = get(json, field, null);
} else {
fieldData = json[field] !== undefined ? json[field] : null;
}
if (fieldData && dateFields.includes(field)) {
fieldData = new Date(fieldData as string);
}
if (useDotNotation) {
set(updateItem, field, fieldData);
} else {
updateItem[field] = fieldData;
}
}
return updateItem;
});
return preperedItems;
}
export function prepareFields(fields: string) {
return fields
.split(',')
.map((field) => field.trim())
.filter((field) => !!field);
}