refactor(core): Allow custom types on getCredentials (no-changelog) (#10567)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2024-08-27 15:23:58 +02:00 committed by GitHub
parent 52c574d83f
commit be52176585
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
65 changed files with 132 additions and 123 deletions

View file

@ -94,11 +94,11 @@ export class EmbeddingsAzureOpenAi implements INodeType {
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.verbose('Supply data for embeddings');
const credentials = (await this.getCredentials('azureOpenAiApi')) as {
const credentials = await this.getCredentials<{
apiKey: string;
resourceName: string;
apiVersion: string;
};
}>('azureOpenAiApi');
const modelName = this.getNodeParameter('model', itemIndex) as string;
const options = this.getNodeParameter('options', itemIndex, {}) as {

View file

@ -102,7 +102,7 @@ export class EmbeddingsCohere implements INodeType {
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.verbose('Supply data for embeddings Cohere');
const modelName = this.getNodeParameter('modelName', itemIndex, 'embed-english-v2.0') as string;
const credentials = (await this.getCredentials('cohereApi')) as { apiKey: string };
const credentials = await this.getCredentials<{ apiKey: string }>('cohereApi');
const embeddings = new CohereEmbeddings({
apiKey: credentials.apiKey,
model: modelName,

View file

@ -133,11 +133,11 @@ export class LmChatAzureOpenAi implements INodeType {
};
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = (await this.getCredentials('azureOpenAiApi')) as {
const credentials = await this.getCredentials<{
apiKey: string;
resourceName: string;
apiVersion: string;
};
}>('azureOpenAiApi');
const modelName = this.getNodeParameter('model', itemIndex) as string;
const options = this.getNodeParameter('options', itemIndex, {}) as {

View file

@ -74,7 +74,7 @@ export class MemoryPostgresChat implements INodeType {
};
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;
const credentials = await this.getCredentials<PostgresNodeCredentials>('postgres');
const tableName = this.getNodeParameter('tableName', itemIndex, 'n8n_chat_histories') as string;
const sessionId = getSessionId(this, itemIndex);

View file

@ -104,11 +104,11 @@ export class MemoryZep implements INodeType {
};
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = (await this.getCredentials('zepApi')) as {
const credentials = await this.getCredentials<{
apiKey?: string;
apiUrl?: string;
cloud?: boolean;
};
}>('zepApi');
const nodeVersion = this.getNode().typeVersion;

View file

@ -14,7 +14,7 @@ export async function validateAuth(context: IWebhookFunctions) {
// Basic authorization is needed to call webhook
let expectedAuth: ICredentialDataDecryptedObject | undefined;
try {
expectedAuth = await context.getCredentials('httpBasicAuth');
expectedAuth = await context.getCredentials<ICredentialDataDecryptedObject>('httpBasicAuth');
} catch {}
if (expectedAuth === undefined || !expectedAuth.user || !expectedAuth.password) {

View file

@ -79,10 +79,10 @@ export const VectorStoreZep = createVectorStoreNode({
embeddingDimensions?: number;
}) || {};
const credentials = (await context.getCredentials('zepApi')) as {
const credentials = await context.getCredentials<{
apiKey?: string;
apiUrl: string;
};
}>('zepApi');
const zepConfig: IZepConfig = {
apiUrl: credentials.apiUrl,
@ -102,10 +102,10 @@ export const VectorStoreZep = createVectorStoreNode({
embeddingDimensions?: number;
}) || {};
const credentials = (await context.getCredentials('zepApi')) as {
const credentials = await context.getCredentials<{
apiKey?: string;
apiUrl: string;
};
}>('zepApi');
const zepConfig = {
apiUrl: credentials.apiUrl,

View file

@ -110,10 +110,10 @@ export class VectorStoreZepInsert implements INodeType {
embeddingDimensions?: number;
}) || {};
const credentials = (await this.getCredentials('zepApi')) as {
const credentials = await this.getCredentials<{
apiKey?: string;
apiUrl: string;
};
}>('zepApi');
const documentInput = (await this.getInputConnectionData(NodeConnectionType.AiDocument, 0)) as
| N8nJsonLoader

View file

@ -93,10 +93,10 @@ export class VectorStoreZepLoad implements INodeType {
embeddingDimensions?: number;
}) || {};
const credentials = (await this.getCredentials('zepApi')) as {
const credentials = await this.getCredentials<{
apiKey?: string;
apiUrl: string;
};
}>('zepApi');
const embeddings = (await this.getInputConnectionData(
NodeConnectionType.AiEmbedding,
0,

View file

@ -3,20 +3,22 @@ import type { ICredentialDataDecryptedObject, ICredentialsEncrypted } from 'n8n-
import { ApplicationError, ICredentials, jsonParse } from 'n8n-workflow';
import { Cipher } from './Cipher';
export class Credentials extends ICredentials {
export class Credentials<
T extends object = ICredentialDataDecryptedObject,
> extends ICredentials<T> {
private readonly cipher = Container.get(Cipher);
/**
* Sets new credential object
*/
setData(data: ICredentialDataDecryptedObject): void {
setData(data: T): void {
this.data = this.cipher.encrypt(data);
}
/**
* Returns the decrypted credential object
*/
getData(): ICredentialDataDecryptedObject {
getData(): T {
if (this.data === undefined) {
throw new ApplicationError('No data is set so nothing can be returned.');
}

View file

@ -1656,7 +1656,8 @@ export async function httpRequestWithAuthentication(
if (additionalCredentialOptions?.credentialsDecrypted) {
credentialsDecrypted = additionalCredentialOptions.credentialsDecrypted.data;
} else {
credentialsDecrypted = await this.getCredentials(credentialsType);
credentialsDecrypted =
await this.getCredentials<ICredentialDataDecryptedObject>(credentialsType);
}
if (credentialsDecrypted === undefined) {
@ -1853,7 +1854,10 @@ export async function requestWithAuthentication(
if (additionalCredentialOptions?.credentialsDecrypted) {
credentialsDecrypted = additionalCredentialOptions.credentialsDecrypted.data;
} else {
credentialsDecrypted = await this.getCredentials(credentialsType, itemIndex);
credentialsDecrypted = await this.getCredentials<ICredentialDataDecryptedObject>(
credentialsType,
itemIndex,
);
}
if (credentialsDecrypted === undefined) {
@ -1988,7 +1992,7 @@ export function getAdditionalKeys(
* @param {INode} node Node which request the data
* @param {string} type The credential type to return
*/
export async function getCredentials(
export async function getCredentials<T extends object = ICredentialDataDecryptedObject>(
workflow: Workflow,
node: INode,
type: string,
@ -1999,7 +2003,7 @@ export async function getCredentials(
runIndex?: number,
connectionInputData?: INodeExecutionData[],
itemIndex?: number,
): Promise<ICredentialDataDecryptedObject> {
): Promise<T> {
// Get the NodeType as it has the information if the credentials are required
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
if (nodeType === undefined) {
@ -2117,7 +2121,7 @@ export async function getCredentials(
expressionResolveValues,
);
return decryptedDataObject;
return decryptedDataObject as T;
}
/**

View file

@ -17,7 +17,7 @@ export async function automizyApiRequest(
qs: IDataObject = {},
option = {},
): Promise<any> {
const credentials = (await this.getCredentials('automizyApi')) as IDataObject;
const credentials = await this.getCredentials<{ apiToken: string }>('automizyApi');
const options: IRequestOptions = {
headers: {

View file

@ -19,16 +19,14 @@ export async function autopilotApiRequest(
uri?: string,
_option: IDataObject = {},
): Promise<any> {
const credentials = (await this.getCredentials('autopilotApi')) as IDataObject;
const apiKey = `${credentials.apiKey}`;
const credentials = await this.getCredentials<{ apiKey: string }>('autopilotApi');
const endpoint = 'https://api2.autopilothq.com/v1';
const options: IRequestOptions = {
headers: {
'Content-Type': 'application/json',
autopilotapikey: apiKey,
autopilotapikey: credentials.apiKey,
},
method,
body,

View file

@ -111,7 +111,7 @@ export class Baserow implements INodeType {
methods = {
loadOptions: {
async getDatabaseIds(this: ILoadOptionsFunctions) {
const credentials = (await this.getCredentials('baserowApi')) as BaserowCredentials;
const credentials = await this.getCredentials<BaserowCredentials>('baserowApi');
const jwtToken = await getJwtToken.call(this, credentials);
const endpoint = '/api/applications/';
const databases = (await baserowApiRequest.call(
@ -124,7 +124,7 @@ export class Baserow implements INodeType {
},
async getTableIds(this: ILoadOptionsFunctions) {
const credentials = (await this.getCredentials('baserowApi')) as BaserowCredentials;
const credentials = await this.getCredentials<BaserowCredentials>('baserowApi');
const jwtToken = await getJwtToken.call(this, credentials);
const databaseId = this.getNodeParameter('databaseId', 0) as string;
const endpoint = `/api/database/tables/database/${databaseId}/`;
@ -138,7 +138,7 @@ export class Baserow implements INodeType {
},
async getTableFields(this: ILoadOptionsFunctions) {
const credentials = (await this.getCredentials('baserowApi')) as BaserowCredentials;
const credentials = await this.getCredentials<BaserowCredentials>('baserowApi');
const jwtToken = await getJwtToken.call(this, credentials);
const tableId = this.getNodeParameter('tableId', 0) as string;
const endpoint = `/api/database/fields/table/${tableId}/`;
@ -160,7 +160,7 @@ export class Baserow implements INodeType {
const operation = this.getNodeParameter('operation', 0) as Operation;
const tableId = this.getNodeParameter('tableId', 0) as string;
const credentials = (await this.getCredentials('baserowApi')) as BaserowCredentials;
const credentials = await this.getCredentials<BaserowCredentials>('baserowApi');
const jwtToken = await getJwtToken.call(this, credentials);
const fields = await mapper.getTableFields.call(this, tableId, jwtToken);
mapper.createMappings(fields);

View file

@ -21,7 +21,7 @@ export async function baserowApiRequest(
body: IDataObject = {},
qs: IDataObject = {},
) {
const credentials = (await this.getCredentials('baserowApi')) as BaserowCredentials;
const credentials = await this.getCredentials<BaserowCredentials>('baserowApi');
const options: IRequestOptions = {
headers: {

View file

@ -19,7 +19,7 @@ export async function getAuthenticationType(
): Promise<'accessToken' | 'apiKey'> {
const authentication = this.getNodeParameter('authentication', 0) as string;
if (authentication === 'apiKey') {
const { apiKey } = (await this.getCredentials('calendlyApi')) as { apiKey: string };
const { apiKey } = await this.getCredentials<{ apiKey: string }>('calendlyApi');
return getAuthenticationTypeFromApiKey(apiKey);
} else {
return 'accessToken';

View file

@ -21,7 +21,7 @@ export async function dhlApiRequest(
uri?: string,
option: IDataObject = {},
): Promise<any> {
const credentials = (await this.getCredentials('dhlApi')) as { apiKey: string };
const credentials = await this.getCredentials<{ apiKey: string }>('dhlApi');
let options: IRequestOptions = {
headers: {

View file

@ -17,7 +17,7 @@ export async function discourseApiRequest(
qs: IDataObject = {},
_option = {},
): Promise<any> {
const credentials = (await this.getCredentials('discourseApi')) as { url: string };
const credentials = await this.getCredentials<{ url: string }>('discourseApi');
const options: IRequestOptions = {
method,

View file

@ -17,7 +17,7 @@ export async function disqusApiRequest(
body: IDataObject = {},
option: IDataObject = {},
): Promise<any> {
const credentials = (await this.getCredentials('disqusApi')) as IDataObject;
const credentials = await this.getCredentials<{ accessToken: string }>('disqusApi');
qs.api_key = credentials.accessToken;
// Convert to query string into a format the API can read

View file

@ -116,8 +116,8 @@ export function simplify(data: IDataObject[]) {
export async function getCredentials(this: IExecuteFunctions) {
const authenticationMethod = this.getNodeParameter('authentication', 0) as string;
if (authenticationMethod === 'accessToken') {
return (await this.getCredentials('dropboxApi')) as IDataObject;
return await this.getCredentials('dropboxApi');
} else {
return (await this.getCredentials('dropboxOAuth2Api')) as IDataObject;
return await this.getCredentials('dropboxOAuth2Api');
}
}

View file

@ -24,7 +24,7 @@ export async function erpNextApiRequest(
uri?: string,
option: IDataObject = {},
) {
const credentials = (await this.getCredentials('erpNextApi')) as ERPNextApiCredentials;
const credentials = await this.getCredentials<ERPNextApiCredentials>('erpNextApi');
const baseUrl = getBaseUrl(credentials);
let options: IRequestOptions = {

View file

@ -23,7 +23,7 @@ export async function emeliaApiRequest(
body: object = {},
qs: IDataObject = {},
) {
const { apiKey } = (await this.getCredentials('emeliaApi')) as { apiKey: string };
const { apiKey } = await this.getCredentials<{ apiKey: string }>('emeliaApi');
const options: IRequestOptions = {
headers: {

View file

@ -61,7 +61,7 @@ export async function formIoApiRequest(
body = {},
qs = {},
): Promise<any> {
const credentials = (await this.getCredentials('formIoApi')) as unknown as IFormIoCredentials;
const credentials = await this.getCredentials<IFormIoCredentials>('formIoApi');
const token = await getToken.call(this, credentials);

View file

@ -73,7 +73,7 @@ export async function apiRequest(
try {
if (authenticationMethod === 'accessToken') {
const credentials = (await this.getCredentials('formstackApi')) as IDataObject;
const credentials = await this.getCredentials<{ accessToken: string }>('formstackApi');
options.headers!.Authorization = `Bearer ${credentials.accessToken}`;
return await this.helpers.request(options);

View file

@ -23,7 +23,7 @@ export async function freshworksCrmApiRequest(
body: IDataObject = {},
qs: IDataObject = {},
) {
const { domain } = (await this.getCredentials('freshworksCrmApi')) as FreshworksCrmApiCredentials;
const { domain } = await this.getCredentials<FreshworksCrmApiCredentials>('freshworksCrmApi');
const options: IRequestOptions = {
method,

View file

@ -510,9 +510,9 @@ export class Ftp implements INodeType {
const protocol = this.getNodeParameter('protocol', 0) as string;
if (protocol === 'sftp') {
credentials = await this.getCredentials('sftp');
credentials = await this.getCredentials<ICredentialDataDecryptedObject>('sftp');
} else {
credentials = await this.getCredentials('ftp');
credentials = await this.getCredentials<ICredentialDataDecryptedObject>('ftp');
}
let ftp: ftpClient;
let sftp: sftpClient;

View file

@ -143,9 +143,9 @@ export async function handleGetAll(
}
export async function loadWebinars(this: ILoadOptionsFunctions) {
const { oauthTokenData } = (await this.getCredentials('goToWebinarOAuth2Api')) as {
const { oauthTokenData } = await this.getCredentials<{
oauthTokenData: { account_key: string };
};
}>('goToWebinarOAuth2Api');
const endpoint = `accounts/${oauthTokenData.account_key}/webinars`;
@ -176,9 +176,9 @@ export async function loadWebinars(this: ILoadOptionsFunctions) {
}
export async function loadWebinarSessions(this: ILoadOptionsFunctions) {
const { oauthTokenData } = (await this.getCredentials('goToWebinarOAuth2Api')) as {
const { oauthTokenData } = await this.getCredentials<{
oauthTokenData: { organizer_key: string };
};
}>('goToWebinarOAuth2Api');
const webinarKey = this.getCurrentNodeParameter('webinarKey') as string;
@ -208,9 +208,9 @@ export async function loadWebinarSessions(this: ILoadOptionsFunctions) {
}
export async function loadRegistranSimpleQuestions(this: ILoadOptionsFunctions) {
const { oauthTokenData } = (await this.getCredentials('goToWebinarOAuth2Api')) as {
const { oauthTokenData } = await this.getCredentials<{
oauthTokenData: { organizer_key: string };
};
}>('goToWebinarOAuth2Api');
const webinarkey = this.getNodeParameter('webinarKey') as string;
@ -233,9 +233,9 @@ export async function loadRegistranSimpleQuestions(this: ILoadOptionsFunctions)
}
export async function loadAnswers(this: ILoadOptionsFunctions) {
const { oauthTokenData } = (await this.getCredentials('goToWebinarOAuth2Api')) as {
const { oauthTokenData } = await this.getCredentials<{
oauthTokenData: { organizer_key: string };
};
}>('goToWebinarOAuth2Api');
const webinarKey = this.getCurrentNodeParameter('webinarKey') as string;
@ -262,9 +262,9 @@ export async function loadAnswers(this: ILoadOptionsFunctions) {
}
export async function loadRegistranMultiChoiceQuestions(this: ILoadOptionsFunctions) {
const { oauthTokenData } = (await this.getCredentials('goToWebinarOAuth2Api')) as {
const { oauthTokenData } = await this.getCredentials<{
oauthTokenData: { organizer_key: string };
};
}>('goToWebinarOAuth2Api');
const webinarkey = this.getNodeParameter('webinarKey') as string;

View file

@ -154,9 +154,9 @@ export class GoToWebinar implements INodeType {
let responseData;
const returnData: INodeExecutionData[] = [];
const { oauthTokenData } = (await this.getCredentials('goToWebinarOAuth2Api')) as {
const { oauthTokenData } = await this.getCredentials<{
oauthTokenData: { account_key: string; organizer_key: string };
};
}>('goToWebinarOAuth2Api');
const accountKey = oauthTokenData.account_key;
const organizerKey = oauthTokenData.organizer_key;

View file

@ -42,10 +42,10 @@ export async function googleApiRequest(
}
if (authenticationMethod === 'serviceAccount') {
const credentials = (await this.getCredentials('googleApi')) as {
const credentials = await this.getCredentials<{
email: string;
privateKey: string;
};
}>('googleApi');
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'books');

View file

@ -21,7 +21,7 @@ export async function grafanaApiRequest(
body: IDataObject = {},
qs: IDataObject = {},
) {
const { baseUrl: rawBaseUrl } = (await this.getCredentials('grafanaApi')) as GrafanaCredentials;
const { baseUrl: rawBaseUrl } = await this.getCredentials<GrafanaCredentials>('grafanaApi');
const baseUrl = tolerateTrailingSlash(rawBaseUrl);

View file

@ -534,7 +534,7 @@ export class JiraTrigger implements INodeType {
let httpQueryAuth: ICredentialDataDecryptedObject | undefined;
try {
httpQueryAuth = await this.getCredentials('httpQueryAuth');
httpQueryAuth = await this.getCredentials<ICredentialDataDecryptedObject>('httpQueryAuth');
} catch (error) {}
if (httpQueryAuth === undefined || !httpQueryAuth.name || !httpQueryAuth.value) {

View file

@ -348,13 +348,13 @@ export class Jwt implements INodeType {
const operation = this.getNodeParameter('operation', 0);
const credentials = (await this.getCredentials('jwtAuth')) as {
const credentials = await this.getCredentials<{
keyType: 'passphrase' | 'pemKey';
publicKey: string;
privateKey: string;
secret: string;
algorithm: jwt.Algorithm;
};
}>('jwtAuth');
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
const options = this.getNodeParameter('options', itemIndex, {}) as {

View file

@ -12,9 +12,9 @@ export async function kitemakerRequest(
this: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions,
body: IDataObject = {},
) {
const { personalAccessToken } = (await this.getCredentials('kitemakerApi')) as {
const { personalAccessToken } = await this.getCredentials<{
personalAccessToken: string;
};
}>('kitemakerApi');
const options = {
headers: {

View file

@ -130,7 +130,7 @@ export class Mqtt implements INodeType {
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const credentials = (await this.getCredentials('mqtt')) as unknown as MqttCredential;
const credentials = await this.getCredentials<MqttCredential>('mqtt');
const client = await createClient(credentials);
const publishPromises = [];

View file

@ -107,7 +107,7 @@ export class MqttTrigger implements INodeType {
}
const options = this.getNodeParameter('options') as Options;
const credentials = (await this.getCredentials('mqtt')) as unknown as MqttCredential;
const credentials = await this.getCredentials<MqttCredential>('mqtt');
const client = await createClient(credentials);
const parsePayload = (topic: string, payload: Buffer) => {

View file

@ -23,9 +23,9 @@ export async function mailjetApiRequest(
if (resource === 'email' || this.getNode().type.includes('Trigger')) {
credentialType = 'mailjetEmailApi';
const { sandboxMode } = (await this.getCredentials('mailjetEmailApi')) as {
const { sandboxMode } = await this.getCredentials<{
sandboxMode: boolean;
};
}>('mailjetEmailApi');
if (!this.getNode().type.includes('Trigger')) {
Object.assign(body, { SandboxMode: sandboxMode });

View file

@ -20,10 +20,10 @@ export async function microsoftApiRequest(
uri?: string,
option: IDataObject = {},
): Promise<any> {
const credentials = (await this.getCredentials('microsoftDynamicsOAuth2Api')) as {
const credentials = await this.getCredentials<{
subdomain: string;
region: string;
};
}>('microsoftDynamicsOAuth2Api');
let options: IRequestOptions = {
headers: {

View file

@ -17,11 +17,11 @@ export async function msGraphSecurityApiRequest(
) {
const {
oauthTokenData: { access_token },
} = (await this.getCredentials('microsoftGraphSecurityOAuth2Api')) as {
} = await this.getCredentials<{
oauthTokenData: {
access_token: string;
};
};
}>('microsoftGraphSecurityOAuth2Api');
const options: IRequestOptions = {
headers: {

View file

@ -17,11 +17,11 @@ export async function monicaCrmApiRequest(
body: IDataObject = {},
qs: IDataObject = {},
) {
const credentials = (await this.getCredentials('monicaCrmApi')) as {
const credentials = await this.getCredentials<{
apiToken: string;
environment: string;
domain: string;
};
}>('monicaCrmApi');
if (credentials === undefined) {
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');

View file

@ -16,7 +16,7 @@ export async function router(this: IExecuteFunctions): Promise<INodeExecutionDat
nodeOptions.nodeVersion = this.getNode().typeVersion;
const credentials = (await this.getCredentials('mySql')) as MysqlNodeCredentials;
const credentials = await this.getCredentials<MysqlNodeCredentials>('mySql');
const pool = await createPool.call(this, credentials, nodeOptions);

View file

@ -3,7 +3,7 @@ import { createPool } from '../transport';
import type { MysqlNodeCredentials } from '../helpers/interfaces';
export async function searchTables(this: ILoadOptionsFunctions): Promise<INodeListSearchResult> {
const credentials = (await this.getCredentials('mySql')) as MysqlNodeCredentials;
const credentials = await this.getCredentials<MysqlNodeCredentials>('mySql');
const nodeOptions = this.getNodeParameter('options', 0) as IDataObject;

View file

@ -4,7 +4,7 @@ import { escapeSqlIdentifier } from '../helpers/utils';
import type { MysqlNodeCredentials } from '../helpers/interfaces';
export async function getColumns(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const credentials = (await this.getCredentials('mySql')) as MysqlNodeCredentials;
const credentials = await this.getCredentials<MysqlNodeCredentials>('mySql');
const nodeOptions = this.getNodeParameter('options', 0) as IDataObject;
const pool = await createPool.call(this, credentials, nodeOptions);

View file

@ -32,7 +32,7 @@ export async function apiRequest(
baseUrl: string;
};
const credentials = (await this.getCredentials('n8nApi')) as N8nApiCredentials;
const credentials = await this.getCredentials<N8nApiCredentials>('n8nApi');
const baseUrl = credentials.baseUrl;
const options: IRequestOptions = {

View file

@ -19,7 +19,7 @@ export async function netscalerADCApiRequest(
uri?: string,
option: IDataObject = {},
): Promise<any> {
const { url } = (await this.getCredentials('citrixAdcApi')) as { url: string };
const { url } = await this.getCredentials<{ url: string }>('citrixAdcApi');
let options: IRequestOptions = {
headers: {

View file

@ -27,9 +27,9 @@ export async function nextCloudApiRequest(
let credentials;
if (authenticationMethod === 'accessToken') {
credentials = (await this.getCredentials('nextCloudApi')) as { webDavUrl: string };
credentials = await this.getCredentials<{ webDavUrl: string }>('nextCloudApi');
} else {
credentials = (await this.getCredentials('nextCloudOAuth2Api')) as { webDavUrl: string };
credentials = await this.getCredentials<{ webDavUrl: string }>('nextCloudOAuth2Api');
}
const options: IRequestOptions = {

View file

@ -162,7 +162,7 @@ export class PayPalTrigger implements INodeType {
const headerData = this.getHeaderData() as IDataObject;
const endpoint = '/notifications/verify-webhook-signature';
const { env } = (await this.getCredentials('payPalApi')) as { env: string };
const { env } = await this.getCredentials<{ env: string }>('payPalApi');
// if sanbox omit verification
if (env === 'sanbox') {

View file

@ -325,7 +325,7 @@ export class PipedriveTrigger implements INodeType {
let httpBasicAuth: ICredentialDataDecryptedObject | undefined;
try {
httpBasicAuth = await this.getCredentials('httpBasicAuth');
httpBasicAuth = await this.getCredentials<ICredentialDataDecryptedObject>('httpBasicAuth');
} catch (error) {
// Do nothing
}

View file

@ -19,10 +19,10 @@ export async function plivoApiRequest(
body: IDataObject = {},
qs: IDataObject = {},
) {
const credentials = (await this.getCredentials('plivoApi')) as {
const credentials = await this.getCredentials<{
authId: string;
authToken: string;
};
}>('plivoApi');
const options: IRequestOptions = {
headers: {

View file

@ -87,7 +87,7 @@ export async function pgTriggerFunction(
}
export async function initDB(this: ITriggerFunctions | ILoadOptionsFunctions) {
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;
const credentials = await this.getCredentials<PostgresNodeCredentials>('postgres');
const options = this.getNodeParameter('options', {}) as {
connectionTimeout?: number;
delayClosingIdleConnection?: number;

View file

@ -15,7 +15,7 @@ export async function router(this: IExecuteFunctions): Promise<INodeExecutionDat
const resource = this.getNodeParameter<PostgresType>('resource', 0);
const operation = this.getNodeParameter('operation', 0);
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;
const credentials = await this.getCredentials<PostgresNodeCredentials>('postgres');
const options = this.getNodeParameter('options', 0, {}) as PostgresNodeOptions;
const node = this.getNode();
options.nodeVersion = node.typeVersion;

View file

@ -4,7 +4,7 @@ import { configurePostgres } from '../transport';
import type { PostgresNodeCredentials } from '../helpers/interfaces';
export async function schemaSearch(this: ILoadOptionsFunctions): Promise<INodeListSearchResult> {
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;
const credentials = await this.getCredentials<PostgresNodeCredentials>('postgres');
const options = { nodeVersion: this.getNode().typeVersion };
const { db } = await configurePostgres.call(this, credentials, options);
@ -23,7 +23,7 @@ export async function schemaSearch(this: ILoadOptionsFunctions): Promise<INodeLi
}
}
export async function tableSearch(this: ILoadOptionsFunctions): Promise<INodeListSearchResult> {
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;
const credentials = await this.getCredentials<PostgresNodeCredentials>('postgres');
const options = { nodeVersion: this.getNode().typeVersion };
const { db } = await configurePostgres.call(this, credentials, options);

View file

@ -5,7 +5,7 @@ import { configurePostgres } from '../transport';
import type { PostgresNodeCredentials } from '../helpers/interfaces';
export async function getColumns(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;
const credentials = await this.getCredentials<PostgresNodeCredentials>('postgres');
const options = { nodeVersion: this.getNode().typeVersion };
const { db } = await configurePostgres.call(this, credentials, options);

View file

@ -46,7 +46,7 @@ function mapPostgresType(postgresType: string): FieldType {
export async function getMappingColumns(
this: ILoadOptionsFunctions,
): Promise<ResourceMapperFields> {
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;
const credentials = await this.getCredentials<PostgresNodeCredentials>('postgres');
const { db } = await configurePostgres.call(this, credentials);

View file

@ -254,9 +254,9 @@ export async function loadResource(this: ILoadOptionsFunctions, resource: string
oauthTokenData: {
callbackQueryString: { realmId },
},
} = (await this.getCredentials('quickBooksOAuth2Api')) as {
} = await this.getCredentials<{
oauthTokenData: { callbackQueryString: { realmId: string } };
};
}>('quickBooksOAuth2Api');
const endpoint = `/v3/company/${realmId}/query`;
const resourceItems = await quickBooksApiRequestAllItems.call(

View file

@ -23,10 +23,10 @@ export async function supabaseApiRequest(
uri?: string,
headers: IDataObject = {},
) {
const credentials = (await this.getCredentials('supabaseApi')) as {
const credentials = await this.getCredentials<{
host: string;
serviceRole: string;
};
}>('supabaseApi');
const options: IRequestOptions = {
headers: {

View file

@ -126,7 +126,7 @@ export class Totp implements INodeType {
const returnData: INodeExecutionData[] = [];
const operation = this.getNodeParameter('operation', 0);
const credentials = (await this.getCredentials('totpApi')) as { label: string; secret: string };
const credentials = await this.getCredentials<{ label: string; secret: string }>('totpApi');
if (!credentials.label.includes(':')) {
throw new NodeOperationError(this.getNode(), 'Malformed label - expected `issuer:username`');

View file

@ -19,13 +19,13 @@ export async function twilioApiRequest(
body: IDataObject,
query?: IDataObject,
): Promise<any> {
const credentials = (await this.getCredentials('twilioApi')) as {
const credentials = await this.getCredentials<{
accountSid: string;
authType: 'authToken' | 'apiKey';
authToken: string;
apiKeySid: string;
apiKeySecret: string;
};
}>('twilioApi');
if (query === undefined) {
query = {};

View file

@ -19,7 +19,7 @@ export async function venafiApiRequest(
uri?: string,
headers: IDataObject = {},
): Promise<any> {
const credentials = (await this.getCredentials('venafiTlsProtectDatacenterApi')) as IDataObject;
const credentials = await this.getCredentials('venafiTlsProtectDatacenterApi');
const options: IRequestOptions = {
headers: {

View file

@ -191,7 +191,7 @@ export async function validateWebhookAuthentication(
// Basic authorization is needed to call webhook
let expectedAuth: ICredentialDataDecryptedObject | undefined;
try {
expectedAuth = await ctx.getCredentials('httpBasicAuth');
expectedAuth = await ctx.getCredentials<ICredentialDataDecryptedObject>('httpBasicAuth');
} catch {}
if (expectedAuth === undefined || !expectedAuth.user || !expectedAuth.password) {
@ -211,7 +211,7 @@ export async function validateWebhookAuthentication(
// Special header with value is needed to call webhook
let expectedAuth: ICredentialDataDecryptedObject | undefined;
try {
expectedAuth = await ctx.getCredentials('httpHeaderAuth');
expectedAuth = await ctx.getCredentials<ICredentialDataDecryptedObject>('httpHeaderAuth');
} catch {}
if (expectedAuth === undefined || !expectedAuth.name || !expectedAuth.value) {
@ -232,12 +232,12 @@ export async function validateWebhookAuthentication(
let expectedAuth;
try {
expectedAuth = (await ctx.getCredentials('jwtAuth')) as {
expectedAuth = await ctx.getCredentials<{
keyType: 'passphrase' | 'pemKey';
publicKey: string;
secret: string;
algorithm: jwt.Algorithm;
};
}>('jwtAuth');
} catch {}
if (expectedAuth === undefined) {

View file

@ -21,11 +21,11 @@ export async function wiseApiRequest(
qs: IDataObject = {},
option: IDataObject = {},
) {
const { apiToken, environment, privateKey } = (await this.getCredentials('wiseApi')) as {
const { apiToken, environment, privateKey } = await this.getCredentials<{
apiToken: string;
environment: 'live' | 'test';
privateKey?: string;
};
}>('wiseApi');
const rootUrl =
environment === 'live'

View file

@ -19,10 +19,10 @@ export async function workableApiRequest(
uri?: string,
option: IDataObject = {},
): Promise<any> {
const credentials = (await this.getCredentials('workableApi')) as {
const credentials = await this.getCredentials<{
accessToken: string;
subdomain: string;
};
}>('workableApi');
let options: IRequestOptions = {
headers: { Authorization: `Bearer ${credentials.accessToken}` },

View file

@ -137,10 +137,10 @@ export class WorkableTrigger implements INodeType {
return false;
},
async create(this: IHookFunctions): Promise<boolean> {
const credentials = (await this.getCredentials('workableApi')) as {
const credentials = await this.getCredentials<{
accessToken: string;
subdomain: string;
};
}>('workableApi');
const webhookData = this.getWorkflowStaticData('node');
const webhookUrl = this.getNodeWebhookUrl('default');
const triggerOn = this.getNodeParameter('triggerOn') as string;

View file

@ -30,9 +30,9 @@ export async function zendeskApiRequest(
let credentials;
if (authenticationMethod === 'apiToken') {
credentials = (await this.getCredentials('zendeskApi')) as { subdomain: string };
credentials = await this.getCredentials<{ subdomain: string }>('zendeskApi');
} else {
credentials = (await this.getCredentials('zendeskOAuth2Api')) as { subdomain: string };
credentials = await this.getCredentials<{ subdomain: string }>('zendeskOAuth2Api');
}
let options: IRequestOptions = {

View file

@ -90,7 +90,7 @@ export interface IGetCredentials {
get(type: string, id: string | null): Promise<ICredentialsEncrypted>;
}
export abstract class ICredentials {
export abstract class ICredentials<T extends object = ICredentialDataDecryptedObject> {
id?: string;
name: string;
@ -106,11 +106,11 @@ export abstract class ICredentials {
this.data = data;
}
abstract getData(nodeType?: string): ICredentialDataDecryptedObject;
abstract getData(nodeType?: string): T;
abstract getDataToSave(): ICredentialsEncrypted;
abstract setData(data: ICredentialDataDecryptedObject): void;
abstract setData(data: T): void;
}
export interface IUser {
@ -128,11 +128,11 @@ export type ProjectSharingData = {
updatedAt: string;
};
export interface ICredentialsDecrypted {
export interface ICredentialsDecrypted<T extends object = ICredentialDataDecryptedObject> {
id: string;
name: string;
type: string;
data?: ICredentialDataDecryptedObject;
data?: T;
homeProject?: ProjectSharingData;
sharedWithProjects?: ProjectSharingData[];
}
@ -718,7 +718,7 @@ export interface IExecuteWorkflowInfo {
export type ICredentialTestFunction = (
this: ICredentialTestFunctions,
credential: ICredentialsDecrypted,
credential: ICredentialsDecrypted<ICredentialDataDecryptedObject>,
) => Promise<INodeCredentialTestResult>;
export interface ICredentialTestFunctions {
@ -860,7 +860,10 @@ export type NodeTypeAndVersion = {
export interface FunctionsBase {
logger: Logger;
getCredentials(type: string, itemIndex?: number): Promise<ICredentialDataDecryptedObject>;
getCredentials<T extends object = ICredentialDataDecryptedObject>(
type: string,
itemIndex?: number,
): Promise<T>;
getCredentialsProperties(type: string): INodeProperties[];
getExecutionId(): string;
getNode(): INode;

View file

@ -116,7 +116,9 @@ export class RoutingNode {
credentials = credentialsDecrypted.data;
} else if (credentialType) {
try {
credentials = (await executeFunctions.getCredentials(credentialType)) || {};
credentials =
(await executeFunctions.getCredentials<ICredentialDataDecryptedObject>(credentialType)) ||
{};
} catch (error) {
if (
nodeType.description.credentials?.length &&