first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled

This commit is contained in:
2026-03-17 16:22:57 +03:30
commit 3d5eaf9445
15349 changed files with 2847338 additions and 0 deletions
@@ -0,0 +1,63 @@
import type {
IDataObject,
IExecuteFunctions,
IHttpRequestMethods,
ILoadOptionsFunctions,
} from 'n8n-workflow';
type RequestParameters = {
headers?: IDataObject;
body?: IDataObject | string;
qs?: IDataObject;
uri?: string;
option?: IDataObject;
};
export async function apiRequest(
this: IExecuteFunctions | ILoadOptionsFunctions,
method: IHttpRequestMethods,
endpoint: string,
parameters?: RequestParameters,
) {
const { body, qs, option } = parameters ?? {};
const credentials = await this.getCredentials('openAiApi');
let uri = `https://api.openai.com/v1${endpoint}`;
let headers = parameters?.headers ?? {};
if (credentials.url) {
uri = `${credentials?.url}${endpoint}`;
}
if (
credentials.header &&
typeof credentials.headerName === 'string' &&
credentials.headerName &&
typeof credentials.headerValue === 'string'
) {
headers = {
...headers,
[credentials.headerName]: credentials.headerValue,
};
}
const options = {
headers,
method,
body,
qs,
uri,
json: true,
};
if (option && Object.keys(option).length !== 0) {
Object.assign(options, option);
}
const response = await this.helpers.requestWithAuthentication.call(this, 'openAiApi', options);
if (response && response.error === null) {
response.error = undefined;
}
return response;
}
@@ -0,0 +1,81 @@
import type { IExecuteFunctions } from 'n8n-workflow';
import { apiRequest } from '../index';
const mockedExecutionContext = {
getCredentials: jest.fn(),
helpers: {
requestWithAuthentication: jest.fn(),
},
};
describe('apiRequest', () => {
beforeEach(() => {
jest.resetAllMocks();
});
it('should call requestWithAuthentication with credentials URL if one is provided', async () => {
mockedExecutionContext.getCredentials.mockResolvedValue({
url: 'http://www.test/url/v1',
});
// Act
await apiRequest.call(mockedExecutionContext as unknown as IExecuteFunctions, 'GET', '/test', {
headers: { 'Content-Type': 'application/json' },
});
// Assert
expect(mockedExecutionContext.getCredentials).toHaveBeenCalledWith('openAiApi');
expect(mockedExecutionContext.helpers.requestWithAuthentication).toHaveBeenCalledWith(
'openAiApi',
{
headers: { 'Content-Type': 'application/json' },
method: 'GET',
uri: 'http://www.test/url/v1/test',
json: true,
},
);
});
it('should call requestWithAuthentication with default URL if credentials URL is not provided', async () => {
mockedExecutionContext.getCredentials.mockResolvedValue({});
// Act
await apiRequest.call(mockedExecutionContext as unknown as IExecuteFunctions, 'GET', '/test', {
headers: { 'Content-Type': 'application/json' },
});
// Assert
expect(mockedExecutionContext.getCredentials).toHaveBeenCalledWith('openAiApi');
expect(mockedExecutionContext.helpers.requestWithAuthentication).toHaveBeenCalledWith(
'openAiApi',
{
headers: { 'Content-Type': 'application/json' },
method: 'GET',
uri: 'https://api.openai.com/v1/test',
json: true,
},
);
});
it('should normalize error: null to error: undefined', async () => {
// Arrange
mockedExecutionContext.getCredentials.mockResolvedValue({});
mockedExecutionContext.helpers.requestWithAuthentication.mockResolvedValue({
id: 'test',
error: null,
});
// Act
const response = await apiRequest.call(
mockedExecutionContext as unknown as IExecuteFunctions,
'GET',
'/test',
);
// Assert
expect(response.error).toBeUndefined();
});
});