Skip to content

Commit

Permalink
Merge branch 'master' into node-1466-overhaul-code-node-p0
Browse files Browse the repository at this point in the history
  • Loading branch information
elsmr committed Dec 18, 2024
2 parents 2a43a5b + 92af245 commit b90ea5a
Show file tree
Hide file tree
Showing 78 changed files with 4,096 additions and 227 deletions.
1 change: 0 additions & 1 deletion packages/@n8n/nodes-langchain/utils/logWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,6 @@ export function logWrapper(
return async (
query: string,
k?: number,
// @ts-ignore
filter?: BiquadFilterType | undefined,
_callbacks?: Callbacks | undefined,
): Promise<Document[]> => {
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@sentry/node": "catalog:",
"aws4": "1.11.0",
"axios": "catalog:",
"chardet": "2.0.0",
"concat-stream": "2.0.0",
"cron": "3.1.7",
"fast-glob": "catalog:",
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/NodeExecuteFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
import { ClientOAuth2 } from '@n8n/client-oauth2';
import type { AxiosError, AxiosHeaders, AxiosRequestConfig, AxiosResponse } from 'axios';
import axios from 'axios';
import chardet from 'chardet';
import crypto, { createHmac } from 'crypto';
import FileType from 'file-type';
import FormData from 'form-data';
Expand Down Expand Up @@ -1050,6 +1051,10 @@ export async function getBinaryDataBuffer(
return await Container.get(BinaryDataService).getAsBuffer(binaryData);
}

export function detectBinaryEncoding(buffer: Buffer): string {
return chardet.detect(buffer) as string;
}

/**
* Store an incoming IBinaryData & related buffer using the configured binary data manager.
*
Expand Down
3 changes: 0 additions & 3 deletions packages/core/src/WorkflowExecute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1796,16 +1796,13 @@ export class WorkflowExecute {
lineResult.json.$json !== undefined
) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
lineResult.error = lineResult.json.$error as NodeApiError | NodeOperationError;
lineResult.json = {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
error: (lineResult.json.$error as NodeApiError | NodeOperationError).message,
};
} else if (lineResult.error !== undefined) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
lineResult.json = { error: lineResult.error.message };
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/node-execution-context/execute-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
getSSHTunnelFunctions,
getFileSystemHelperFunctions,
getCheckProcessedHelperFunctions,
detectBinaryEncoding,
} from '@/NodeExecuteFunctions';

import { BaseExecuteContext } from './base-execute-context';
Expand Down Expand Up @@ -96,6 +97,7 @@ export class ExecuteContext extends BaseExecuteContext implements IExecuteFuncti
assertBinaryData(inputData, node, itemIndex, propertyName, 0),
getBinaryDataBuffer: async (itemIndex, propertyName) =>
await getBinaryDataBuffer(inputData, itemIndex, propertyName, 0),
detectBinaryEncoding: (buffer: Buffer) => detectBinaryEncoding(buffer),
};

this.nodeHelpers = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ApplicationError, createDeferredPromise, NodeConnectionType } from 'n8n
// eslint-disable-next-line import/no-cycle
import {
assertBinaryData,
detectBinaryEncoding,
getBinaryDataBuffer,
getBinaryHelperFunctions,
getRequestHelperFunctions,
Expand Down Expand Up @@ -69,6 +70,7 @@ export class ExecuteSingleContext extends BaseExecuteContext implements IExecute
assertBinaryData(inputData, node, itemIndex, propertyName, inputIndex),
getBinaryDataBuffer: async (propertyName, inputIndex = 0) =>
await getBinaryDataBuffer(inputData, itemIndex, propertyName, inputIndex),
detectBinaryEncoding: (buffer) => detectBinaryEncoding(buffer),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
assertBinaryData,
constructExecutionMetaData,
copyInputItems,
detectBinaryEncoding,
getBinaryDataBuffer,
getBinaryHelperFunctions,
getCheckProcessedHelperFunctions,
Expand Down Expand Up @@ -87,6 +88,7 @@ export class SupplyDataContext extends BaseExecuteContext implements ISupplyData
assertBinaryData(inputData, node, itemIndex, propertyName, 0),
getBinaryDataBuffer: async (itemIndex, propertyName) =>
await getBinaryDataBuffer(inputData, itemIndex, propertyName, 0),
detectBinaryEncoding: (buffer: Buffer) => detectBinaryEncoding(buffer),

returnJsonArray,
normalizeItems,
Expand Down
3 changes: 3 additions & 0 deletions packages/editor-ui/src/composables/useMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export function useMessage() {
...(config ?? (typeof configOrTitle === 'object' ? configOrTitle : {})),
cancelButtonClass: 'btn--cancel',
confirmButtonClass: 'btn--confirm',
dangerouslyUseHTMLString: true,
};

if (typeof configOrTitle === 'string') {
Expand All @@ -49,6 +50,7 @@ export function useMessage() {
distinguishCancelAndClose: true,
showClose: config?.showClose ?? false,
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
...(config ?? (typeof configOrTitle === 'object' ? configOrTitle : {})),
};

Expand All @@ -74,6 +76,7 @@ export function useMessage() {
...(config ?? (typeof configOrTitle === 'object' ? configOrTitle : {})),
cancelButtonClass: 'btn--cancel',
confirmButtonClass: 'btn--confirm',
dangerouslyUseHTMLString: true,
};

if (typeof configOrTitle === 'string') {
Expand Down
1 change: 0 additions & 1 deletion packages/editor-ui/src/composables/useWorkflowHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,6 @@ export function useWorkflowHelpers(options: { router: ReturnType<typeof useRoute

const nodes: INode[] = [];
for (let nodeIndex = 0; nodeIndex < workflowNodes.length; nodeIndex++) {
// @ts-ignore
nodeData = getNodeDataToSave(workflowNodes[nodeIndex]);

nodes.push(nodeData);
Expand Down
2 changes: 0 additions & 2 deletions packages/node-dev/src/Build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,7 @@ export async function buildFiles({

// Forward the output of the child process to the main one
// that the user can see what is happening
// @ts-ignore
buildProcess.stdout.pipe(process.stdout);
// @ts-ignore
buildProcess.stderr.pipe(process.stderr);

// Make sure that the child process gets also always terminated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class ElasticsearchApi implements ICredentialType {

test: ICredentialTestRequest = {
request: {
baseURL: '={{$credentials.baseUrl}}',
baseURL: '={{$credentials.baseUrl}}'.replace(/\/$/, ''),
url: '/_xpack?human=false',
skipSslCertificateValidation: '={{$credentials.ignoreSSLIssues}}',
},
Expand Down
3 changes: 3 additions & 0 deletions packages/nodes-base/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Avoid tests failing because of difference between local and GitHub actions timezone
process.env.TZ = 'UTC';

/** @type {import('jest').Config} */
module.exports = {
...require('../../jest.config'),
Expand Down
2 changes: 0 additions & 2 deletions packages/nodes-base/nodes/Affinity/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export async function affinityApiRequestAllItems(

do {
responseData = await affinityApiRequest.call(this, method, resource, body, query);
// @ts-ignore
query.page_token = responseData.page_token;
returnData.push.apply(returnData, responseData[propertyName] as IDataObject[]);
} while (responseData.page_token !== undefined && responseData.page_token !== null);
Expand All @@ -84,7 +83,6 @@ export function eventsExist(subscriptions: string[], currentSubsriptions: string
}

export function mapResource(key: string) {
//@ts-ignore
return {
person: 'persons',
list: 'lists',
Expand Down
1 change: 0 additions & 1 deletion packages/nodes-base/nodes/Automizy/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ export async function automizyApiRequest(
if (Object.keys(option).length !== 0) {
Object.assign(options, option);
}
//@ts-ignore
return await this.helpers.request.call(this, options);
} catch (error) {
throw new NodeApiError(this.getNode(), error as JsonObject);
Expand Down
1 change: 0 additions & 1 deletion packages/nodes-base/nodes/BambooHr/v1/transport/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export async function apiRequest(
}

try {
//@ts-ignore
return await this.helpers.request(options);
} catch (error) {
const description = error?.response?.headers['x-bamboohr-error-messsage'] || '';
Expand Down
1 change: 0 additions & 1 deletion packages/nodes-base/nodes/Box/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export async function boxApiRequest(
includeCredentialsOnRefreshOnBody: true,
};

//@ts-ignore
return await this.helpers.requestOAuth2.call(this, 'boxOAuth2Api', options, oAuth2Options);
} catch (error) {
throw new NodeApiError(this.getNode(), error as JsonObject);
Expand Down
1 change: 0 additions & 1 deletion packages/nodes-base/nodes/Cisco/Webex/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export async function webexApiRequest(
if (Object.keys(qs).length === 0) {
delete options.qs;
}
//@ts-ignore
return await this.helpers.requestOAuth2.call(this, 'ciscoWebexOAuth2Api', options, {
tokenType: 'Bearer',
});
Expand Down
1 change: 0 additions & 1 deletion packages/nodes-base/nodes/ClickUp/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export async function clickupApiRequest(
keepBearer: false,
tokenType: 'Bearer',
};
// @ts-ignore
return await this.helpers.requestOAuth2.call(
this,
'clickUpOAuth2Api',
Expand Down
1 change: 0 additions & 1 deletion packages/nodes-base/nodes/Coda/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ export async function codaApiRequestAllItems(
do {
responseData = await codaApiRequest.call(this, method, resource, body, query, uri);
uri = responseData.nextPageLink;
// @ts-ignore
returnData.push.apply(returnData, responseData[propertyName] as IDataObject[]);
} while (responseData.nextPageLink !== undefined && responseData.nextPageLink !== '');

Expand Down
1 change: 0 additions & 1 deletion packages/nodes-base/nodes/CoinGecko/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export async function coinGeckoApiRequest(
delete options.body;
}

//@ts-ignore
return await this.helpers.request.call(this, options);
} catch (error) {
throw new NodeApiError(this.getNode(), error as JsonObject);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export class Elasticsearch implements INodeType {
} else {
responseData = await elasticsearchApiRequest.call(
this,
'GET',
'POST',
`/${indexId}/_search`,
body,
qs,
Expand All @@ -184,7 +184,7 @@ export class Elasticsearch implements INodeType {

responseData = await elasticsearchApiRequest.call(
this,
'GET',
'POST',
`/${indexId}/_search`,
body,
qs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export async function elasticsearchBulkApiRequest(this: IExecuteFunctions, body:
method: 'POST',
headers: { 'Content-Type': 'application/x-ndjson' },
body: bulkBody,
url: `${baseUrl}/_bulk`,
url: `${baseUrl.replace(/\/$/, '')}/_bulk`,
skipSslCertificateValidation: ignoreSSLIssues,
returnFullResponse: true,
ignoreHttpStatusErrors: true,
Expand Down Expand Up @@ -66,7 +66,7 @@ export async function elasticsearchApiRequest(
method,
body,
qs,
url: `${baseUrl}${endpoint}`,
url: `${baseUrl.replace(/\/$/, '')}${endpoint}`,
json: true,
skipSslCertificateValidation: ignoreSSLIssues,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { type IExecuteFunctions, NodeApiError } from 'n8n-workflow';

import { elasticsearchApiRequest } from '../GenericFunctions';

describe('Elasticsearch -> elasticsearchApiRequest', () => {
let mockExecuteFunctions: IExecuteFunctions;

const mockHttpRequestWithAuthentication = jest.fn();

const setupMockFunctions = () => {
mockExecuteFunctions = {
getCredentials: jest.fn().mockResolvedValue({
baseUrl: 'https://example.com',
ignoreSSLIssues: false,
}),
helpers: {
httpRequestWithAuthentication: mockHttpRequestWithAuthentication,
},
getNode: jest.fn().mockReturnValue({}),
} as unknown as IExecuteFunctions;
jest.clearAllMocks();
};

beforeEach(() => {
setupMockFunctions();
mockHttpRequestWithAuthentication.mockClear();
});

const response = { success: true };

it('should make a successful GET API request', async () => {
mockHttpRequestWithAuthentication.mockResolvedValue(response);

const result = await elasticsearchApiRequest.call(
mockExecuteFunctions,
'GET',
'/test-endpoint',
);

expect(result).toEqual(response);
expect(mockExecuteFunctions.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith(
'elasticsearchApi',
expect.objectContaining({
method: 'GET',
url: 'https://example.com/test-endpoint',
json: true,
skipSslCertificateValidation: false,
}),
);
});

it('should make a successful POST API request', async () => {
const body = { key: 'value' };

mockHttpRequestWithAuthentication.mockResolvedValue(response);

const result = await elasticsearchApiRequest.call(
mockExecuteFunctions,
'POST',
'/test-endpoint',
body,
);

expect(result).toEqual(response);
expect(mockExecuteFunctions.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith(
'elasticsearchApi',
expect.objectContaining({
body,
method: 'POST',
url: 'https://example.com/test-endpoint',
json: true,
skipSslCertificateValidation: false,
}),
);
});

it('should handle API request errors', async () => {
const errorResponse = { message: 'Error occurred' };
mockHttpRequestWithAuthentication.mockRejectedValue(errorResponse);

await expect(
elasticsearchApiRequest.call(mockExecuteFunctions, 'GET', '/test-endpoint'),
).rejects.toThrow(NodeApiError);

expect(mockExecuteFunctions.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith(
'elasticsearchApi',
expect.objectContaining({
method: 'GET',
url: 'https://example.com/test-endpoint',
json: true,
skipSslCertificateValidation: false,
}),
);
});

it('should ignore trailing slashes in the base URL', async () => {
mockHttpRequestWithAuthentication.mockResolvedValue(response);

mockExecuteFunctions.getCredentials = jest.fn().mockResolvedValue({
baseUrl: 'https://elastic.domain.com/',
ignoreSSLIssues: false,
});
await elasticsearchApiRequest.call(mockExecuteFunctions, 'GET', '/test-endpoint');

expect(mockExecuteFunctions.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith(
'elasticsearchApi',
expect.objectContaining({
url: 'https://elastic.domain.com/test-endpoint',
}),
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import type {
} from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow';

import * as spreadsheet from './actions/spreadsheet.operation';
import * as moveTo from './actions/moveTo.operation';
import * as pdf from './actions/pdf.operation';
import * as spreadsheet from './actions/spreadsheet.operation';

export class ExtractFromFile implements INodeType {
// eslint-disable-next-line n8n-nodes-base/node-class-description-missing-subtitle
Expand Down
Loading

0 comments on commit b90ea5a

Please sign in to comment.