n8n/packages/nodes-base/nodes/Taiga/GenericFunctions.ts
Omar Ajoue d3fecb9f6d
🎨 Centralize error throwing for encryption keys and credentials (#3105)
* Centralized error throwing for encryption key

* Unifying the error message used by cli and core packages

* Improvements to error messages to make it more DRY

* Removed unnecessary throw

* Throwing error when credential does not exist to simplify node behavior (#3112)

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
2022-04-15 08:00:47 +02:00

159 lines
4.1 KiB
TypeScript

import {
OptionsWithUri,
} from 'request';
import {
IExecuteFunctions,
IExecuteSingleFunctions,
IHookFunctions,
ILoadOptionsFunctions,
IWebhookFunctions,
} from 'n8n-core';
import {
ICredentialDataDecryptedObject,
IDataObject,
NodeApiError,
NodeOperationError,
} from 'n8n-workflow';
import {
createHash,
} from 'crypto';
export async function getAuthorization(
this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IWebhookFunctions,
credentials?: ICredentialDataDecryptedObject,
): Promise<string> {
if (credentials === undefined) {
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
}
const { password, username } = credentials;
const options: OptionsWithUri = {
headers: { 'Content-Type': 'application/json' },
method: 'POST',
body: {
type: 'normal',
password,
username,
},
uri: (credentials.url) ? `${credentials.url}/api/v1/auth` : 'https://api.taiga.io/api/v1/auth',
json: true,
};
try {
const response = await this.helpers.request!(options);
return response.auth_token;
} catch (error) {
throw new NodeApiError(this.getNode(), error);
}
}
export async function taigaApiRequest(
this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IWebhookFunctions,
method: string,
resource: string,
body = {},
query = {},
uri?: string | undefined,
option = {},
): Promise<any> { // tslint:disable-line:no-any
const credentials = await this.getCredentials('taigaApi');
const authToken = await getAuthorization.call(this, credentials);
const options: OptionsWithUri = {
headers: {
'Content-Type': 'application/json',
},
auth: {
bearer: authToken,
},
qs: query,
method,
body,
uri: uri || (credentials.url) ? `${credentials.url}/api/v1${resource}` : `https://api.taiga.io/api/v1${resource}`,
json: true,
};
if (Object.keys(option).length !== 0) {
Object.assign(options, option);
}
try {
return await this.helpers.request!(options);
} catch (error) {
throw new NodeApiError(this.getNode(), error);
}
}
export async function taigaApiRequestAllItems(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
const returnData: IDataObject[] = [];
let responseData;
let uri: string | undefined;
do {
responseData = await taigaApiRequest.call(this, method, resource, body, query, uri, { resolveWithFullResponse: true });
returnData.push.apply(returnData, responseData.body);
uri = responseData.headers['x-pagination-next'];
if (query.limit && returnData.length >= query.limit) {
return returnData;
}
} while (
responseData.headers['x-pagination-next'] !== undefined &&
responseData.headers['x-pagination-next'] !== ''
);
return returnData;
}
export function getAutomaticSecret(credentials: ICredentialDataDecryptedObject) {
const data = `${credentials.username},${credentials.password}`;
return createHash('md5').update(data).digest('hex');
}
export async function handleListing(
this: IExecuteFunctions,
method: string,
endpoint: string,
body: IDataObject = {},
qs: IDataObject = {},
i: number,
) {
let responseData;
qs.project = this.getNodeParameter('projectId', i) as number;
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
if (returnAll) {
return await taigaApiRequestAllItems.call(this, method, endpoint, body, qs);
} else {
qs.limit = this.getNodeParameter('limit', i) as number;
responseData = await taigaApiRequestAllItems.call(this, method, endpoint, body, qs);
return responseData.splice(0, qs.limit);
}
}
export const toOptions = (items: LoadedResource[]) =>
items.map(({ name, id }) => ({ name, value: id }));
export function throwOnEmptyUpdate(
this: IExecuteFunctions,
resource: Resource,
) {
throw new NodeOperationError(
this.getNode(),
`Please enter at least one field to update for the ${resource}.`,
);
}
export async function getVersionForUpdate(
this: IExecuteFunctions,
endpoint: string,
) {
return await taigaApiRequest.call(this, 'GET', endpoint).then(response => response.version);
}