mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
refactor(core): Generalize binary data manager interface (no-changelog) (#7164)
Depends on: #7092 | Story: [PAY-768](https://linear.app/n8n/issue/PAY-768) This PR: - Generalizes the `IBinaryDataManager` interface. - Adjusts `Filesystem.ts` to satisfy the interface. - Sets up an S3 client stub to be filled in in the next PR. - Turns `BinaryDataManager` into an injectable service. - Adjusts the config schema and adds new validators. Note that the PR looks large but all the main changes are in `packages/core/src/binaryData`. Out of scope: - `BinaryDataManager` (now `BinaryDataService`) and `Filesystem.ts` (now `fs.client.ts`) were slightly refactored for maintainability, but fully overhauling them is **not** the focus of this PR, which is meant to clear the way for the S3 implementation. Future improvements for these two should include setting up a backwards-compatible dir structure that makes it easier to locate binary data files to delete, removing duplication, simplifying cloning methods, using integers for binary data size instead of `prettyBytes()`, writing tests for existing binary data logic, etc. --------- Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import nock from 'nock';
|
||||
import { getWorkflowFilenames, initBinaryDataManager, testWorkflows } from '@test/nodes/Helpers';
|
||||
import { getWorkflowFilenames, initBinaryDataService, testWorkflows } from '@test/nodes/Helpers';
|
||||
|
||||
const workflows = getWorkflowFilenames(__dirname);
|
||||
|
||||
@@ -11,7 +11,7 @@ describe('Test S3 V1 Node', () => {
|
||||
beforeAll(async () => {
|
||||
jest.useFakeTimers({ doNotFake: ['nextTick'], now });
|
||||
|
||||
await initBinaryDataManager();
|
||||
await initBinaryDataService();
|
||||
|
||||
nock.disableNetConnect();
|
||||
mock = nock('https://bucket.s3.eu-central-1.amazonaws.com');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import nock from 'nock';
|
||||
import { getWorkflowFilenames, initBinaryDataManager, testWorkflows } from '@test/nodes/Helpers';
|
||||
import { getWorkflowFilenames, initBinaryDataService, testWorkflows } from '@test/nodes/Helpers';
|
||||
|
||||
const workflows = getWorkflowFilenames(__dirname);
|
||||
|
||||
@@ -11,7 +11,7 @@ describe('Test S3 V2 Node', () => {
|
||||
beforeAll(async () => {
|
||||
jest.useFakeTimers({ doNotFake: ['nextTick'], now });
|
||||
|
||||
await initBinaryDataManager();
|
||||
await initBinaryDataService();
|
||||
|
||||
nock.disableNetConnect();
|
||||
mock = nock('https://bucket.s3.eu-central-1.amazonaws.com');
|
||||
|
||||
@@ -3,7 +3,7 @@ import { NodeVM } from '@n8n/vm2';
|
||||
import type { IExecuteFunctions, IWorkflowDataProxyData } from 'n8n-workflow';
|
||||
import { NodeHelpers } from 'n8n-workflow';
|
||||
import { normalizeItems } from 'n8n-core';
|
||||
import { testWorkflows, getWorkflowFilenames, initBinaryDataManager } from '@test/nodes/Helpers';
|
||||
import { testWorkflows, getWorkflowFilenames, initBinaryDataService } from '@test/nodes/Helpers';
|
||||
import { Code } from '../Code.node';
|
||||
import { ValidationError } from '../ValidationError';
|
||||
|
||||
@@ -11,7 +11,7 @@ describe('Test Code Node', () => {
|
||||
const workflows = getWorkflowFilenames(__dirname);
|
||||
|
||||
beforeAll(async () => {
|
||||
await initBinaryDataManager();
|
||||
await initBinaryDataService();
|
||||
});
|
||||
|
||||
testWorkflows(workflows);
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { IDataObject } from 'n8n-workflow';
|
||||
import {
|
||||
getResultNodeData,
|
||||
setup,
|
||||
initBinaryDataManager,
|
||||
initBinaryDataService,
|
||||
readJsonFileSync,
|
||||
} from '@test/nodes/Helpers';
|
||||
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
|
||||
@@ -16,7 +16,7 @@ import os from 'node:os';
|
||||
if (os.platform() !== 'win32') {
|
||||
describe('Execute Compression Node', () => {
|
||||
beforeEach(async () => {
|
||||
await initBinaryDataManager();
|
||||
await initBinaryDataService();
|
||||
});
|
||||
|
||||
const workflowData = readJsonFileSync('nodes/Compression/test/node/workflow.compression.json');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs';
|
||||
import fsPromises from 'fs/promises';
|
||||
import { Readable } from 'stream';
|
||||
import { testWorkflows, getWorkflowFilenames, initBinaryDataManager } from '@test/nodes/Helpers';
|
||||
import { testWorkflows, getWorkflowFilenames, initBinaryDataService } from '@test/nodes/Helpers';
|
||||
|
||||
const workflows = getWorkflowFilenames(__dirname);
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('Test Crypto Node', () => {
|
||||
fs.createReadStream = () => Readable.from(Buffer.from('test')) as fs.ReadStream;
|
||||
|
||||
beforeEach(async () => {
|
||||
await initBinaryDataManager();
|
||||
await initBinaryDataService();
|
||||
});
|
||||
|
||||
testWorkflows(workflows);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
equalityTest,
|
||||
workflowToTests,
|
||||
getWorkflowFilenames,
|
||||
initBinaryDataManager,
|
||||
initBinaryDataService,
|
||||
} from '@test/nodes/Helpers';
|
||||
|
||||
describe('Test Binary Data Download', () => {
|
||||
@@ -14,7 +14,7 @@ describe('Test Binary Data Download', () => {
|
||||
const baseUrl = 'https://dummy.domain';
|
||||
|
||||
beforeAll(async () => {
|
||||
await initBinaryDataManager();
|
||||
await initBinaryDataService();
|
||||
|
||||
nock.disableNetConnect();
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { setup, equalityTest, workflowToTests, getWorkflowFilenames } from '@test/nodes/Helpers';
|
||||
import {
|
||||
initBinaryDataService,
|
||||
setup,
|
||||
equalityTest,
|
||||
workflowToTests,
|
||||
getWorkflowFilenames,
|
||||
} from '@test/nodes/Helpers';
|
||||
|
||||
import nock from 'nock';
|
||||
|
||||
@@ -8,7 +14,8 @@ describe('Test HTTP Request Node', () => {
|
||||
|
||||
const baseUrl = 'https://dummyjson.com';
|
||||
|
||||
beforeAll(() => {
|
||||
beforeAll(async () => {
|
||||
await initBinaryDataService();
|
||||
nock.disableNetConnect();
|
||||
|
||||
//GET
|
||||
|
||||
@@ -5,13 +5,13 @@ import {
|
||||
getResultNodeData,
|
||||
setup,
|
||||
readJsonFileSync,
|
||||
initBinaryDataManager,
|
||||
initBinaryDataService,
|
||||
} from '@test/nodes/Helpers';
|
||||
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
|
||||
|
||||
describe('Execute iCalendar Node', () => {
|
||||
beforeEach(async () => {
|
||||
await initBinaryDataManager();
|
||||
await initBinaryDataService();
|
||||
});
|
||||
const workflowData = readJsonFileSync('nodes/ICalendar/test/node/workflow.iCalendar.json');
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import path from 'path';
|
||||
|
||||
describe('Test Move Binary Data Node', () => {
|
||||
beforeEach(async () => {
|
||||
await Helpers.initBinaryDataManager();
|
||||
await Helpers.initBinaryDataService();
|
||||
});
|
||||
|
||||
const workflow = Helpers.readJsonFileSync(
|
||||
|
||||
@@ -6,7 +6,7 @@ import nock from 'nock';
|
||||
|
||||
describe('Test QuickChart Node', () => {
|
||||
beforeEach(async () => {
|
||||
await Helpers.initBinaryDataManager();
|
||||
await Helpers.initBinaryDataService();
|
||||
nock.disableNetConnect();
|
||||
nock('https://quickchart.io')
|
||||
.persist()
|
||||
|
||||
@@ -6,7 +6,7 @@ import path from 'path';
|
||||
|
||||
describe('Test Read Binary File Node', () => {
|
||||
beforeEach(async () => {
|
||||
await Helpers.initBinaryDataManager();
|
||||
await Helpers.initBinaryDataService();
|
||||
});
|
||||
|
||||
const workflow = Helpers.readJsonFileSync(
|
||||
|
||||
@@ -6,7 +6,7 @@ import path from 'path';
|
||||
|
||||
describe('Test Read Binary Files Node', () => {
|
||||
beforeEach(async () => {
|
||||
await Helpers.initBinaryDataManager();
|
||||
await Helpers.initBinaryDataService();
|
||||
});
|
||||
|
||||
const workflow = Helpers.readJsonFileSync(
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { getWorkflowFilenames, initBinaryDataManager, testWorkflows } from '@test/nodes/Helpers';
|
||||
import { getWorkflowFilenames, initBinaryDataService, testWorkflows } from '@test/nodes/Helpers';
|
||||
|
||||
describe('Test Read PDF Node', () => {
|
||||
const workflows = getWorkflowFilenames(__dirname);
|
||||
|
||||
beforeAll(async () => {
|
||||
await initBinaryDataManager();
|
||||
await initBinaryDataService();
|
||||
});
|
||||
|
||||
testWorkflows(workflows);
|
||||
|
||||
@@ -6,7 +6,7 @@ import path from 'path';
|
||||
|
||||
describe('Execute Spreadsheet File Node', () => {
|
||||
beforeEach(async () => {
|
||||
await Helpers.initBinaryDataManager();
|
||||
await Helpers.initBinaryDataService();
|
||||
});
|
||||
|
||||
// replace workflow json 'Read Binary File' node's filePath to local file
|
||||
|
||||
@@ -6,7 +6,7 @@ import path from 'path';
|
||||
|
||||
describe('Test Write Binary File Node', () => {
|
||||
beforeEach(async () => {
|
||||
await Helpers.initBinaryDataManager();
|
||||
await Helpers.initBinaryDataService();
|
||||
});
|
||||
|
||||
const temporaryDir = Helpers.createTemporaryDir();
|
||||
|
||||
@@ -872,6 +872,7 @@
|
||||
"snowflake-sdk": "^1.8.0",
|
||||
"ssh2-sftp-client": "^7.0.0",
|
||||
"tmp-promise": "^3.0.2",
|
||||
"typedi": "^0.10.0",
|
||||
"uuid": "^8.3.2",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz",
|
||||
"xml2js": "^0.5.0"
|
||||
|
||||
@@ -3,7 +3,8 @@ import path from 'path';
|
||||
import { tmpdir } from 'os';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { get } from 'lodash';
|
||||
import { BinaryDataManager, Credentials, constructExecutionMetaData } from 'n8n-core';
|
||||
import { BinaryDataService, Credentials, constructExecutionMetaData } from 'n8n-core';
|
||||
import { Container } from 'typedi';
|
||||
import type {
|
||||
CredentialLoadingDetails,
|
||||
ICredentialDataDecryptedObject,
|
||||
@@ -216,14 +217,10 @@ export function createTemporaryDir(prefix = 'n8n') {
|
||||
return mkdtempSync(path.join(tmpdir(), prefix));
|
||||
}
|
||||
|
||||
export async function initBinaryDataManager(mode: 'default' | 'filesystem' = 'default') {
|
||||
const temporaryDir = createTemporaryDir();
|
||||
await BinaryDataManager.init({
|
||||
mode,
|
||||
availableModes: mode,
|
||||
localStoragePath: temporaryDir,
|
||||
});
|
||||
return temporaryDir;
|
||||
export async function initBinaryDataService(mode: 'default' | 'filesystem' = 'default') {
|
||||
const binaryDataService = new BinaryDataService();
|
||||
await binaryDataService.init({ mode: 'default', availableModes: [mode] });
|
||||
Container.set(BinaryDataService, binaryDataService);
|
||||
}
|
||||
|
||||
const credentialTypes = new CredentialType();
|
||||
|
||||
Reference in New Issue
Block a user