mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
refactor(core): Use mixins to delete redundant code between Entity classes (no-changelog) (#6616)
* db entities don't need an ID before they are inserted * don't define constructors on entity classes, use repository.create instead * use mixins to reduce duplicate code in db entity classes
This commit is contained in:
parent
e6903a87b5
commit
dc2ba743eb
|
@ -1,6 +1,13 @@
|
||||||
import { BeforeUpdate, CreateDateColumn, UpdateDateColumn } from 'typeorm';
|
import {
|
||||||
|
BeforeInsert,
|
||||||
|
BeforeUpdate,
|
||||||
|
CreateDateColumn,
|
||||||
|
PrimaryColumn,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from 'typeorm';
|
||||||
import { IsDate, IsOptional } from 'class-validator';
|
import { IsDate, IsOptional } from 'class-validator';
|
||||||
import config from '@/config';
|
import config from '@/config';
|
||||||
|
import { generateNanoId } from '../utils/generators';
|
||||||
|
|
||||||
const dbType = config.getEnv('database.type');
|
const dbType = config.getEnv('database.type');
|
||||||
|
|
||||||
|
@ -14,18 +21,37 @@ const timestampSyntax = {
|
||||||
export const jsonColumnType = dbType === 'sqlite' ? 'simple-json' : 'json';
|
export const jsonColumnType = dbType === 'sqlite' ? 'simple-json' : 'json';
|
||||||
export const datetimeColumnType = dbType === 'postgresdb' ? 'timestamptz' : 'datetime';
|
export const datetimeColumnType = dbType === 'postgresdb' ? 'timestamptz' : 'datetime';
|
||||||
|
|
||||||
export abstract class AbstractEntity {
|
const tsColumnOptions = {
|
||||||
@CreateDateColumn({
|
|
||||||
precision: 3,
|
precision: 3,
|
||||||
default: () => timestampSyntax,
|
default: () => timestampSyntax,
|
||||||
})
|
};
|
||||||
|
|
||||||
|
type Constructor<T> = new (...args: any[]) => T;
|
||||||
|
|
||||||
|
function mixinStringId<T extends Constructor<{}>>(base: T) {
|
||||||
|
class Derived extends base {
|
||||||
|
@PrimaryColumn('varchar')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@BeforeInsert()
|
||||||
|
generateId() {
|
||||||
|
if (!this.id) {
|
||||||
|
this.id = generateNanoId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Derived;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mixinTimestamps<T extends Constructor<{}>>(base: T) {
|
||||||
|
class Derived extends base {
|
||||||
|
@CreateDateColumn(tsColumnOptions)
|
||||||
@IsOptional() // ignored by validation because set at DB level
|
@IsOptional() // ignored by validation because set at DB level
|
||||||
@IsDate()
|
@IsDate()
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({
|
@UpdateDateColumn({
|
||||||
precision: 3,
|
...tsColumnOptions,
|
||||||
default: () => timestampSyntax,
|
|
||||||
onUpdate: timestampSyntax,
|
onUpdate: timestampSyntax,
|
||||||
})
|
})
|
||||||
@IsOptional() // ignored by validation because set at DB level
|
@IsOptional() // ignored by validation because set at DB level
|
||||||
|
@ -36,4 +62,12 @@ export abstract class AbstractEntity {
|
||||||
setUpdateDate(): void {
|
setUpdateDate(): void {
|
||||||
this.updatedAt = new Date();
|
this.updatedAt = new Date();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return Derived;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BaseEntity {}
|
||||||
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
|
export const WithStringId = mixinStringId(BaseEntity);
|
||||||
|
export const WithTimestamps = mixinTimestamps(BaseEntity);
|
||||||
|
export const WithTimestampsAndStringId = mixinStringId(WithTimestamps);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { Column, Entity, ManyToOne, PrimaryColumn, Unique } from 'typeorm';
|
import { Column, Entity, ManyToOne, PrimaryColumn, Unique } from 'typeorm';
|
||||||
import { AbstractEntity } from './AbstractEntity';
|
import { WithTimestamps } from './AbstractEntity';
|
||||||
import { User } from './User';
|
import { User } from './User';
|
||||||
|
|
||||||
export type AuthProviderType = 'ldap' | 'email' | 'saml'; // | 'google';
|
export type AuthProviderType = 'ldap' | 'email' | 'saml'; // | 'google';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@Unique(['providerId', 'providerType'])
|
@Unique(['providerId', 'providerType'])
|
||||||
export class AuthIdentity extends AbstractEntity {
|
export class AuthIdentity extends WithTimestamps {
|
||||||
@Column()
|
@Column()
|
||||||
userId: string;
|
userId: string;
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,12 @@
|
||||||
import type { ICredentialNodeAccess } from 'n8n-workflow';
|
import type { ICredentialNodeAccess } from 'n8n-workflow';
|
||||||
import { BeforeInsert, Column, Entity, Index, OneToMany, PrimaryColumn } from 'typeorm';
|
import { Column, Entity, Index, OneToMany } from 'typeorm';
|
||||||
import { IsArray, IsObject, IsString, Length } from 'class-validator';
|
import { IsArray, IsObject, IsString, Length } from 'class-validator';
|
||||||
import type { SharedCredentials } from './SharedCredentials';
|
import type { SharedCredentials } from './SharedCredentials';
|
||||||
import { AbstractEntity, jsonColumnType } from './AbstractEntity';
|
import { WithTimestampsAndStringId, jsonColumnType } from './AbstractEntity';
|
||||||
import type { ICredentialsDb } from '@/Interfaces';
|
import type { ICredentialsDb } from '@/Interfaces';
|
||||||
import { generateNanoId } from '../utils/generators';
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class CredentialsEntity extends AbstractEntity implements ICredentialsDb {
|
export class CredentialsEntity extends WithTimestampsAndStringId implements ICredentialsDb {
|
||||||
constructor(data?: Partial<CredentialsEntity>) {
|
|
||||||
super();
|
|
||||||
Object.assign(this, data);
|
|
||||||
if (!this.id) {
|
|
||||||
this.id = generateNanoId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeInsert()
|
|
||||||
nanoId(): void {
|
|
||||||
if (!this.id) {
|
|
||||||
this.id = generateNanoId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PrimaryColumn('varchar')
|
|
||||||
id: string;
|
|
||||||
|
|
||||||
@Column({ length: 128 })
|
@Column({ length: 128 })
|
||||||
@IsString({ message: 'Credential `name` must be of type string.' })
|
@IsString({ message: 'Credential `name` must be of type string.' })
|
||||||
@Length(3, 128, {
|
@Length(3, 128, {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { MessageEventBusDestinationOptions } from 'n8n-workflow';
|
import { MessageEventBusDestinationOptions } from 'n8n-workflow';
|
||||||
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||||
import { AbstractEntity, jsonColumnType } from './AbstractEntity';
|
import { WithTimestamps, jsonColumnType } from './AbstractEntity';
|
||||||
|
|
||||||
@Entity({ name: 'event_destinations' })
|
@Entity({ name: 'event_destinations' })
|
||||||
export class EventDestinations extends AbstractEntity {
|
export class EventDestinations extends WithTimestamps {
|
||||||
@PrimaryColumn('uuid')
|
@PrimaryColumn('uuid')
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Column, Entity, JoinColumn, OneToMany, PrimaryColumn } from 'typeorm';
|
import { Column, Entity, JoinColumn, OneToMany, PrimaryColumn } from 'typeorm';
|
||||||
import type { InstalledNodes } from './InstalledNodes';
|
import type { InstalledNodes } from './InstalledNodes';
|
||||||
import { AbstractEntity } from './AbstractEntity';
|
import { WithTimestamps } from './AbstractEntity';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class InstalledPackages extends AbstractEntity {
|
export class InstalledPackages extends WithTimestamps {
|
||||||
@PrimaryColumn()
|
@PrimaryColumn()
|
||||||
packageName: string;
|
packageName: string;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { IsString, Length } from 'class-validator';
|
||||||
import type { User } from './User';
|
import type { User } from './User';
|
||||||
import type { SharedWorkflow } from './SharedWorkflow';
|
import type { SharedWorkflow } from './SharedWorkflow';
|
||||||
import type { SharedCredentials } from './SharedCredentials';
|
import type { SharedCredentials } from './SharedCredentials';
|
||||||
import { AbstractEntity } from './AbstractEntity';
|
import { WithTimestamps } from './AbstractEntity';
|
||||||
import { idStringifier } from '../utils/transformers';
|
import { idStringifier } from '../utils/transformers';
|
||||||
|
|
||||||
export type RoleNames = 'owner' | 'member' | 'user' | 'editor';
|
export type RoleNames = 'owner' | 'member' | 'user' | 'editor';
|
||||||
|
@ -12,7 +12,7 @@ export type RoleScopes = 'global' | 'workflow' | 'credential';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@Unique(['scope', 'name'])
|
@Unique(['scope', 'name'])
|
||||||
export class Role extends AbstractEntity {
|
export class Role extends WithTimestamps {
|
||||||
@PrimaryColumn({ transformer: idStringifier })
|
@PrimaryColumn({ transformer: idStringifier })
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@ import { Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||||
import { CredentialsEntity } from './CredentialsEntity';
|
import { CredentialsEntity } from './CredentialsEntity';
|
||||||
import { User } from './User';
|
import { User } from './User';
|
||||||
import { Role } from './Role';
|
import { Role } from './Role';
|
||||||
import { AbstractEntity } from './AbstractEntity';
|
import { WithTimestamps } from './AbstractEntity';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class SharedCredentials extends AbstractEntity {
|
export class SharedCredentials extends WithTimestamps {
|
||||||
@ManyToOne('Role', 'sharedCredentials', { nullable: false })
|
@ManyToOne('Role', 'sharedCredentials', { nullable: false })
|
||||||
role: Role;
|
role: Role;
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@ import { Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||||
import { WorkflowEntity } from './WorkflowEntity';
|
import { WorkflowEntity } from './WorkflowEntity';
|
||||||
import { User } from './User';
|
import { User } from './User';
|
||||||
import { Role } from './Role';
|
import { Role } from './Role';
|
||||||
import { AbstractEntity } from './AbstractEntity';
|
import { WithTimestamps } from './AbstractEntity';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class SharedWorkflow extends AbstractEntity {
|
export class SharedWorkflow extends WithTimestamps {
|
||||||
@ManyToOne('Role', 'sharedWorkflows', { nullable: false })
|
@ManyToOne('Role', 'sharedWorkflows', { nullable: false })
|
||||||
role: Role;
|
role: Role;
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,11 @@
|
||||||
import { BeforeInsert, Column, Entity, Index, ManyToMany, OneToMany, PrimaryColumn } from 'typeorm';
|
import { Column, Entity, Index, ManyToMany, OneToMany } from 'typeorm';
|
||||||
import { IsString, Length } from 'class-validator';
|
import { IsString, Length } from 'class-validator';
|
||||||
import type { WorkflowEntity } from './WorkflowEntity';
|
import type { WorkflowEntity } from './WorkflowEntity';
|
||||||
import type { WorkflowTagMapping } from './WorkflowTagMapping';
|
import type { WorkflowTagMapping } from './WorkflowTagMapping';
|
||||||
import { AbstractEntity } from './AbstractEntity';
|
import { WithTimestampsAndStringId } from './AbstractEntity';
|
||||||
import { generateNanoId } from '../utils/generators';
|
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class TagEntity extends AbstractEntity {
|
export class TagEntity extends WithTimestampsAndStringId {
|
||||||
constructor(data?: Partial<TagEntity>) {
|
|
||||||
super();
|
|
||||||
Object.assign(this, data);
|
|
||||||
if (!this.id) {
|
|
||||||
this.id = generateNanoId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeInsert()
|
|
||||||
nanoId() {
|
|
||||||
if (!this.id) {
|
|
||||||
this.id = generateNanoId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PrimaryColumn('varchar')
|
|
||||||
id: string;
|
|
||||||
|
|
||||||
@Column({ length: 24 })
|
@Column({ length: 24 })
|
||||||
@Index({ unique: true })
|
@Index({ unique: true })
|
||||||
@IsString({ message: 'Tag name must be of type string.' })
|
@IsString({ message: 'Tag name must be of type string.' })
|
||||||
|
|
|
@ -17,7 +17,7 @@ import type { SharedWorkflow } from './SharedWorkflow';
|
||||||
import type { SharedCredentials } from './SharedCredentials';
|
import type { SharedCredentials } from './SharedCredentials';
|
||||||
import { NoXss } from '../utils/customValidators';
|
import { NoXss } from '../utils/customValidators';
|
||||||
import { objectRetriever, lowerCaser } from '../utils/transformers';
|
import { objectRetriever, lowerCaser } from '../utils/transformers';
|
||||||
import { AbstractEntity, jsonColumnType } from './AbstractEntity';
|
import { WithTimestamps, jsonColumnType } from './AbstractEntity';
|
||||||
import type { IPersonalizationSurveyAnswers } from '@/Interfaces';
|
import type { IPersonalizationSurveyAnswers } from '@/Interfaces';
|
||||||
import type { AuthIdentity } from './AuthIdentity';
|
import type { AuthIdentity } from './AuthIdentity';
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ export const MIN_PASSWORD_LENGTH = 8;
|
||||||
export const MAX_PASSWORD_LENGTH = 64;
|
export const MAX_PASSWORD_LENGTH = 64;
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class User extends AbstractEntity implements IUser {
|
export class User extends WithTimestamps implements IUser {
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,8 @@
|
||||||
import { BeforeInsert, Column, Entity, PrimaryColumn } from 'typeorm';
|
import { Column, Entity } from 'typeorm';
|
||||||
import { generateNanoId } from '../utils/generators';
|
import { WithStringId } from './AbstractEntity';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class Variables {
|
export class Variables extends WithStringId {
|
||||||
constructor(data?: Partial<Variables>) {
|
|
||||||
Object.assign(this, data);
|
|
||||||
if (!this.id) {
|
|
||||||
this.id = generateNanoId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeInsert()
|
|
||||||
nanoId() {
|
|
||||||
if (!this.id) {
|
|
||||||
this.id = generateNanoId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PrimaryColumn('varchar')
|
|
||||||
id: string;
|
|
||||||
|
|
||||||
@Column('text')
|
@Column('text')
|
||||||
key: string;
|
key: string;
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,7 @@ import { Length } from 'class-validator';
|
||||||
import { IConnections, IDataObject, IWorkflowSettings } from 'n8n-workflow';
|
import { IConnections, IDataObject, IWorkflowSettings } from 'n8n-workflow';
|
||||||
import type { IBinaryKeyData, INode, IPairedItemData } from 'n8n-workflow';
|
import type { IBinaryKeyData, INode, IPairedItemData } from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import { Column, Entity, Index, JoinColumn, JoinTable, ManyToMany, OneToMany } from 'typeorm';
|
||||||
BeforeInsert,
|
|
||||||
Column,
|
|
||||||
Entity,
|
|
||||||
Index,
|
|
||||||
JoinColumn,
|
|
||||||
JoinTable,
|
|
||||||
ManyToMany,
|
|
||||||
OneToMany,
|
|
||||||
PrimaryColumn,
|
|
||||||
} from 'typeorm';
|
|
||||||
|
|
||||||
import config from '@/config';
|
import config from '@/config';
|
||||||
import type { TagEntity } from './TagEntity';
|
import type { TagEntity } from './TagEntity';
|
||||||
|
@ -21,30 +11,11 @@ import type { SharedWorkflow } from './SharedWorkflow';
|
||||||
import type { WorkflowStatistics } from './WorkflowStatistics';
|
import type { WorkflowStatistics } from './WorkflowStatistics';
|
||||||
import type { WorkflowTagMapping } from './WorkflowTagMapping';
|
import type { WorkflowTagMapping } from './WorkflowTagMapping';
|
||||||
import { objectRetriever, sqlite } from '../utils/transformers';
|
import { objectRetriever, sqlite } from '../utils/transformers';
|
||||||
import { AbstractEntity, jsonColumnType } from './AbstractEntity';
|
import { WithTimestampsAndStringId, jsonColumnType } from './AbstractEntity';
|
||||||
import type { IWorkflowDb } from '@/Interfaces';
|
import type { IWorkflowDb } from '@/Interfaces';
|
||||||
import { generateNanoId } from '../utils/generators';
|
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class WorkflowEntity extends AbstractEntity implements IWorkflowDb {
|
export class WorkflowEntity extends WithTimestampsAndStringId implements IWorkflowDb {
|
||||||
constructor(data?: Partial<WorkflowEntity>) {
|
|
||||||
super();
|
|
||||||
Object.assign(this, data);
|
|
||||||
if (!this.id) {
|
|
||||||
this.id = generateNanoId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeInsert()
|
|
||||||
nanoId() {
|
|
||||||
if (!this.id) {
|
|
||||||
this.id = generateNanoId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PrimaryColumn('varchar')
|
|
||||||
id: string;
|
|
||||||
|
|
||||||
// TODO: Add XSS check
|
// TODO: Add XSS check
|
||||||
@Index({ unique: true })
|
@Index({ unique: true })
|
||||||
@Length(1, 128, {
|
@Length(1, 128, {
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { readFile as fsReadFile } from 'fs/promises';
|
||||||
import { Credentials, UserSettings } from 'n8n-core';
|
import { Credentials, UserSettings } from 'n8n-core';
|
||||||
import type { IWorkflowToImport } from '@/Interfaces';
|
import type { IWorkflowToImport } from '@/Interfaces';
|
||||||
import type { ExportableCredential } from './types/exportableCredential';
|
import type { ExportableCredential } from './types/exportableCredential';
|
||||||
import { Variables } from '@db/entities/Variables';
|
import type { Variables } from '@db/entities/Variables';
|
||||||
import { UM_FIX_INSTRUCTION } from '@/commands/BaseCommand';
|
import { UM_FIX_INSTRUCTION } from '@/commands/BaseCommand';
|
||||||
import { SharedCredentials } from '@db/entities/SharedCredentials';
|
import { SharedCredentials } from '@db/entities/SharedCredentials';
|
||||||
import type { WorkflowTagMapping } from '@db/entities/WorkflowTagMapping';
|
import type { WorkflowTagMapping } from '@db/entities/WorkflowTagMapping';
|
||||||
|
@ -576,7 +576,7 @@ export class SourceControlImportService {
|
||||||
if (overriddenKeys.length > 0 && valueOverrides) {
|
if (overriddenKeys.length > 0 && valueOverrides) {
|
||||||
for (const key of overriddenKeys) {
|
for (const key of overriddenKeys) {
|
||||||
result.imported.push(key);
|
result.imported.push(key);
|
||||||
const newVariable = new Variables({ key, value: valueOverrides[key] });
|
const newVariable = Db.collections.Variables.create({ key, value: valueOverrides[key] });
|
||||||
await Db.collections.Variables.save(newVariable);
|
await Db.collections.Variables.save(newVariable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { audit } from '@/audit';
|
||||||
import { FILESYSTEM_INTERACTION_NODE_TYPES, FILESYSTEM_REPORT } from '@/audit/constants';
|
import { FILESYSTEM_INTERACTION_NODE_TYPES, FILESYSTEM_REPORT } from '@/audit/constants';
|
||||||
import { getRiskSection, saveManualTriggerWorkflow } from './utils';
|
import { getRiskSection, saveManualTriggerWorkflow } from './utils';
|
||||||
import * as testDb from '../shared/testDb';
|
import * as testDb from '../shared/testDb';
|
||||||
import { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await testDb.init();
|
await testDb.init();
|
||||||
|
@ -27,7 +26,7 @@ test('should report filesystem interaction nodes', async () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const promises = Object.entries(map).map(async ([nodeType, nodeId]) => {
|
const promises = Object.entries(map).map(async ([nodeType, nodeId]) => {
|
||||||
const details = new WorkflowEntity({
|
const details = Db.collections.Workflow.create({
|
||||||
name: 'My Test Workflow',
|
name: 'My Test Workflow',
|
||||||
active: false,
|
active: false,
|
||||||
connections: {},
|
connections: {},
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { toReportTitle } from '@/audit/utils';
|
||||||
import { mockInstance } from '../shared/utils/';
|
import { mockInstance } from '../shared/utils/';
|
||||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||||
import { NodeTypes } from '@/NodeTypes';
|
import { NodeTypes } from '@/NodeTypes';
|
||||||
import { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
|
||||||
|
|
||||||
const nodesAndCredentials = mockInstance(LoadNodesAndCredentials);
|
const nodesAndCredentials = mockInstance(LoadNodesAndCredentials);
|
||||||
nodesAndCredentials.getCustomDirectories.mockReturnValue([]);
|
nodesAndCredentials.getCustomDirectories.mockReturnValue([]);
|
||||||
|
@ -33,7 +32,7 @@ test('should report risky official nodes', async () => {
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const promises = Object.entries(map).map(async ([nodeType, nodeId]) => {
|
const promises = Object.entries(map).map(async ([nodeType, nodeId]) => {
|
||||||
const details = new WorkflowEntity({
|
const details = Db.collections.Workflow.create({
|
||||||
name: 'My Test Workflow',
|
name: 'My Test Workflow',
|
||||||
active: false,
|
active: false,
|
||||||
connections: {},
|
connections: {},
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { InstalledPackages } from '@db/entities/InstalledPackages';
|
||||||
import type { Role } from '@db/entities/Role';
|
import type { Role } from '@db/entities/Role';
|
||||||
import type { TagEntity } from '@db/entities/TagEntity';
|
import type { TagEntity } from '@db/entities/TagEntity';
|
||||||
import type { User } from '@db/entities/User';
|
import type { User } from '@db/entities/User';
|
||||||
import { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
||||||
import { RoleRepository } from '@db/repositories';
|
import { RoleRepository } from '@db/repositories';
|
||||||
import type { ICredentialsDb } from '@/Interfaces';
|
import type { ICredentialsDb } from '@/Interfaces';
|
||||||
|
|
||||||
|
@ -412,7 +412,7 @@ export async function createManyWorkflows(
|
||||||
export async function createWorkflow(attributes: Partial<WorkflowEntity> = {}, user?: User) {
|
export async function createWorkflow(attributes: Partial<WorkflowEntity> = {}, user?: User) {
|
||||||
const { active, name, nodes, connections } = attributes;
|
const { active, name, nodes, connections } = attributes;
|
||||||
|
|
||||||
const workflowEntity = new WorkflowEntity({
|
const workflowEntity = Db.collections.Workflow.create({
|
||||||
active: active ?? false,
|
active: active ?? false,
|
||||||
name: name ?? 'test workflow',
|
name: name ?? 'test workflow',
|
||||||
nodes: nodes ?? [
|
nodes: nodes ?? [
|
||||||
|
|
Loading…
Reference in a new issue