refactor: Use string ids on Credentials, Workflows, Tags, and Executions DB entities (#5041)
This commit is contained in:
committed by
GitHub
parent
8bee04cd2a
commit
ee28213538
@@ -1,14 +1,16 @@
|
||||
import type { ICredentialNodeAccess } from 'n8n-workflow';
|
||||
import { Column, Entity, Index, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { Column, Entity, Generated, Index, OneToMany, PrimaryColumn } from 'typeorm';
|
||||
import { IsArray, IsObject, IsString, Length } from 'class-validator';
|
||||
import type { SharedCredentials } from './SharedCredentials';
|
||||
import { AbstractEntity, jsonColumnType } from './AbstractEntity';
|
||||
import type { ICredentialsDb } from '@/Interfaces';
|
||||
import { idStringifier } from '../utils/transformers';
|
||||
|
||||
@Entity()
|
||||
export class CredentialsEntity extends AbstractEntity implements ICredentialsDb {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
@Generated()
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
id: string;
|
||||
|
||||
@Column({ length: 128 })
|
||||
@IsString({ message: 'Credential `name` must be of type string.' })
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import type { WorkflowExecuteMode } from 'n8n-workflow';
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { Column, Entity, Generated, Index, PrimaryColumn } from 'typeorm';
|
||||
import { datetimeColumnType, jsonColumnType } from './AbstractEntity';
|
||||
import type { IExecutionFlattedDb, IWorkflowDb } from '@/Interfaces';
|
||||
import { idStringifier } from '../utils/transformers';
|
||||
|
||||
@Entity()
|
||||
@Index(['workflowId', 'id'])
|
||||
@@ -10,8 +11,9 @@ import type { IExecutionFlattedDb, IWorkflowDb } from '@/Interfaces';
|
||||
@Index(['workflowId', 'finished', 'id'])
|
||||
@Index(['workflowId', 'waitTill', 'id'])
|
||||
export class ExecutionEntity implements IExecutionFlattedDb {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
@Generated()
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
id: string;
|
||||
|
||||
@Column('text')
|
||||
data: string;
|
||||
@@ -38,7 +40,7 @@ export class ExecutionEntity implements IExecutionFlattedDb {
|
||||
@Column(jsonColumnType)
|
||||
workflowData: IWorkflowDb;
|
||||
|
||||
@Column({ nullable: true })
|
||||
@Column({ nullable: true, transformer: idStringifier })
|
||||
workflowId: string;
|
||||
|
||||
@Column({ type: datetimeColumnType, nullable: true })
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { CredentialsEntity } from './CredentialsEntity';
|
||||
import type { User } from './User';
|
||||
import type { Role } from './Role';
|
||||
import { AbstractEntity } from './AbstractEntity';
|
||||
import { idStringifier } from '../utils/transformers';
|
||||
|
||||
@Entity()
|
||||
export class SharedCredentials extends AbstractEntity {
|
||||
@@ -22,7 +23,7 @@ export class SharedCredentials extends AbstractEntity {
|
||||
})
|
||||
credentials: CredentialsEntity;
|
||||
|
||||
@PrimaryColumn()
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
@RelationId((sharedCredential: SharedCredentials) => sharedCredential.credentials)
|
||||
credentialsId: number;
|
||||
credentialsId: string;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { WorkflowEntity } from './WorkflowEntity';
|
||||
import type { User } from './User';
|
||||
import type { Role } from './Role';
|
||||
import { AbstractEntity } from './AbstractEntity';
|
||||
import { idStringifier } from '../utils/transformers';
|
||||
|
||||
@Entity()
|
||||
export class SharedWorkflow extends AbstractEntity {
|
||||
@@ -22,7 +23,7 @@ export class SharedWorkflow extends AbstractEntity {
|
||||
})
|
||||
workflow: WorkflowEntity;
|
||||
|
||||
@PrimaryColumn()
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
@RelationId((sharedWorkflow: SharedWorkflow) => sharedWorkflow.workflow)
|
||||
workflowId: number;
|
||||
workflowId: string;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
import { Column, Entity, Generated, Index, ManyToMany, PrimaryColumn } from 'typeorm';
|
||||
import { IsString, Length } from 'class-validator';
|
||||
|
||||
import type { ITagDb } from '@/Interfaces';
|
||||
import { idStringifier } from '../utils/transformers';
|
||||
import type { WorkflowEntity } from './WorkflowEntity';
|
||||
import { AbstractEntity } from './AbstractEntity';
|
||||
|
||||
@Entity()
|
||||
export class TagEntity extends AbstractEntity implements ITagDb {
|
||||
export class TagEntity extends AbstractEntity {
|
||||
@Generated()
|
||||
@PrimaryColumn({
|
||||
transformer: idStringifier,
|
||||
})
|
||||
id: number;
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
id: string;
|
||||
|
||||
@Column({ length: 24 })
|
||||
@Index({ unique: true })
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
||||
|
||||
import { IWebhookDb } from '@/Interfaces';
|
||||
import { idStringifier } from '../utils/transformers';
|
||||
|
||||
@Entity()
|
||||
@Index(['webhookId', 'method', 'pathLength'])
|
||||
export class WebhookEntity implements IWebhookDb {
|
||||
@Column()
|
||||
workflowId: number;
|
||||
export class WebhookEntity {
|
||||
@Column({ transformer: idStringifier })
|
||||
workflowId: string;
|
||||
|
||||
@PrimaryColumn()
|
||||
webhookPath: string;
|
||||
@@ -18,8 +18,8 @@ export class WebhookEntity implements IWebhookDb {
|
||||
node: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
webhookId: string;
|
||||
webhookId?: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
pathLength: number;
|
||||
pathLength?: number;
|
||||
}
|
||||
|
||||
@@ -12,26 +12,28 @@ import type {
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Generated,
|
||||
Index,
|
||||
JoinColumn,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
OneToMany,
|
||||
PrimaryGeneratedColumn,
|
||||
PrimaryColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import config from '@/config';
|
||||
import type { TagEntity } from './TagEntity';
|
||||
import type { SharedWorkflow } from './SharedWorkflow';
|
||||
import type { WorkflowStatistics } from './WorkflowStatistics';
|
||||
import { objectRetriever, sqlite } from '../utils/transformers';
|
||||
import { idStringifier, objectRetriever, sqlite } from '../utils/transformers';
|
||||
import { AbstractEntity, jsonColumnType } from './AbstractEntity';
|
||||
import type { IWorkflowDb } from '@/Interfaces';
|
||||
|
||||
@Entity()
|
||||
export class WorkflowEntity extends AbstractEntity implements IWorkflowDb {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
@Generated()
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
id: string;
|
||||
|
||||
// TODO: Add XSS check
|
||||
@Index({ unique: true })
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Column, Entity, RelationId, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||
import { idStringifier } from '../utils/transformers';
|
||||
import { datetimeColumnType } from './AbstractEntity';
|
||||
import type { WorkflowEntity } from './WorkflowEntity';
|
||||
|
||||
@@ -26,7 +27,7 @@ export class WorkflowStatistics {
|
||||
})
|
||||
workflow: WorkflowEntity;
|
||||
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
@RelationId((workflowStatistics: WorkflowStatistics) => workflowStatistics.workflow)
|
||||
@PrimaryColumn()
|
||||
workflowId: number;
|
||||
workflowId: string;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ export class UpdateWorkflowCredentials1630451444017 implements MigrationInterfac
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id.toString() || null, name };
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
@@ -79,7 +79,7 @@ export class UpdateWorkflowCredentials1630451444017 implements MigrationInterfac
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id.toString() || null, name };
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
@@ -123,7 +123,7 @@ export class UpdateWorkflowCredentials1630451444017 implements MigrationInterfac
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id.toString() || null, name };
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ export class UpdateWorkflowCredentials1630419189837 implements MigrationInterfac
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id.toString() || null, name };
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ export class UpdateWorkflowCredentials1630419189837 implements MigrationInterfac
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id.toString() || null, name };
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,7 @@ export class UpdateWorkflowCredentials1630419189837 implements MigrationInterfac
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id.toString() || null, name };
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export class UpdateWorkflowCredentials1630330987096 implements MigrationInterfac
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id.toString() || null, name };
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ export class UpdateWorkflowCredentials1630330987096 implements MigrationInterfac
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id.toString() || null, name };
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,7 @@ export class UpdateWorkflowCredentials1630330987096 implements MigrationInterfac
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id.toString() || null, name };
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { jsonParse } from 'n8n-workflow';
|
||||
import { ValueTransformer } from 'typeorm';
|
||||
import type { ValueTransformer, FindOperator } from 'typeorm';
|
||||
import config from '@/config';
|
||||
|
||||
export const idStringifier = {
|
||||
from: (value: number): string | number => (typeof value === 'number' ? value.toString() : value),
|
||||
to: (value: string): number | string => (typeof value === 'string' ? Number(value) : value),
|
||||
from: (value?: number): string | undefined => value?.toString(),
|
||||
to: (
|
||||
value: string | FindOperator<unknown> | undefined,
|
||||
): number | FindOperator<unknown> | undefined =>
|
||||
typeof value === 'string' ? Number(value) : value,
|
||||
};
|
||||
|
||||
export const lowerCaser = {
|
||||
|
||||
Reference in New Issue
Block a user