mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
feat(core): Add support to import/export tags (#3130)
* Export and Import Workflow Tags Support exporting and importing tags of workflows via frontend and cli. On export, all tag data is included in the json. - id - name - updatedAt - createdAt When importing a workflow json to n8n we: - first check if a tag with the same id and createdAt date exists in the database, then we can assume the tag is identical. Changes on the name of the tag are now preserved. - check if a tag with the same name exists on the database. - create a new tag with the given name. * clean up fe export * remove usage count * return updatedat, createdat * fix tags import * move logic from workflow package * refactor import * check for tags before import * update checks on type * fix on import * fix build issues * fix type issue * remove unnessary ? * update tag helpers so only name is required * fix tag import * add don't replace existing tags * fix build issue * address comments * fix with promise.all * update setting tags * update check * fix existing check * add helper * fix duplication * fix multiple same tags bug * fix db bugs * add more validation on workflow type * fix validation * disable importing tags on copy paste Co-authored-by: Luca Berneking <l.berneking@mittwald.de>
This commit is contained in:
@@ -17,15 +17,34 @@ import glob from 'fast-glob';
|
||||
import { UserSettings } from 'n8n-core';
|
||||
import { EntityManager, getConnection } from 'typeorm';
|
||||
import { getLogger } from '../../src/Logger';
|
||||
import { Db, ICredentialsDb } from '../../src';
|
||||
import { Db, ICredentialsDb, IWorkflowToImport } from '../../src';
|
||||
import { SharedWorkflow } from '../../src/databases/entities/SharedWorkflow';
|
||||
import { WorkflowEntity } from '../../src/databases/entities/WorkflowEntity';
|
||||
import { Role } from '../../src/databases/entities/Role';
|
||||
import { User } from '../../src/databases/entities/User';
|
||||
import { setTagsForImport } from '../../src/TagHelpers';
|
||||
|
||||
const FIX_INSTRUCTION =
|
||||
'Please fix the database by running ./packages/cli/bin/n8n user-management:reset';
|
||||
|
||||
function assertHasWorkflowsToImport(workflows: unknown): asserts workflows is IWorkflowToImport[] {
|
||||
if (!Array.isArray(workflows)) {
|
||||
throw new Error(
|
||||
'File does not seem to contain workflows. Make sure the workflows are contained in an array.',
|
||||
);
|
||||
}
|
||||
|
||||
for (const workflow of workflows) {
|
||||
if (
|
||||
typeof workflow !== 'object' ||
|
||||
!Object.prototype.hasOwnProperty.call(workflow, 'nodes') ||
|
||||
!Object.prototype.hasOwnProperty.call(workflow, 'connections')
|
||||
) {
|
||||
throw new Error('File does not seem to contain valid workflows.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ImportWorkflowsCommand extends Command {
|
||||
static description = 'Import workflows';
|
||||
|
||||
@@ -82,7 +101,8 @@ export class ImportWorkflowsCommand extends Command {
|
||||
|
||||
// Make sure the settings exist
|
||||
await UserSettings.prepareUserSettings();
|
||||
const credentials = (await Db.collections.Credentials.find()) ?? [];
|
||||
const credentials = await Db.collections.Credentials.find();
|
||||
const tags = await Db.collections.Tag.find();
|
||||
|
||||
let totalImported = 0;
|
||||
|
||||
@@ -111,6 +131,10 @@ export class ImportWorkflowsCommand extends Command {
|
||||
});
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(workflow, 'tags')) {
|
||||
await setTagsForImport(transactionManager, workflow, tags);
|
||||
}
|
||||
|
||||
await this.storeWorkflow(workflow, user);
|
||||
}
|
||||
});
|
||||
@@ -121,13 +145,9 @@ export class ImportWorkflowsCommand extends Command {
|
||||
|
||||
const workflows = JSON.parse(fs.readFileSync(flags.input, { encoding: 'utf8' }));
|
||||
|
||||
totalImported = workflows.length;
|
||||
assertHasWorkflowsToImport(workflows);
|
||||
|
||||
if (!Array.isArray(workflows)) {
|
||||
throw new Error(
|
||||
'File does not seem to contain workflows. Make sure the workflows are contained in an array.',
|
||||
);
|
||||
}
|
||||
totalImported = workflows.length;
|
||||
|
||||
await getConnection().transaction(async (transactionManager) => {
|
||||
this.transactionManager = transactionManager;
|
||||
@@ -139,6 +159,10 @@ export class ImportWorkflowsCommand extends Command {
|
||||
});
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(workflow, 'tags')) {
|
||||
await setTagsForImport(transactionManager, workflow, tags);
|
||||
}
|
||||
|
||||
await this.storeWorkflow(workflow, user);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user