mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 09:36:44 +00:00
refactor(core): Move initial files to @n8n/db (#14953)
This commit is contained in:
@@ -21,6 +21,12 @@
|
||||
"dist/**/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"@n8n/config": "workspace:^",
|
||||
"@n8n/di": "workspace:^",
|
||||
"@n8n/typeorm": "catalog:",
|
||||
"n8n-core": "workspace:^",
|
||||
"n8n-workflow": "workspace:^",
|
||||
"nanoid": "catalog:",
|
||||
"reflect-metadata": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { ColumnOptions } from '@n8n/typeorm';
|
||||
import {
|
||||
BeforeInsert,
|
||||
BeforeUpdate,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
PrimaryColumn,
|
||||
UpdateDateColumn,
|
||||
@@ -24,12 +25,26 @@ const timestampSyntax = {
|
||||
export const jsonColumnType = dbType === 'sqlite' ? 'simple-json' : 'json';
|
||||
export const datetimeColumnType = dbType === 'postgresdb' ? 'timestamptz' : 'datetime';
|
||||
|
||||
export function JsonColumn(options?: Omit<ColumnOptions, 'type'>) {
|
||||
return Column({
|
||||
...options,
|
||||
type: jsonColumnType,
|
||||
});
|
||||
}
|
||||
|
||||
export function DateTimeColumn(options?: Omit<ColumnOptions, 'type'>) {
|
||||
return Column({
|
||||
...options,
|
||||
type: datetimeColumnType,
|
||||
});
|
||||
}
|
||||
const tsColumnOptions: ColumnOptions = {
|
||||
precision: 3,
|
||||
default: () => timestampSyntax,
|
||||
type: datetimeColumnType,
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function mixinStringId<T extends Class<{}, any[]>>(base: T) {
|
||||
class Derived extends base {
|
||||
@PrimaryColumn('varchar')
|
||||
@@ -45,6 +60,7 @@ function mixinStringId<T extends Class<{}, any[]>>(base: T) {
|
||||
return Derived;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function mixinTimestamps<T extends Class<{}, any[]>>(base: T) {
|
||||
class Derived extends base {
|
||||
@CreateDateColumn(tsColumnOptions)
|
||||
@@ -1 +1,14 @@
|
||||
export {};
|
||||
export {
|
||||
WithStringId,
|
||||
WithTimestamps,
|
||||
WithTimestampsAndStringId,
|
||||
jsonColumnType,
|
||||
datetimeColumnType,
|
||||
dbType,
|
||||
JsonColumn,
|
||||
DateTimeColumn,
|
||||
} from './entities/abstract-entity';
|
||||
|
||||
export { generateNanoId } from './utils/generators';
|
||||
export { isStringArray } from './utils/is-string-array';
|
||||
export { separate } from './utils/separate';
|
||||
|
||||
3
packages/@n8n/db/src/utils/is-string-array.ts
Normal file
3
packages/@n8n/db/src/utils/is-string-array.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export function isStringArray(value: unknown): value is string[] {
|
||||
return Array.isArray(value) && value.every((item) => typeof item === 'string');
|
||||
}
|
||||
8
packages/@n8n/db/src/utils/separate.ts
Normal file
8
packages/@n8n/db/src/utils/separate.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export const separate = <T>(array: T[], test: (element: T) => boolean) => {
|
||||
const pass: T[] = [];
|
||||
const fail: T[] = [];
|
||||
|
||||
array.forEach((i) => (test(i) ? pass : fail).push(i));
|
||||
|
||||
return [pass, fail];
|
||||
};
|
||||
@@ -6,7 +6,10 @@
|
||||
"baseUrl": "src",
|
||||
"tsBuildInfoFile": "dist/typecheck.tsbuildinfo",
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true
|
||||
"emitDecoratorMetadata": true,
|
||||
|
||||
// remove all options below this line
|
||||
"strictPropertyInitialization": false
|
||||
},
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
"@n8n/permissions": "workspace:*",
|
||||
"@n8n/task-runner": "workspace:*",
|
||||
"@n8n/ai-workflow-builder": "workspace:*",
|
||||
"@n8n/typeorm": "0.3.20-12",
|
||||
"@n8n/typeorm": "catalog:",
|
||||
"@n8n_io/ai-assistant-sdk": "catalog:",
|
||||
"@n8n_io/license-sdk": "2.20.0",
|
||||
"@oclif/core": "4.0.7",
|
||||
|
||||
@@ -13,16 +13,12 @@ import type PCancelable from 'p-cancelable';
|
||||
|
||||
import { ExecutionRepository } from '@/databases/repositories/execution.repository';
|
||||
import { ExecutionNotFoundError } from '@/errors/execution-not-found-error';
|
||||
import type {
|
||||
CreateExecutionPayload,
|
||||
IExecutingWorkflowData,
|
||||
IExecutionDb,
|
||||
IExecutionsCurrentSummary,
|
||||
} from '@/interfaces';
|
||||
import type { IExecutingWorkflowData, IExecutionsCurrentSummary } from '@/interfaces';
|
||||
import { isWorkflowIdValid } from '@/utils';
|
||||
|
||||
import { ConcurrencyControlService } from './concurrency/concurrency-control.service';
|
||||
import config from './config';
|
||||
import type { CreateExecutionPayload, IExecutionDb } from './types-db';
|
||||
|
||||
@Service()
|
||||
export class ActiveExecutions {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
import { Flags } from '@oclif/core';
|
||||
import glob from 'fast-glob';
|
||||
@@ -11,7 +12,6 @@ import { ProjectRepository } from '@/databases/repositories/project.repository';
|
||||
import { SharedWorkflowRepository } from '@/databases/repositories/shared-workflow.repository';
|
||||
import { UserRepository } from '@/databases/repositories/user.repository';
|
||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
import type { IWorkflowToImport } from '@/interfaces';
|
||||
import { ImportService } from '@/services/import.service';
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ import { FolderNotFoundError } from '@/errors/folder-not-found.error';
|
||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||
import { InternalServerError } from '@/errors/response-errors/internal-server.error';
|
||||
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import { AuthenticatedRequest } from '@/requests';
|
||||
import { FolderService } from '@/services/folder.service';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
@RestController('/projects/:projectId/folders')
|
||||
export class ProjectController {
|
||||
|
||||
@@ -27,10 +27,11 @@ import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import { EventService } from '@/events/event.service';
|
||||
import { ExternalHooks } from '@/external-hooks';
|
||||
import { listQueryMiddleware } from '@/middlewares';
|
||||
import { AuthenticatedRequest, ListQuery, UserRequest } from '@/requests';
|
||||
import { AuthenticatedRequest, UserRequest } from '@/requests';
|
||||
import { FolderService } from '@/services/folder.service';
|
||||
import { ProjectService } from '@/services/project.service.ee';
|
||||
import { UserService } from '@/services/user.service';
|
||||
import { ListQuery } from '@/types-db';
|
||||
import type { PublicUser } from '@/types-db';
|
||||
import { WorkflowService } from '@/workflows/workflow.service';
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ describe('CredentialsController', () => {
|
||||
id: newCredentialsPayload.projectId,
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
credentialsService.createUnmanagedCredential.mockResolvedValue(createdCredentials);
|
||||
|
||||
sharedCredentialsRepository.findCredentialOwningProject.mockResolvedValue(
|
||||
|
||||
@@ -33,13 +33,12 @@ import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import { ExternalHooks } from '@/external-hooks';
|
||||
import { validateEntity } from '@/generic-helpers';
|
||||
import { userHasScopes } from '@/permissions.ee/check-access';
|
||||
import type { CredentialRequest, ListQuery } from '@/requests';
|
||||
import type { CredentialRequest } from '@/requests';
|
||||
import { CredentialsTester } from '@/services/credentials-tester.service';
|
||||
import { OwnershipService } from '@/services/ownership.service';
|
||||
import { ProjectService } from '@/services/project.service.ee';
|
||||
import type { ScopesField } from '@/services/role.service';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import type { ICredentialsDb } from '@/types-db';
|
||||
import type { ICredentialsDb, ListQuery, ScopesField } from '@/types-db';
|
||||
|
||||
import { CredentialsFinderService } from './credentials-finder.service';
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { WithTimestampsAndStringId } from '@n8n/db';
|
||||
import { Column, Entity, Index, ManyToMany, OneToMany } from '@n8n/typeorm';
|
||||
import { IsString, Length } from 'class-validator';
|
||||
|
||||
import type { AnnotationTagMapping } from '@/databases/entities/annotation-tag-mapping.ee';
|
||||
import type { ExecutionAnnotation } from '@/databases/entities/execution-annotation.ee';
|
||||
|
||||
import { WithTimestampsAndStringId } from './abstract-entity';
|
||||
|
||||
@Entity()
|
||||
export class AnnotationTagEntity extends WithTimestampsAndStringId {
|
||||
@Column({ length: 24 })
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { JsonColumn, WithTimestampsAndStringId } from '@n8n/db';
|
||||
import type { ApiKeyScope } from '@n8n/permissions';
|
||||
import { Column, Entity, Index, ManyToOne, Unique } from '@n8n/typeorm';
|
||||
|
||||
import { jsonColumnType, WithTimestampsAndStringId } from './abstract-entity';
|
||||
import { User } from './user';
|
||||
|
||||
@Entity('user_api_keys')
|
||||
@@ -20,7 +20,7 @@ export class ApiKey extends WithTimestampsAndStringId {
|
||||
@Column({ type: String })
|
||||
label: string;
|
||||
|
||||
@Column({ type: jsonColumnType, nullable: false })
|
||||
@JsonColumn({ nullable: false })
|
||||
scopes: ApiKeyScope[];
|
||||
|
||||
@Index({ unique: true })
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { WithTimestamps } from '@n8n/db';
|
||||
import { Column, Entity, ManyToOne, PrimaryColumn, Unique } from '@n8n/typeorm';
|
||||
|
||||
import { WithTimestamps } from './abstract-entity';
|
||||
import { User } from './user';
|
||||
|
||||
export type AuthProviderType = 'ldap' | 'email' | 'saml'; // | 'google';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { DateTimeColumn } from '@n8n/db';
|
||||
import { Column, Entity, PrimaryGeneratedColumn } from '@n8n/typeorm';
|
||||
|
||||
import { datetimeColumnType } from './abstract-entity';
|
||||
import { AuthProviderType } from './auth-identity';
|
||||
|
||||
export type RunningMode = 'dry' | 'live';
|
||||
@@ -20,10 +20,10 @@ export class AuthProviderSyncHistory {
|
||||
@Column('text')
|
||||
status: SyncStatus;
|
||||
|
||||
@Column(datetimeColumnType)
|
||||
@DateTimeColumn()
|
||||
startedAt: Date;
|
||||
|
||||
@Column(datetimeColumnType)
|
||||
@DateTimeColumn()
|
||||
endedAt: Date;
|
||||
|
||||
@Column()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { WithTimestampsAndStringId } from '@n8n/db';
|
||||
import { Column, Entity, Index, OneToMany } from '@n8n/typeorm';
|
||||
import { IsObject, IsString, Length } from 'class-validator';
|
||||
|
||||
import type { ICredentialsDb } from '@/types-db';
|
||||
|
||||
import { WithTimestampsAndStringId } from './abstract-entity';
|
||||
import type { SharedCredentials } from './shared-credentials';
|
||||
|
||||
@Entity()
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { Column, Entity, PrimaryColumn } from '@n8n/typeorm';
|
||||
import { JsonColumn, WithTimestamps } from '@n8n/db';
|
||||
import { Entity, PrimaryColumn } from '@n8n/typeorm';
|
||||
import { MessageEventBusDestinationOptions } from 'n8n-workflow';
|
||||
|
||||
import { WithTimestamps, jsonColumnType } from './abstract-entity';
|
||||
|
||||
@Entity({ name: 'event_destinations' })
|
||||
export class EventDestinations extends WithTimestamps {
|
||||
@PrimaryColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column(jsonColumnType)
|
||||
@JsonColumn()
|
||||
destination: MessageEventBusDestinationOptions;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { JsonColumn } from '@n8n/db';
|
||||
import { Column, Entity, ManyToOne, PrimaryColumn } from '@n8n/typeorm';
|
||||
import { IWorkflowBase } from 'n8n-workflow';
|
||||
|
||||
import { jsonColumnType } from './abstract-entity';
|
||||
import { ExecutionEntity } from './execution-entity';
|
||||
import { idStringifier } from '../utils/transformers';
|
||||
|
||||
@@ -15,7 +15,7 @@ export class ExecutionData {
|
||||
// This is because manual executions of unsaved workflows have no workflow id
|
||||
// and IWorkflowDb has it as a mandatory field. IWorkflowBase reflects the correct
|
||||
// data structure for this entity.
|
||||
@Column(jsonColumnType)
|
||||
@JsonColumn()
|
||||
workflowData: IWorkflowBase;
|
||||
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DateTimeColumn, datetimeColumnType } from '@n8n/db';
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
@@ -10,11 +11,11 @@ import {
|
||||
Relation,
|
||||
DeleteDateColumn,
|
||||
} from '@n8n/typeorm';
|
||||
import type { SimpleColumnType } from '@n8n/typeorm/driver/types/ColumnTypes';
|
||||
import { ExecutionStatus, WorkflowExecuteMode } from 'n8n-workflow';
|
||||
|
||||
import type { ExecutionAnnotation } from '@/databases/entities/execution-annotation.ee';
|
||||
|
||||
import { datetimeColumnType } from './abstract-entity';
|
||||
import type { ExecutionData } from './execution-data';
|
||||
import type { ExecutionMetadata } from './execution-metadata';
|
||||
import { WorkflowEntity } from './workflow-entity';
|
||||
@@ -58,20 +59,23 @@ export class ExecutionEntity {
|
||||
* Time when the processing of the execution actually started. This column
|
||||
* is `null` when an execution is enqueued but has not started yet.
|
||||
*/
|
||||
@Column({ type: datetimeColumnType, nullable: true })
|
||||
@Column({
|
||||
type: datetimeColumnType as SimpleColumnType,
|
||||
nullable: true,
|
||||
})
|
||||
startedAt: Date | null;
|
||||
|
||||
@Index()
|
||||
@Column({ type: datetimeColumnType, nullable: true })
|
||||
@DateTimeColumn({ nullable: true })
|
||||
stoppedAt: Date;
|
||||
|
||||
@DeleteDateColumn({ type: datetimeColumnType, nullable: true })
|
||||
@DeleteDateColumn({ type: datetimeColumnType as SimpleColumnType, nullable: true })
|
||||
deletedAt: Date;
|
||||
|
||||
@Column({ nullable: true })
|
||||
workflowId: string;
|
||||
|
||||
@Column({ type: datetimeColumnType, nullable: true })
|
||||
@DateTimeColumn({ nullable: true })
|
||||
waitTill: Date | null;
|
||||
|
||||
@OneToMany('ExecutionMetadata', 'execution')
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { WithTimestampsAndStringId } from '@n8n/db';
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
@@ -8,7 +9,6 @@ import {
|
||||
OneToMany,
|
||||
} from '@n8n/typeorm';
|
||||
|
||||
import { WithTimestampsAndStringId } from './abstract-entity';
|
||||
import { Project } from './project';
|
||||
import { TagEntity } from './tag-entity';
|
||||
import { type WorkflowEntity } from './workflow-entity';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { WithTimestamps } from '@n8n/db';
|
||||
import { Column, Entity, JoinColumn, OneToMany, PrimaryColumn } from '@n8n/typeorm';
|
||||
|
||||
import { WithTimestamps } from './abstract-entity';
|
||||
import type { InstalledNodes } from './installed-nodes';
|
||||
|
||||
@Entity()
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { Column, Entity, PrimaryColumn } from '@n8n/typeorm';
|
||||
|
||||
import { datetimeColumnType } from './abstract-entity';
|
||||
import { DateTimeColumn } from '@n8n/db';
|
||||
import { Entity, PrimaryColumn } from '@n8n/typeorm';
|
||||
|
||||
@Entity()
|
||||
export class InvalidAuthToken {
|
||||
@PrimaryColumn()
|
||||
token: string;
|
||||
|
||||
@Column(datetimeColumnType)
|
||||
@DateTimeColumn()
|
||||
expiresAt: Date;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Column, Entity, PrimaryColumn } from '@n8n/typeorm';
|
||||
import { JsonColumn, WithTimestamps } from '@n8n/db';
|
||||
import { Entity, PrimaryColumn } from '@n8n/typeorm';
|
||||
|
||||
import type { IProcessedDataEntries, IProcessedDataLatest } from '@/interfaces';
|
||||
import type { IProcessedDataEntries, IProcessedDataLatest } from '@/types-db';
|
||||
|
||||
import { jsonColumnType, WithTimestamps } from './abstract-entity';
|
||||
import { objectRetriever } from '../utils/transformers';
|
||||
|
||||
@Entity()
|
||||
@@ -13,8 +13,7 @@ export class ProcessedData extends WithTimestamps {
|
||||
@PrimaryColumn()
|
||||
workflowId: string;
|
||||
|
||||
@Column({
|
||||
type: jsonColumnType,
|
||||
@JsonColumn({
|
||||
nullable: true,
|
||||
transformer: objectRetriever,
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ProjectRole } from '@n8n/api-types';
|
||||
import { WithTimestamps } from '@n8n/db';
|
||||
import { Column, Entity, ManyToOne, PrimaryColumn } from '@n8n/typeorm';
|
||||
|
||||
import { WithTimestamps } from './abstract-entity';
|
||||
import { Project } from './project';
|
||||
import { User } from './user';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ProjectIcon, ProjectType } from '@n8n/api-types';
|
||||
import { WithTimestampsAndStringId } from '@n8n/db';
|
||||
import { Column, Entity, OneToMany } from '@n8n/typeorm';
|
||||
|
||||
import { WithTimestampsAndStringId } from './abstract-entity';
|
||||
import type { ProjectRelation } from './project-relation';
|
||||
import type { SharedCredentials } from './shared-credentials';
|
||||
import type { SharedWorkflow } from './shared-workflow';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { WithTimestamps } from '@n8n/db';
|
||||
import { Column, Entity, ManyToOne, PrimaryColumn } from '@n8n/typeorm';
|
||||
|
||||
import { WithTimestamps } from './abstract-entity';
|
||||
import { CredentialsEntity } from './credentials-entity';
|
||||
import { Project } from './project';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { WithTimestamps } from '@n8n/db';
|
||||
import { Column, Entity, ManyToOne, PrimaryColumn } from '@n8n/typeorm';
|
||||
|
||||
import { WithTimestamps } from './abstract-entity';
|
||||
import { Project } from './project';
|
||||
import { WorkflowEntity } from './workflow-entity';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { WithTimestampsAndStringId } from '@n8n/db';
|
||||
import { Column, Entity, Index, ManyToMany, OneToMany } from '@n8n/typeorm';
|
||||
import { IsString, Length } from 'class-validator';
|
||||
|
||||
import { WithTimestampsAndStringId } from './abstract-entity';
|
||||
import type { FolderTagMapping } from './folder-tag-mapping';
|
||||
import type { WorkflowEntity } from './workflow-entity';
|
||||
import type { WorkflowTagMapping } from './workflow-tag-mapping';
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import { DateTimeColumn, JsonColumn, WithStringId } from '@n8n/db';
|
||||
import { Column, Entity, ManyToOne, OneToOne } from '@n8n/typeorm';
|
||||
import type { IDataObject } from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
datetimeColumnType,
|
||||
jsonColumnType,
|
||||
WithStringId,
|
||||
} from '@/databases/entities/abstract-entity';
|
||||
import type { ExecutionEntity } from '@/databases/entities/execution-entity';
|
||||
import { TestRun } from '@/databases/entities/test-run.ee';
|
||||
import type { TestCaseExecutionErrorCode } from '@/evaluation.ee/test-runner/errors.ee';
|
||||
@@ -62,18 +58,18 @@ export class TestCaseExecution extends WithStringId {
|
||||
@Column()
|
||||
status: TestCaseExecutionStatus;
|
||||
|
||||
@Column({ type: datetimeColumnType, nullable: true })
|
||||
@DateTimeColumn({ nullable: true })
|
||||
runAt: Date | null;
|
||||
|
||||
@Column({ type: datetimeColumnType, nullable: true })
|
||||
@DateTimeColumn({ nullable: true })
|
||||
completedAt: Date | null;
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
errorCode: TestCaseExecutionErrorCode | null;
|
||||
|
||||
@Column(jsonColumnType, { nullable: true })
|
||||
@JsonColumn({ nullable: true })
|
||||
errorDetails: IDataObject | null;
|
||||
|
||||
@Column(jsonColumnType, { nullable: true })
|
||||
@JsonColumn({ nullable: true })
|
||||
metrics: TestCaseRunMetrics;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JsonColumn, WithTimestampsAndStringId } from '@n8n/db';
|
||||
import { Column, Entity, Index, ManyToOne, OneToMany, RelationId } from '@n8n/typeorm';
|
||||
import { Length } from 'class-validator';
|
||||
|
||||
@@ -5,8 +6,6 @@ import { AnnotationTagEntity } from '@/databases/entities/annotation-tag-entity.
|
||||
import type { TestMetric } from '@/databases/entities/test-metric.ee';
|
||||
import { WorkflowEntity } from '@/databases/entities/workflow-entity';
|
||||
|
||||
import { jsonColumnType, WithTimestampsAndStringId } from './abstract-entity';
|
||||
|
||||
// Entity representing a node in a workflow under test, for which data should be mocked during test execution
|
||||
export type MockedNodeItem = {
|
||||
name?: string;
|
||||
@@ -33,7 +32,7 @@ export class TestDefinition extends WithTimestampsAndStringId {
|
||||
@Column('text')
|
||||
description: string;
|
||||
|
||||
@Column(jsonColumnType, { default: '[]' })
|
||||
@JsonColumn({ default: '[]' })
|
||||
mockedNodes: MockedNodeItem[];
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { WithTimestampsAndStringId } from '@n8n/db';
|
||||
import { Column, Entity, Index, ManyToOne } from '@n8n/typeorm';
|
||||
import { Length } from 'class-validator';
|
||||
|
||||
import { WithTimestampsAndStringId } from '@/databases/entities/abstract-entity';
|
||||
import { TestDefinition } from '@/databases/entities/test-definition.ee';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import { WithTimestampsAndStringId, JsonColumn, DateTimeColumn } from '@n8n/db';
|
||||
import { Column, Entity, Index, ManyToOne, OneToMany, RelationId } from '@n8n/typeorm';
|
||||
import type { IDataObject } from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
datetimeColumnType,
|
||||
jsonColumnType,
|
||||
WithTimestampsAndStringId,
|
||||
} from '@/databases/entities/abstract-entity';
|
||||
import type { TestCaseExecution } from '@/databases/entities/test-case-execution.ee';
|
||||
import { TestDefinition } from '@/databases/entities/test-definition.ee';
|
||||
import type { TestRunFinalResult } from '@/databases/repositories/test-run.repository.ee';
|
||||
@@ -31,13 +27,13 @@ export class TestRun extends WithTimestampsAndStringId {
|
||||
@Column('varchar')
|
||||
status: TestRunStatus;
|
||||
|
||||
@Column({ type: datetimeColumnType, nullable: true })
|
||||
@DateTimeColumn({ nullable: true })
|
||||
runAt: Date | null;
|
||||
|
||||
@Column({ type: datetimeColumnType, nullable: true })
|
||||
@DateTimeColumn({ nullable: true })
|
||||
completedAt: Date | null;
|
||||
|
||||
@Column(jsonColumnType, { nullable: true })
|
||||
@JsonColumn({ nullable: true })
|
||||
metrics: AggregatedTestRunMetrics;
|
||||
|
||||
/**
|
||||
@@ -69,7 +65,7 @@ export class TestRun extends WithTimestampsAndStringId {
|
||||
/**
|
||||
* Optional details about the error that happened during the test run
|
||||
*/
|
||||
@Column(jsonColumnType, { nullable: true })
|
||||
@JsonColumn({ nullable: true })
|
||||
errorDetails: IDataObject | null;
|
||||
|
||||
@OneToMany('TestCaseExecution', 'testRun')
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JsonColumn, WithTimestamps } from '@n8n/db';
|
||||
import { hasScope, type ScopeOptions, type Scope, GlobalRole } from '@n8n/permissions';
|
||||
import {
|
||||
AfterLoad,
|
||||
@@ -22,7 +23,6 @@ import type { IPersonalizationSurveyAnswers } from '@/types-db';
|
||||
import { NoUrl } from '@/validators/no-url.validator';
|
||||
import { NoXss } from '@/validators/no-xss.validator';
|
||||
|
||||
import { WithTimestamps, jsonColumnType } from './abstract-entity';
|
||||
import type { ApiKey } from './api-key';
|
||||
import type { AuthIdentity } from './auth-identity';
|
||||
import type { ProjectRelation } from './project-relation';
|
||||
@@ -68,17 +68,13 @@ export class User extends WithTimestamps implements IUser {
|
||||
@IsString({ message: 'Password must be of type string.' })
|
||||
password: string;
|
||||
|
||||
@Column({
|
||||
type: jsonColumnType,
|
||||
@JsonColumn({
|
||||
nullable: true,
|
||||
transformer: objectRetriever,
|
||||
})
|
||||
personalizationAnswers: IPersonalizationSurveyAnswers | null;
|
||||
|
||||
@Column({
|
||||
type: jsonColumnType,
|
||||
nullable: true,
|
||||
})
|
||||
@JsonColumn({ nullable: true })
|
||||
settings: IUserSettings | null;
|
||||
|
||||
@Column({ type: String })
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { WithStringId } from '@n8n/db';
|
||||
import { Column, Entity } from '@n8n/typeorm';
|
||||
|
||||
import { WithStringId } from './abstract-entity';
|
||||
|
||||
@Entity()
|
||||
export class Variables extends WithStringId {
|
||||
@Column('text')
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JsonColumn, WithTimestampsAndStringId, dbType } from '@n8n/db';
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
@@ -14,7 +15,6 @@ import type { IBinaryKeyData, INode, IPairedItemData } from 'n8n-workflow';
|
||||
|
||||
import type { IWorkflowDb } from '@/types-db';
|
||||
|
||||
import { WithTimestampsAndStringId, dbType, jsonColumnType } from './abstract-entity';
|
||||
import { type Folder } from './folder';
|
||||
import type { SharedWorkflow } from './shared-workflow';
|
||||
import type { TagEntity } from './tag-entity';
|
||||
@@ -35,27 +35,22 @@ export class WorkflowEntity extends WithTimestampsAndStringId implements IWorkfl
|
||||
@Column()
|
||||
active: boolean;
|
||||
|
||||
@Column(jsonColumnType)
|
||||
@JsonColumn()
|
||||
nodes: INode[];
|
||||
|
||||
@Column(jsonColumnType)
|
||||
@JsonColumn()
|
||||
connections: IConnections;
|
||||
|
||||
@Column({
|
||||
type: jsonColumnType,
|
||||
nullable: true,
|
||||
})
|
||||
@JsonColumn({ nullable: true })
|
||||
settings?: IWorkflowSettings;
|
||||
|
||||
@Column({
|
||||
type: jsonColumnType,
|
||||
@JsonColumn({
|
||||
nullable: true,
|
||||
transformer: objectRetriever,
|
||||
})
|
||||
staticData?: IDataObject;
|
||||
|
||||
@Column({
|
||||
type: jsonColumnType,
|
||||
@JsonColumn({
|
||||
nullable: true,
|
||||
transformer: objectRetriever,
|
||||
})
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { JsonColumn, WithTimestamps } from '@n8n/db';
|
||||
import { Column, Entity, ManyToOne, PrimaryColumn } from '@n8n/typeorm';
|
||||
import { IConnections } from 'n8n-workflow';
|
||||
import type { INode } from 'n8n-workflow';
|
||||
|
||||
import { WithTimestamps, jsonColumnType } from './abstract-entity';
|
||||
import { WorkflowEntity } from './workflow-entity';
|
||||
|
||||
@Entity()
|
||||
@@ -13,10 +13,10 @@ export class WorkflowHistory extends WithTimestamps {
|
||||
@Column()
|
||||
workflowId: string;
|
||||
|
||||
@Column(jsonColumnType)
|
||||
@JsonColumn()
|
||||
nodes: INode[];
|
||||
|
||||
@Column(jsonColumnType)
|
||||
@JsonColumn()
|
||||
connections: IConnections;
|
||||
|
||||
@Column()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { DateTimeColumn } from '@n8n/db';
|
||||
import { Column, Entity, ManyToOne, PrimaryColumn } from '@n8n/typeorm';
|
||||
|
||||
import { datetimeColumnType } from './abstract-entity';
|
||||
import { WorkflowEntity } from './workflow-entity';
|
||||
|
||||
export const enum StatisticsNames {
|
||||
@@ -19,7 +19,7 @@ export class WorkflowStatistics {
|
||||
@Column()
|
||||
rootCount: number;
|
||||
|
||||
@Column(datetimeColumnType)
|
||||
@DateTimeColumn()
|
||||
latestEvent: Date;
|
||||
|
||||
@PrimaryColumn({ length: 128 })
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { ProjectRole } from '@n8n/api-types';
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
import { UserError } from 'n8n-workflow';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import type { User } from '@/databases/entities/user';
|
||||
import type { MigrationContext, ReversibleMigration } from '@/databases/types';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
|
||||
const projectAdminRole: ProjectRole = 'project:personalOwner';
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
|
||||
import type { ApiKey } from '@/databases/entities/api-key';
|
||||
import type { MigrationContext, ReversibleMigration } from '@/databases/types';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
|
||||
export class AddApiKeysTable1724951148974 implements ReversibleMigration {
|
||||
async up({
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
|
||||
import type { ApiKey } from '@/databases/entities/api-key';
|
||||
import type { MigrationContext, ReversibleMigration } from '@/databases/types';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
|
||||
export class AddApiKeysTable1724951148974 implements ReversibleMigration {
|
||||
transaction = false as const;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Service } from '@n8n/di';
|
||||
import { DataSource, In, Repository, Like } from '@n8n/typeorm';
|
||||
import type { FindManyOptions } from '@n8n/typeorm';
|
||||
|
||||
import type { ListQuery } from '@/requests';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
import { CredentialsEntity } from '../entities/credentials-entity';
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { GlobalConfig } from '@n8n/config';
|
||||
import { separate } from '@n8n/db';
|
||||
import { Service } from '@n8n/di';
|
||||
import type {
|
||||
FindManyOptions,
|
||||
@@ -35,10 +36,13 @@ import { AnnotationTagEntity } from '@/databases/entities/annotation-tag-entity.
|
||||
import { AnnotationTagMapping } from '@/databases/entities/annotation-tag-mapping.ee';
|
||||
import { ExecutionAnnotation } from '@/databases/entities/execution-annotation.ee';
|
||||
import { PostgresLiveRowsRetrievalError } from '@/errors/postgres-live-rows-retrieval.error';
|
||||
import type { ExecutionSummaries } from '@/executions/execution.types';
|
||||
import type { CreateExecutionPayload, IExecutionFlattedDb } from '@/interfaces';
|
||||
import type { IExecutionBase, IExecutionResponse } from '@/types-db';
|
||||
import { separate } from '@/utils';
|
||||
import type {
|
||||
CreateExecutionPayload,
|
||||
IExecutionFlattedDb,
|
||||
IExecutionBase,
|
||||
IExecutionResponse,
|
||||
ExecutionSummaries,
|
||||
} from '@/types-db';
|
||||
|
||||
import { ExecutionDataRepository } from './execution-data.repository';
|
||||
import { ExecutionData } from '../entities/execution-data';
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { EntityManager, SelectQueryBuilder } from '@n8n/typeorm';
|
||||
import { DataSource, Repository } from '@n8n/typeorm';
|
||||
import { PROJECT_ROOT } from 'n8n-workflow';
|
||||
|
||||
import type { ListQuery } from '@/requests';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
import type { FolderWithWorkflowAndSubFolderCount } from '../entities/folder';
|
||||
import { Folder } from '../entities/folder';
|
||||
|
||||
@@ -4,7 +4,7 @@ import { DataSource, In, Repository } from '@n8n/typeorm';
|
||||
|
||||
import { TestDefinition } from '@/databases/entities/test-definition.ee';
|
||||
import { ForbiddenError } from '@/errors/response-errors/forbidden.error';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
@Service()
|
||||
export class TestDefinitionRepository extends Repository<TestDefinition> {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { TestRun } from '@/databases/entities/test-run.ee';
|
||||
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import type { TestRunErrorCode } from '@/evaluation.ee/test-runner/errors.ee';
|
||||
import { getTestRunFinalResult } from '@/evaluation.ee/test-runner/utils.ee';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
export type TestRunFinalResult = 'success' | 'error' | 'warning';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { GlobalRole } from '@n8n/permissions';
|
||||
import type { DeepPartial, EntityManager, FindManyOptions } from '@n8n/typeorm';
|
||||
import { DataSource, In, IsNull, Not, Repository } from '@n8n/typeorm';
|
||||
|
||||
import type { ListQuery } from '@/requests';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
import { Project } from '../entities/project';
|
||||
import { ProjectRelation } from '../entities/project-relation';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { GlobalConfig } from '@n8n/config';
|
||||
import { isStringArray } from '@n8n/db';
|
||||
import { Service } from '@n8n/di';
|
||||
import { DataSource, Repository, In, Like } from '@n8n/typeorm';
|
||||
import type {
|
||||
@@ -12,8 +13,7 @@ import type {
|
||||
} from '@n8n/typeorm';
|
||||
import { PROJECT_ROOT } from 'n8n-workflow';
|
||||
|
||||
import type { ListQuery } from '@/requests';
|
||||
import { isStringArray } from '@/utils';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
import { FolderRepository } from './folder.repository';
|
||||
import type { Folder, FolderWithWorkflowAndSubFolderCount } from '../entities/folder';
|
||||
|
||||
@@ -15,7 +15,7 @@ import * as assert from 'node:assert/strict';
|
||||
import type { ProcessedData } from '@/databases/entities/processed-data';
|
||||
import { ProcessedDataRepository } from '@/databases/repositories/processed-data.repository';
|
||||
import { DeduplicationError } from '@/errors/deduplication.error';
|
||||
import type { IProcessedDataEntries, IProcessedDataLatest } from '@/interfaces';
|
||||
import type { IProcessedDataEntries, IProcessedDataLatest } from '@/types-db';
|
||||
|
||||
export class DeduplicationHelper implements IDataDeduplicator {
|
||||
private static sortEntries(
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
import { Service } from '@n8n/di';
|
||||
|
||||
import type { Variables } from '@/databases/entities/variables';
|
||||
import { VariablesRepository } from '@/databases/repositories/variables.repository';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
import { VariableCountLimitReachedError } from '@/errors/variable-count-limit-reached.error';
|
||||
import { VariableValidationError } from '@/errors/variable-validation.error';
|
||||
import { EventService } from '@/events/event.service';
|
||||
|
||||
@@ -6,8 +6,8 @@ import { TestDefinitionRepository } from '@/databases/repositories/test-definiti
|
||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import { validateEntity } from '@/generic-helpers';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import { Telemetry } from '@/telemetry';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
type TestDefinitionLike = Omit<
|
||||
Partial<TestDefinition>,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { MockedNodeItem } from '@/databases/entities/test-definition.ee';
|
||||
import type { AuthenticatedRequest, ListQuery } from '@/requests';
|
||||
import type { AuthenticatedRequest } from '@/requests';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
// ----------------------------------
|
||||
// /test-definitions
|
||||
|
||||
@@ -4,8 +4,9 @@ import { Logger } from 'n8n-core';
|
||||
import { ensureError, type ExecutionStatus, type IRun, type IWorkflowBase } from 'n8n-workflow';
|
||||
|
||||
import { ExecutionRepository } from '@/databases/repositories/execution.repository';
|
||||
import type { IExecutionDb, UpdateExecutionPayload } from '@/interfaces';
|
||||
import type { UpdateExecutionPayload } from '@/interfaces';
|
||||
import { ExecutionMetadataService } from '@/services/execution-metadata.service';
|
||||
import type { IExecutionDb } from '@/types-db';
|
||||
import { isWorkflowIdValid } from '@/utils';
|
||||
|
||||
export function determineFinalExecutionStatus(runData: IRun): ExecutionStatus {
|
||||
|
||||
@@ -3,8 +3,9 @@ import { mock } from 'jest-mock-extended';
|
||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import type { ExecutionService } from '@/executions/execution.service';
|
||||
import type { ExecutionRequest, ExecutionSummaries } from '@/executions/execution.types';
|
||||
import type { ExecutionRequest } from '@/executions/execution.types';
|
||||
import { ExecutionsController } from '@/executions/executions.controller';
|
||||
import type { ExecutionSummaries } from '@/types-db';
|
||||
import type { WorkflowSharingService } from '@/workflows/workflow-sharing.service';
|
||||
|
||||
describe('ExecutionsController', () => {
|
||||
|
||||
@@ -33,15 +33,15 @@ import { MissingExecutionStopError } from '@/errors/missing-execution-stop.error
|
||||
import { QueuedExecutionRetryError } from '@/errors/queued-execution-retry.error';
|
||||
import { InternalServerError } from '@/errors/response-errors/internal-server.error';
|
||||
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import type { CreateExecutionPayload, IExecutionFlattedResponse } from '@/interfaces';
|
||||
import type { IExecutionFlattedResponse } from '@/interfaces';
|
||||
import { License } from '@/license';
|
||||
import { NodeTypes } from '@/node-types';
|
||||
import type { IExecutionResponse } from '@/types-db';
|
||||
import type { CreateExecutionPayload, ExecutionSummaries, IExecutionResponse } from '@/types-db';
|
||||
import { WaitTracker } from '@/wait-tracker';
|
||||
import { WorkflowRunner } from '@/workflow-runner';
|
||||
import { WorkflowSharingService } from '@/workflows/workflow-sharing.service';
|
||||
|
||||
import type { ExecutionRequest, ExecutionSummaries, StopResult } from './execution.types';
|
||||
import type { ExecutionRequest, StopResult } from './execution.types';
|
||||
|
||||
export const schemaGetExecutionsQueryFilter = {
|
||||
$id: '/IGetExecutionsQueryFilter',
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import type { Scope } from '@n8n/permissions';
|
||||
import type {
|
||||
AnnotationVote,
|
||||
ExecutionStatus,
|
||||
ExecutionSummary,
|
||||
IDataObject,
|
||||
WorkflowExecuteMode,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import type { ExecutionEntity } from '@/databases/entities/execution-entity';
|
||||
import type { AuthenticatedRequest } from '@/requests';
|
||||
import type { ExecutionSummaries } from '@/types-db';
|
||||
|
||||
export declare namespace ExecutionRequest {
|
||||
namespace QueryParams {
|
||||
@@ -56,55 +55,6 @@ export declare namespace ExecutionRequest {
|
||||
type Update = AuthenticatedRequest<RouteParams.ExecutionId, {}, ExecutionUpdatePayload, {}>;
|
||||
}
|
||||
|
||||
export namespace ExecutionSummaries {
|
||||
export type Query = RangeQuery | CountQuery;
|
||||
|
||||
export type RangeQuery = { kind: 'range' } & FilterFields &
|
||||
AccessFields &
|
||||
RangeFields &
|
||||
OrderFields;
|
||||
|
||||
export type CountQuery = { kind: 'count' } & FilterFields & AccessFields;
|
||||
|
||||
type FilterFields = Partial<{
|
||||
id: string;
|
||||
finished: boolean;
|
||||
mode: string;
|
||||
retryOf: string;
|
||||
retrySuccessId: string;
|
||||
status: ExecutionStatus[];
|
||||
workflowId: string;
|
||||
waitTill: boolean;
|
||||
metadata: Array<{ key: string; value: string }>;
|
||||
startedAfter: string;
|
||||
startedBefore: string;
|
||||
annotationTags: string[]; // tag IDs
|
||||
vote: AnnotationVote;
|
||||
projectId: string;
|
||||
}>;
|
||||
|
||||
type AccessFields = {
|
||||
accessibleWorkflowIds?: string[];
|
||||
};
|
||||
|
||||
type RangeFields = {
|
||||
range: {
|
||||
limit: number;
|
||||
firstId?: string;
|
||||
lastId?: string;
|
||||
};
|
||||
};
|
||||
|
||||
type OrderFields = {
|
||||
order?: {
|
||||
top?: ExecutionStatus;
|
||||
startedAt?: 'DESC';
|
||||
};
|
||||
};
|
||||
|
||||
export type ExecutionSummaryWithScopes = ExecutionSummary & { scopes: Scope[] };
|
||||
}
|
||||
|
||||
export type StopResult = {
|
||||
mode: WorkflowExecuteMode;
|
||||
startedAt: Date;
|
||||
|
||||
@@ -5,12 +5,13 @@ import type { User } from '@/databases/entities/user';
|
||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import { License } from '@/license';
|
||||
import type { ExecutionSummaries } from '@/types-db';
|
||||
import { isPositiveInteger } from '@/utils';
|
||||
import { WorkflowSharingService } from '@/workflows/workflow-sharing.service';
|
||||
|
||||
import { ExecutionService } from './execution.service';
|
||||
import { EnterpriseExecutionsService } from './execution.service.ee';
|
||||
import { ExecutionRequest, type ExecutionSummaries } from './execution.types';
|
||||
import { ExecutionRequest } from './execution.types';
|
||||
import { parseRangeQuery } from './parse-range-query.middleware';
|
||||
import { validateExecutionUpdatePayload } from './validation';
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import type {
|
||||
IDeferredPromise,
|
||||
IExecuteResponsePromiseData,
|
||||
IRun,
|
||||
IRunExecutionData,
|
||||
ITelemetryTrackProperties,
|
||||
IWorkflowBase,
|
||||
CredentialLoadingDetails,
|
||||
@@ -15,14 +14,12 @@ import type {
|
||||
ExecutionStatus,
|
||||
ExecutionSummary,
|
||||
IWorkflowExecutionDataProcess,
|
||||
DeduplicationMode,
|
||||
DeduplicationItemTypes,
|
||||
} from 'n8n-workflow';
|
||||
import type PCancelable from 'p-cancelable';
|
||||
|
||||
import type { ActiveWorkflowManager } from '@/active-workflow-manager';
|
||||
import type { ExternalHooks } from '@/external-hooks';
|
||||
import type { ICredentialsBase, IExecutionBase, ITagBase } from '@/types-db';
|
||||
import type { ICredentialsBase, IExecutionBase, IExecutionDb, ITagBase } from '@/types-db';
|
||||
|
||||
export interface ICredentialsTypeData {
|
||||
[key: string]: CredentialLoadingDetails;
|
||||
@@ -32,20 +29,6 @@ export interface ICredentialsOverwrite {
|
||||
[key: string]: ICredentialDataDecryptedObject;
|
||||
}
|
||||
|
||||
// ----------------------------------
|
||||
// ProcessedData
|
||||
// ----------------------------------
|
||||
|
||||
export interface IProcessedDataLatest {
|
||||
mode: DeduplicationMode;
|
||||
data: DeduplicationItemTypes;
|
||||
}
|
||||
|
||||
export interface IProcessedDataEntries {
|
||||
mode: DeduplicationMode;
|
||||
data: DeduplicationItemTypes[];
|
||||
}
|
||||
|
||||
// ----------------------------------
|
||||
// tags
|
||||
// ----------------------------------
|
||||
@@ -82,15 +65,6 @@ export type ICredentialsDecryptedResponse = ICredentialsDecryptedDb;
|
||||
|
||||
export type SaveExecutionDataType = 'all' | 'none';
|
||||
|
||||
// Data in regular format with references
|
||||
export interface IExecutionDb extends IExecutionBase {
|
||||
data: IRunExecutionData;
|
||||
workflowData: IWorkflowBase;
|
||||
}
|
||||
|
||||
/** Payload for creating an execution. */
|
||||
export type CreateExecutionPayload = Omit<IExecutionDb, 'id' | 'createdAt' | 'startedAt'>;
|
||||
|
||||
/** Payload for updating an execution. */
|
||||
export type UpdateExecutionPayload = Omit<IExecutionDb, 'id' | 'createdAt'>;
|
||||
|
||||
@@ -101,13 +75,6 @@ export interface IExecutionFlatted extends IExecutionBase {
|
||||
workflowData: IWorkflowBase;
|
||||
}
|
||||
|
||||
export interface IExecutionFlattedDb extends IExecutionBase {
|
||||
id: string;
|
||||
data: string;
|
||||
workflowData: Omit<IWorkflowBase, 'pinData'>;
|
||||
customData: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface IExecutionFlattedResponse extends IExecutionFlatted {
|
||||
id: string;
|
||||
retryOf?: string;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
|
||||
import { AuthIdentity } from '@/databases/entities/auth-identity';
|
||||
import { User } from '@/databases/entities/user';
|
||||
import { UserRepository } from '@/databases/repositories/user.repository';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
import * as helpers from '@/ldap.ee/helpers.ee';
|
||||
import { mockInstance } from '@test/mocking';
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ import type { Response, NextFunction } from 'express';
|
||||
import { filterListQueryMiddleware } from '@/middlewares/list-query/filter';
|
||||
import { paginationListQueryMiddleware } from '@/middlewares/list-query/pagination';
|
||||
import { selectListQueryMiddleware } from '@/middlewares/list-query/select';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import * as ResponseHelper from '@/response-helper';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
import { sortByQueryMiddleware } from '../sort-by';
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { isStringArray } from '@n8n/db';
|
||||
import { jsonParse, UnexpectedError } from 'n8n-workflow';
|
||||
|
||||
import { isStringArray } from '@/utils';
|
||||
|
||||
export class BaseSelect {
|
||||
static selectableFields: Set<string>;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { NextFunction, Response } from 'express';
|
||||
|
||||
import type { ListQuery } from '@/requests';
|
||||
import * as ResponseHelper from '@/response-helper';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
import { toError } from '@/utils';
|
||||
|
||||
import { CredentialsFilter } from './dtos/credentials.filter.dto';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type NextFunction, type Response } from 'express';
|
||||
|
||||
import type { ListQuery } from '@/requests';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
import { filterListQueryMiddleware } from './filter';
|
||||
import { paginationListQueryMiddleware } from './pagination';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { RequestHandler } from 'express';
|
||||
import { UnexpectedError } from 'n8n-workflow';
|
||||
|
||||
import type { ListQuery } from '@/requests';
|
||||
import * as ResponseHelper from '@/response-helper';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
import { toError } from '@/utils';
|
||||
|
||||
import { Pagination } from './dtos/pagination.dto';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { RequestHandler } from 'express';
|
||||
|
||||
import type { ListQuery } from '@/requests';
|
||||
import * as ResponseHelper from '@/response-helper';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
import { toError } from '@/utils';
|
||||
|
||||
import { CredentialsSelect } from './dtos/credentials.select.dto';
|
||||
|
||||
@@ -3,8 +3,8 @@ import { validateSync } from 'class-validator';
|
||||
import type { RequestHandler } from 'express';
|
||||
import { UnexpectedError } from 'n8n-workflow';
|
||||
|
||||
import type { ListQuery } from '@/requests';
|
||||
import * as ResponseHelper from '@/response-helper';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
import { toError } from '@/utils';
|
||||
|
||||
import { WorkflowSorting } from './dtos/workflow.sort-by.dto';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DateTimeColumn } from '@n8n/db';
|
||||
import {
|
||||
BaseEntity,
|
||||
Column,
|
||||
@@ -8,8 +9,6 @@ import {
|
||||
} from '@n8n/typeorm';
|
||||
import { UnexpectedError } from 'n8n-workflow';
|
||||
|
||||
import { datetimeColumnType } from '@/databases/entities/abstract-entity';
|
||||
|
||||
import { InsightsMetadata } from './insights-metadata';
|
||||
import type { PeriodUnit } from './insights-shared';
|
||||
import {
|
||||
@@ -70,6 +69,6 @@ export class InsightsByPeriod extends BaseEntity {
|
||||
this.periodUnit_ = PeriodUnitToNumber[value];
|
||||
}
|
||||
|
||||
@Column({ type: datetimeColumnType })
|
||||
@DateTimeColumn()
|
||||
periodStart: Date;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { GlobalConfig } from '@n8n/config';
|
||||
import { DateTimeColumn } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from '@n8n/typeorm';
|
||||
import { UnexpectedError } from 'n8n-workflow';
|
||||
|
||||
import { datetimeColumnType } from '@/databases/entities/abstract-entity';
|
||||
|
||||
import { isValidTypeNumber, NumberToType, TypeToNumber } from './insights-shared';
|
||||
|
||||
export const { type: dbType } = Container.get(GlobalConfig).database;
|
||||
@@ -42,9 +41,6 @@ export class InsightsRaw extends BaseEntity {
|
||||
@Column()
|
||||
value: number;
|
||||
|
||||
@Column({
|
||||
name: 'timestamp',
|
||||
type: datetimeColumnType,
|
||||
})
|
||||
@DateTimeColumn({ name: 'timestamp' })
|
||||
timestamp: Date;
|
||||
}
|
||||
|
||||
@@ -5,17 +5,13 @@ import type {
|
||||
ICredentialDataDecryptedObject,
|
||||
INodeCredentialTestRequest,
|
||||
IPersonalizationSurveyAnswersV4,
|
||||
IUser,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import type { CredentialsEntity } from '@/databases/entities/credentials-entity';
|
||||
import type { Project } from '@/databases/entities/project';
|
||||
import type { User } from '@/databases/entities/user';
|
||||
import type { Variables } from '@/databases/entities/variables';
|
||||
import type { WorkflowEntity } from '@/databases/entities/workflow-entity';
|
||||
import type { WorkflowHistory } from '@/databases/entities/workflow-history';
|
||||
import type { ScopesField } from '@/services/role.service';
|
||||
import type { SlimProject } from '@/types-db';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
export type APIRequest<
|
||||
RouteParams = {},
|
||||
@@ -50,80 +46,6 @@ export type AuthenticatedRequest<
|
||||
// list query
|
||||
// ----------------------------------
|
||||
|
||||
export namespace ListQuery {
|
||||
export type Request = AuthenticatedRequest<{}, {}, {}, Params> & {
|
||||
listQueryOptions?: Options;
|
||||
};
|
||||
|
||||
export type Params = {
|
||||
filter?: string;
|
||||
skip?: string;
|
||||
take?: string;
|
||||
select?: string;
|
||||
sortBy?: string;
|
||||
};
|
||||
|
||||
export type Options = {
|
||||
filter?: Record<string, unknown>;
|
||||
select?: Record<string, true>;
|
||||
skip?: number;
|
||||
take?: number;
|
||||
sortBy?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Slim workflow returned from a list query operation.
|
||||
*/
|
||||
export namespace Workflow {
|
||||
type OptionalBaseFields = 'name' | 'active' | 'versionId' | 'createdAt' | 'updatedAt' | 'tags';
|
||||
|
||||
type BaseFields = Pick<WorkflowEntity, 'id'> &
|
||||
Partial<Pick<WorkflowEntity, OptionalBaseFields>>;
|
||||
|
||||
type SharedField = Partial<Pick<WorkflowEntity, 'shared'>>;
|
||||
|
||||
type SortingField = 'createdAt' | 'updatedAt' | 'name';
|
||||
|
||||
export type SortOrder = `${SortingField}:asc` | `${SortingField}:desc`;
|
||||
|
||||
type OwnedByField = { ownedBy: SlimUser | null; homeProject: SlimProject | null };
|
||||
|
||||
export type Plain = BaseFields;
|
||||
|
||||
export type WithSharing = BaseFields & SharedField;
|
||||
|
||||
export type WithOwnership = BaseFields & OwnedByField;
|
||||
|
||||
type SharedWithField = { sharedWith: SlimUser[]; sharedWithProjects: SlimProject[] };
|
||||
|
||||
export type WithOwnedByAndSharedWith = BaseFields &
|
||||
OwnedByField &
|
||||
SharedWithField &
|
||||
SharedField;
|
||||
|
||||
export type WithScopes = BaseFields & ScopesField & SharedField;
|
||||
}
|
||||
|
||||
export namespace Credentials {
|
||||
type OwnedByField = { homeProject: SlimProject | null };
|
||||
|
||||
type SharedField = Partial<Pick<CredentialsEntity, 'shared'>>;
|
||||
|
||||
type SharedWithField = { sharedWithProjects: SlimProject[] };
|
||||
|
||||
export type WithSharing = CredentialsEntity & SharedField;
|
||||
|
||||
export type WithOwnedByAndSharedWith = CredentialsEntity &
|
||||
OwnedByField &
|
||||
SharedWithField &
|
||||
SharedField;
|
||||
|
||||
export type WithScopes = CredentialsEntity & ScopesField & SharedField;
|
||||
}
|
||||
}
|
||||
|
||||
type SlimUser = Pick<IUser, 'id' | 'email' | 'firstName' | 'lastName'>;
|
||||
|
||||
export function hasSharing(
|
||||
workflows: ListQuery.Workflow.Plain[] | ListQuery.Workflow.WithSharing[],
|
||||
): workflows is ListQuery.Workflow.WithSharing[] {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { GlobalConfig } from '@n8n/config';
|
||||
import { separate } from '@n8n/db';
|
||||
import { Service } from '@n8n/di';
|
||||
import axios from 'axios';
|
||||
import { InstanceSettings, Logger } from 'n8n-core';
|
||||
@@ -15,7 +16,6 @@ import {
|
||||
} from '@/security-audit/constants';
|
||||
import type { RiskReporter, Risk, n8n } from '@/security-audit/types';
|
||||
import { toFlaggedNode } from '@/security-audit/utils';
|
||||
import { separate } from '@/utils';
|
||||
|
||||
@Service()
|
||||
export class InstanceRiskReporter implements RiskReporter {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { FolderTagMappingRepository } from '@/databases/repositories/folder-tag-
|
||||
import { FolderRepository } from '@/databases/repositories/folder.repository';
|
||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { FolderNotFoundError } from '@/errors/folder-not-found.error';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
export interface SimpleFolderNode {
|
||||
id: string;
|
||||
|
||||
@@ -6,8 +6,8 @@ import { ProjectRelationRepository } from '@/databases/repositories/project-rela
|
||||
import { ProjectRepository } from '@/databases/repositories/project.repository';
|
||||
import { SharedWorkflowRepository } from '@/databases/repositories/shared-workflow.repository';
|
||||
import { UserRepository } from '@/databases/repositories/user.repository';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import { CacheService } from '@/services/cache/cache.service';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
@Service()
|
||||
export class OwnershipService {
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
WORKFLOW_SHARING_EDITOR_SCOPES,
|
||||
WORKFLOW_SHARING_OWNER_SCOPES,
|
||||
} from '@/permissions.ee/resource-roles';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import type { ListQuery, ScopesField } from '@/types-db';
|
||||
|
||||
export type RoleNamespace = 'global' | 'project' | 'credential' | 'workflow';
|
||||
|
||||
@@ -100,7 +100,7 @@ const ROLE_NAMES: Record<
|
||||
'workflow:editor': 'Workflow Editor',
|
||||
};
|
||||
|
||||
export type ScopesField = { scopes: Scope[] };
|
||||
// export type ScopesField = { scopes: Scope[] };
|
||||
|
||||
@Service()
|
||||
export class RoleService {
|
||||
@@ -189,7 +189,10 @@ export class RoleService {
|
||||
| ListQuery.Workflow.WithScopes
|
||||
| ListQuery.Credentials.WithScopes {
|
||||
const shared = rawEntity.shared;
|
||||
const entity = rawEntity as ListQuery.Workflow.WithScopes | ListQuery.Credentials.WithScopes;
|
||||
const entity = rawEntity as
|
||||
| (CredentialsEntity & ScopesField)
|
||||
| ListQuery.Workflow.WithScopes
|
||||
| ListQuery.Credentials.WithScopes;
|
||||
|
||||
Object.assign(entity, {
|
||||
scopes: [],
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
|
||||
import type { AuthIdentity } from '@/databases/entities/auth-identity';
|
||||
import { User } from '@/databases/entities/user';
|
||||
import { AuthIdentityRepository } from '@/databases/repositories/auth-identity.repository';
|
||||
import { UserRepository } from '@/databases/repositories/user.repository';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
import * as helpers from '@/sso.ee/saml/saml-helpers';
|
||||
import type { SamlUserAttributes } from '@/sso.ee/saml/types';
|
||||
import { mockInstance } from '@test/mocking';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { GlobalRole, Scope } from '@n8n/permissions';
|
||||
import type express from 'express';
|
||||
import type {
|
||||
ICredentialsEncrypted,
|
||||
IRunExecutionData,
|
||||
@@ -7,10 +8,16 @@ import type {
|
||||
ExecutionStatus,
|
||||
FeatureFlags,
|
||||
IUserSettings,
|
||||
DeduplicationMode,
|
||||
DeduplicationItemTypes,
|
||||
AnnotationVote,
|
||||
ExecutionSummary,
|
||||
IUser,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import type { AnnotationTagEntity } from '@/databases/entities/annotation-tag-entity.ee';
|
||||
import type { AuthProviderType } from '@/databases/entities/auth-identity';
|
||||
import type { CredentialsEntity } from '@/databases/entities/credentials-entity';
|
||||
import type { Folder } from '@/databases/entities/folder';
|
||||
import type { Project } from '@/databases/entities/project';
|
||||
import type { SharedCredentials } from '@/databases/entities/shared-credentials';
|
||||
@@ -140,3 +147,176 @@ export interface WorkflowWithSharingsMetaDataAndCredentials extends Omit<Workflo
|
||||
sharedWithProjects: SlimProject[];
|
||||
usedCredentials?: CredentialUsedByWorkflow[];
|
||||
}
|
||||
|
||||
export interface IProcessedDataLatest {
|
||||
mode: DeduplicationMode;
|
||||
data: DeduplicationItemTypes;
|
||||
}
|
||||
|
||||
export interface IProcessedDataEntries {
|
||||
mode: DeduplicationMode;
|
||||
data: DeduplicationItemTypes[];
|
||||
}
|
||||
|
||||
/** Payload for creating an execution. */
|
||||
export type CreateExecutionPayload = Omit<IExecutionDb, 'id' | 'createdAt' | 'startedAt'>;
|
||||
|
||||
// Data in regular format with references
|
||||
export interface IExecutionDb extends IExecutionBase {
|
||||
data: IRunExecutionData;
|
||||
workflowData: IWorkflowBase;
|
||||
}
|
||||
|
||||
export interface IExecutionFlattedDb extends IExecutionBase {
|
||||
id: string;
|
||||
data: string;
|
||||
workflowData: Omit<IWorkflowBase, 'pinData'>;
|
||||
customData: Record<string, string>;
|
||||
}
|
||||
|
||||
export namespace ExecutionSummaries {
|
||||
export type Query = RangeQuery | CountQuery;
|
||||
|
||||
export type RangeQuery = { kind: 'range' } & FilterFields &
|
||||
AccessFields &
|
||||
RangeFields &
|
||||
OrderFields;
|
||||
|
||||
export type CountQuery = { kind: 'count' } & FilterFields & AccessFields;
|
||||
|
||||
type FilterFields = Partial<{
|
||||
id: string;
|
||||
finished: boolean;
|
||||
mode: string;
|
||||
retryOf: string;
|
||||
retrySuccessId: string;
|
||||
status: ExecutionStatus[];
|
||||
workflowId: string;
|
||||
waitTill: boolean;
|
||||
metadata: Array<{ key: string; value: string }>;
|
||||
startedAfter: string;
|
||||
startedBefore: string;
|
||||
annotationTags: string[]; // tag IDs
|
||||
vote: AnnotationVote;
|
||||
projectId: string;
|
||||
}>;
|
||||
|
||||
type AccessFields = {
|
||||
accessibleWorkflowIds?: string[];
|
||||
};
|
||||
|
||||
type RangeFields = {
|
||||
range: {
|
||||
limit: number;
|
||||
firstId?: string;
|
||||
lastId?: string;
|
||||
};
|
||||
};
|
||||
|
||||
type OrderFields = {
|
||||
order?: {
|
||||
top?: ExecutionStatus;
|
||||
startedAt?: 'DESC';
|
||||
};
|
||||
};
|
||||
|
||||
export type ExecutionSummaryWithScopes = ExecutionSummary & { scopes: Scope[] };
|
||||
}
|
||||
|
||||
export type APIRequest<
|
||||
RouteParams = {},
|
||||
ResponseBody = {},
|
||||
RequestBody = {},
|
||||
RequestQuery = {},
|
||||
> = express.Request<RouteParams, ResponseBody, RequestBody, RequestQuery> & {
|
||||
browserId?: string;
|
||||
};
|
||||
|
||||
export type AuthenticatedRequest<
|
||||
RouteParams = {},
|
||||
ResponseBody = {},
|
||||
RequestBody = {},
|
||||
RequestQuery = {},
|
||||
> = Omit<APIRequest<RouteParams, ResponseBody, RequestBody, RequestQuery>, 'user' | 'cookies'> & {
|
||||
user: User;
|
||||
cookies: Record<string, string | undefined>;
|
||||
headers: express.Request['headers'] & {
|
||||
'push-ref': string;
|
||||
};
|
||||
};
|
||||
|
||||
export namespace ListQuery {
|
||||
export type Request = AuthenticatedRequest<{}, {}, {}, Params> & {
|
||||
listQueryOptions?: Options;
|
||||
};
|
||||
|
||||
export type Params = {
|
||||
filter?: string;
|
||||
skip?: string;
|
||||
take?: string;
|
||||
select?: string;
|
||||
sortBy?: string;
|
||||
};
|
||||
|
||||
export type Options = {
|
||||
filter?: Record<string, unknown>;
|
||||
select?: Record<string, true>;
|
||||
skip?: number;
|
||||
take?: number;
|
||||
sortBy?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Slim workflow returned from a list query operation.
|
||||
*/
|
||||
export namespace Workflow {
|
||||
type OptionalBaseFields = 'name' | 'active' | 'versionId' | 'createdAt' | 'updatedAt' | 'tags';
|
||||
|
||||
type BaseFields = Pick<WorkflowEntity, 'id'> &
|
||||
Partial<Pick<WorkflowEntity, OptionalBaseFields>>;
|
||||
|
||||
type SharedField = Partial<Pick<WorkflowEntity, 'shared'>>;
|
||||
|
||||
type SortingField = 'createdAt' | 'updatedAt' | 'name';
|
||||
|
||||
export type SortOrder = `${SortingField}:asc` | `${SortingField}:desc`;
|
||||
|
||||
type OwnedByField = { ownedBy: SlimUser | null; homeProject: SlimProject | null };
|
||||
|
||||
export type Plain = BaseFields;
|
||||
|
||||
export type WithSharing = BaseFields & SharedField;
|
||||
|
||||
export type WithOwnership = BaseFields & OwnedByField;
|
||||
|
||||
type SharedWithField = { sharedWith: SlimUser[]; sharedWithProjects: SlimProject[] };
|
||||
|
||||
export type WithOwnedByAndSharedWith = BaseFields &
|
||||
OwnedByField &
|
||||
SharedWithField &
|
||||
SharedField;
|
||||
|
||||
export type WithScopes = BaseFields & ScopesField & SharedField;
|
||||
}
|
||||
|
||||
export namespace Credentials {
|
||||
type OwnedByField = { homeProject: SlimProject | null };
|
||||
|
||||
type SharedField = Partial<Pick<CredentialsEntity, 'shared'>>;
|
||||
|
||||
type SharedWithField = { sharedWithProjects: SlimProject[] };
|
||||
|
||||
export type WithSharing = CredentialsEntity & SharedField;
|
||||
|
||||
export type WithOwnedByAndSharedWith = CredentialsEntity &
|
||||
OwnedByField &
|
||||
SharedWithField &
|
||||
SharedField;
|
||||
|
||||
export type WithScopes = CredentialsEntity & ScopesField & SharedField;
|
||||
}
|
||||
}
|
||||
|
||||
type SlimUser = Pick<IUser, 'id' | 'email' | 'firstName' | 'lastName'>;
|
||||
|
||||
export type ScopesField = { scopes: Scope[] };
|
||||
|
||||
@@ -39,23 +39,10 @@ export const findSubworkflowStart = findWorkflowStart('integrated');
|
||||
|
||||
export const findCliWorkflowStart = findWorkflowStart('cli');
|
||||
|
||||
export const separate = <T>(array: T[], test: (element: T) => boolean) => {
|
||||
const pass: T[] = [];
|
||||
const fail: T[] = [];
|
||||
|
||||
array.forEach((i) => (test(i) ? pass : fail).push(i));
|
||||
|
||||
return [pass, fail];
|
||||
};
|
||||
|
||||
export const toError = (maybeError: unknown) =>
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
maybeError instanceof Error ? maybeError : new Error(`${maybeError}`);
|
||||
|
||||
export function isStringArray(value: unknown): value is string[] {
|
||||
return Array.isArray(value) && value.every((item) => typeof item === 'string');
|
||||
}
|
||||
|
||||
export const isIntegerString = (value: string) => /^\d+$/.test(value);
|
||||
|
||||
export function removeTrailingSlash(path: string) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
import type * as express from 'express';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { ITaskData, IWorkflowBase } from 'n8n-workflow';
|
||||
@@ -8,7 +9,6 @@ import {
|
||||
} from 'n8n-workflow';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import { WebhookNotFoundError } from '@/errors/response-errors/webhook-not-found.error';
|
||||
import type {
|
||||
|
||||
@@ -23,8 +23,9 @@ import { ExecutionRepository } from '@/databases/repositories/execution.reposito
|
||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { ExecutionDataService } from '@/executions/execution-data.service';
|
||||
import { SubworkflowPolicyChecker } from '@/executions/pre-execution-checks';
|
||||
import type { CreateExecutionPayload, IWorkflowErrorData } from '@/interfaces';
|
||||
import type { IWorkflowErrorData } from '@/interfaces';
|
||||
import { NodeTypes } from '@/node-types';
|
||||
import type { CreateExecutionPayload } from '@/types-db';
|
||||
import { TestWebhooks } from '@/webhooks/test-webhooks';
|
||||
import * as WorkflowExecuteAdditionalData from '@/workflow-execute-additional-data';
|
||||
import { WorkflowRunner } from '@/workflow-runner';
|
||||
|
||||
@@ -8,7 +8,8 @@ import type {
|
||||
IWorkflowBase,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import type { AuthenticatedRequest, ListQuery } from '@/requests';
|
||||
import type { AuthenticatedRequest } from '@/requests';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
export declare namespace WorkflowRequest {
|
||||
type CreateUpdatePayload = Partial<{
|
||||
|
||||
@@ -27,13 +27,14 @@ import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import { EventService } from '@/events/event.service';
|
||||
import { ExternalHooks } from '@/external-hooks';
|
||||
import { validateEntity } from '@/generic-helpers';
|
||||
import { hasSharing, type ListQuery } from '@/requests';
|
||||
import { hasSharing } from '@/requests';
|
||||
import { FolderService } from '@/services/folder.service';
|
||||
import { OrchestrationService } from '@/services/orchestration.service';
|
||||
import { OwnershipService } from '@/services/ownership.service';
|
||||
import { ProjectService } from '@/services/project.service.ee';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { TagService } from '@/services/tag.service';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
import * as WorkflowHelpers from '@/workflow-helpers';
|
||||
|
||||
import { WorkflowFinderService } from './workflow-finder.service';
|
||||
|
||||
@@ -8,8 +8,8 @@ import type { Project } from '@/databases/entities/project';
|
||||
import type { User } from '@/databases/entities/user';
|
||||
import { ProjectRepository } from '@/databases/repositories/project.repository';
|
||||
import { SharedCredentialsRepository } from '@/databases/repositories/shared-credentials.repository';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import { ProjectService } from '@/services/project.service.ee';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
import { UserManagementMailer } from '@/user-management/email';
|
||||
import { createWorkflow, shareWorkflowWithUsers } from '@test-integration/db/workflows';
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ import type { User } from '@/databases/entities/user';
|
||||
import { CredentialsRepository } from '@/databases/repositories/credentials.repository';
|
||||
import { ProjectRepository } from '@/databases/repositories/project.repository';
|
||||
import { SharedCredentialsRepository } from '@/databases/repositories/shared-credentials.repository';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import { CredentialsTester } from '@/services/credentials-tester.service';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
|
||||
import {
|
||||
decryptCredentialData,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
import { InstanceSettings } from 'n8n-core';
|
||||
|
||||
import { ActiveWorkflowManager } from '@/active-workflow-manager';
|
||||
import type { WorkflowEntity } from '@/databases/entities/workflow-entity';
|
||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
import { MultiMainSetup } from '@/scaling/multi-main-setup.ee';
|
||||
|
||||
import { createOwner } from './shared/db/users';
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ExecutionMetadataRepository } from '@/databases/repositories/execution-
|
||||
import { ExecutionRepository } from '@/databases/repositories/execution.repository';
|
||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { ExecutionService } from '@/executions/execution.service';
|
||||
import type { ExecutionSummaries } from '@/executions/execution.types';
|
||||
import type { ExecutionSummaries } from '@/types-db';
|
||||
import { createTeamProject } from '@test-integration/db/projects';
|
||||
|
||||
import { annotateExecution, createAnnotationTags, createExecution } from './shared/db/executions';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { SecurityConfig } from '@n8n/config';
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
@@ -7,7 +8,6 @@ import { CredentialsRepository } from '@/databases/repositories/credentials.repo
|
||||
import { ExecutionDataRepository } from '@/databases/repositories/execution-data.repository';
|
||||
import { ExecutionRepository } from '@/databases/repositories/execution.repository';
|
||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
import { CREDENTIALS_REPORT } from '@/security-audit/constants';
|
||||
import { SecurityAuditService } from '@/security-audit/security-audit.service';
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
import {
|
||||
DATABASE_REPORT,
|
||||
SQL_NODE_TYPES,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { GlobalConfig } from '@n8n/config';
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import { NodeConnectionTypes } from 'n8n-workflow';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
import { INSTANCE_REPORT, WEBHOOK_VALIDATOR_NODE_TYPES } from '@/security-audit/constants';
|
||||
import { SecurityAuditService } from '@/security-audit/security-audit.service';
|
||||
import { toReportTitle } from '@/security-audit/utils';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
import type { IWorkflowBase } from 'n8n-workflow';
|
||||
|
||||
@@ -5,7 +6,6 @@ import type { TagEntity } from '@/databases/entities/tag-entity';
|
||||
import type { WorkflowEntity } from '@/databases/entities/workflow-entity';
|
||||
import { TagRepository } from '@/databases/repositories/tag.repository';
|
||||
import { WorkflowTagMappingRepository } from '@/databases/repositories/workflow-tag-mapping.repository';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
|
||||
import { randomName } from '../random';
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
import { randomString } from 'n8n-workflow';
|
||||
|
||||
import { VariablesRepository } from '@/databases/repositories/variables.repository';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
|
||||
export async function createVariable(key = randomString(5), value = randomString(5)) {
|
||||
return await Container.get(VariablesRepository).save({ id: generateNanoId(), key, value });
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { generateNanoId } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
|
||||
import type { Variables } from '@/databases/entities/variables';
|
||||
import { VariablesRepository } from '@/databases/repositories/variables.repository';
|
||||
import { generateNanoId } from '@/databases/utils/generators';
|
||||
import { VariablesService } from '@/environments.ee/variables/variables.service.ee';
|
||||
import { CacheService } from '@/services/cache/cache.service';
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ import { WorkflowHistoryRepository } from '@/databases/repositories/workflow-his
|
||||
import type { WorkflowFolderUnionFull } from '@/databases/repositories/workflow.repository';
|
||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { License } from '@/license';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import { ProjectService } from '@/services/project.service.ee';
|
||||
import type { ListQuery } from '@/types-db';
|
||||
import { EnterpriseWorkflowService } from '@/workflows/workflow.service.ee';
|
||||
import { createFolder } from '@test-integration/db/folders';
|
||||
|
||||
|
||||
68
pnpm-lock.yaml
generated
68
pnpm-lock.yaml
generated
@@ -18,6 +18,9 @@ catalogs:
|
||||
'@langchain/openai':
|
||||
specifier: 0.3.17
|
||||
version: 0.3.17
|
||||
'@n8n/typeorm':
|
||||
specifier: 0.3.20-12
|
||||
version: 0.3.20-12
|
||||
'@n8n_io/ai-assistant-sdk':
|
||||
specifier: 1.14.0
|
||||
version: 1.14.0
|
||||
@@ -463,6 +466,24 @@ importers:
|
||||
|
||||
packages/@n8n/db:
|
||||
dependencies:
|
||||
'@n8n/config':
|
||||
specifier: workspace:^
|
||||
version: link:../config
|
||||
'@n8n/di':
|
||||
specifier: workspace:^
|
||||
version: link:../di
|
||||
'@n8n/typeorm':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.14)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@18.16.16)(typescript@5.8.2))
|
||||
n8n-core:
|
||||
specifier: workspace:^
|
||||
version: link:../../core
|
||||
n8n-workflow:
|
||||
specifier: workspace:^
|
||||
version: link:../../workflow
|
||||
nanoid:
|
||||
specifier: 'catalog:'
|
||||
version: 3.3.8
|
||||
reflect-metadata:
|
||||
specifier: 'catalog:'
|
||||
version: 0.2.2
|
||||
@@ -647,7 +668,7 @@ importers:
|
||||
version: 3.666.0(@aws-sdk/client-sts@3.666.0)
|
||||
'@getzep/zep-cloud':
|
||||
specifier: 1.0.12
|
||||
version: 1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(73c39badb3fd5b3eb4d1084b1fb22de6))
|
||||
version: 1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(e320b1d8e94e7308fefdef3743329630))
|
||||
'@getzep/zep-js':
|
||||
specifier: 0.9.0
|
||||
version: 0.9.0
|
||||
@@ -674,7 +695,7 @@ importers:
|
||||
version: 0.3.2(@aws-sdk/client-sso-oidc@3.666.0(@aws-sdk/client-sts@3.666.0))(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
|
||||
'@langchain/community':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.24(d72b3dbd91eb98a3175f929d13e7c0a7)
|
||||
version: 0.3.24(a23560be5fb93c23c5c4ed2a6b67082b)
|
||||
'@langchain/core':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
|
||||
@@ -773,7 +794,7 @@ importers:
|
||||
version: 23.0.1
|
||||
langchain:
|
||||
specifier: 0.3.11
|
||||
version: 0.3.11(73c39badb3fd5b3eb4d1084b1fb22de6)
|
||||
version: 0.3.11(e320b1d8e94e7308fefdef3743329630)
|
||||
lodash:
|
||||
specifier: 'catalog:'
|
||||
version: 4.17.21
|
||||
@@ -1040,7 +1061,7 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:../@n8n/task-runner
|
||||
'@n8n/typeorm':
|
||||
specifier: 0.3.20-12
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.14)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@18.16.16)(typescript@5.8.2))
|
||||
'@n8n_io/ai-assistant-sdk':
|
||||
specifier: 'catalog:'
|
||||
@@ -8047,15 +8068,6 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
debug@4.3.7:
|
||||
resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
debug@4.4.0:
|
||||
resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
|
||||
engines: {node: '>=6.0'}
|
||||
@@ -16323,7 +16335,7 @@ snapshots:
|
||||
'@gar/promisify@1.1.3':
|
||||
optional: true
|
||||
|
||||
'@getzep/zep-cloud@1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(73c39badb3fd5b3eb4d1084b1fb22de6))':
|
||||
'@getzep/zep-cloud@1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(e320b1d8e94e7308fefdef3743329630))':
|
||||
dependencies:
|
||||
form-data: 4.0.0
|
||||
node-fetch: 2.7.0(encoding@0.1.13)
|
||||
@@ -16332,7 +16344,7 @@ snapshots:
|
||||
zod: 3.24.1
|
||||
optionalDependencies:
|
||||
'@langchain/core': 0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
|
||||
langchain: 0.3.11(73c39badb3fd5b3eb4d1084b1fb22de6)
|
||||
langchain: 0.3.11(e320b1d8e94e7308fefdef3743329630)
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
@@ -16847,7 +16859,7 @@ snapshots:
|
||||
- aws-crt
|
||||
- encoding
|
||||
|
||||
'@langchain/community@0.3.24(d72b3dbd91eb98a3175f929d13e7c0a7)':
|
||||
'@langchain/community@0.3.24(a23560be5fb93c23c5c4ed2a6b67082b)':
|
||||
dependencies:
|
||||
'@browserbasehq/stagehand': 1.9.0(@playwright/test@1.49.1)(deepmerge@4.3.1)(dotenv@16.4.5)(encoding@0.1.13)(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))(zod@3.24.1)
|
||||
'@ibm-cloud/watsonx-ai': 1.1.2
|
||||
@@ -16858,7 +16870,7 @@ snapshots:
|
||||
flat: 5.0.2
|
||||
ibm-cloud-sdk-core: 5.3.2
|
||||
js-yaml: 4.1.0
|
||||
langchain: 0.3.11(73c39badb3fd5b3eb4d1084b1fb22de6)
|
||||
langchain: 0.3.11(e320b1d8e94e7308fefdef3743329630)
|
||||
langsmith: 0.2.15(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
|
||||
openai: 4.78.1(encoding@0.1.13)(zod@3.24.1)
|
||||
uuid: 10.0.0
|
||||
@@ -16873,7 +16885,7 @@ snapshots:
|
||||
'@aws-sdk/credential-provider-node': 3.666.0(@aws-sdk/client-sso-oidc@3.666.0(@aws-sdk/client-sts@3.666.0))(@aws-sdk/client-sts@3.666.0)
|
||||
'@azure/storage-blob': 12.18.0(encoding@0.1.13)
|
||||
'@browserbasehq/sdk': 2.0.0(encoding@0.1.13)
|
||||
'@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(73c39badb3fd5b3eb4d1084b1fb22de6))
|
||||
'@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(e320b1d8e94e7308fefdef3743329630))
|
||||
'@getzep/zep-js': 0.9.0
|
||||
'@google-ai/generativelanguage': 2.6.0(encoding@0.1.13)
|
||||
'@google-cloud/storage': 7.12.1(encoding@0.1.13)
|
||||
@@ -17255,8 +17267,8 @@ snapshots:
|
||||
buffer: 6.0.3
|
||||
chalk: 4.1.2
|
||||
dayjs: 1.11.10
|
||||
debug: 4.3.7
|
||||
dotenv: 16.3.1
|
||||
debug: 4.4.0(supports-color@8.1.1)
|
||||
dotenv: 16.4.5
|
||||
glob: 10.4.5
|
||||
mkdirp: 2.1.3
|
||||
reflect-metadata: 0.2.2
|
||||
@@ -17287,8 +17299,8 @@ snapshots:
|
||||
buffer: 6.0.3
|
||||
chalk: 4.1.2
|
||||
dayjs: 1.11.10
|
||||
debug: 4.3.7
|
||||
dotenv: 16.3.1
|
||||
debug: 4.4.0(supports-color@8.1.1)
|
||||
dotenv: 16.4.5
|
||||
glob: 10.4.5
|
||||
mkdirp: 2.1.3
|
||||
reflect-metadata: 0.2.2
|
||||
@@ -21342,10 +21354,6 @@ snapshots:
|
||||
optionalDependencies:
|
||||
supports-color: 8.1.1
|
||||
|
||||
debug@4.3.7:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
debug@4.4.0(supports-color@8.1.1):
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
@@ -23071,7 +23079,7 @@ snapshots:
|
||||
'@types/debug': 4.1.12
|
||||
'@types/node': 18.16.16
|
||||
'@types/tough-cookie': 4.0.2
|
||||
axios: 1.8.3(debug@4.4.0)
|
||||
axios: 1.8.3
|
||||
camelcase: 6.3.0
|
||||
debug: 4.4.0(supports-color@8.1.1)
|
||||
dotenv: 16.4.5
|
||||
@@ -23081,7 +23089,7 @@ snapshots:
|
||||
isstream: 0.1.2
|
||||
jsonwebtoken: 9.0.2
|
||||
mime-types: 2.1.35
|
||||
retry-axios: 2.6.0(axios@1.8.3)
|
||||
retry-axios: 2.6.0(axios@1.8.3(debug@4.4.0))
|
||||
tough-cookie: 4.1.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -24075,7 +24083,7 @@ snapshots:
|
||||
|
||||
kuler@2.0.0: {}
|
||||
|
||||
langchain@0.3.11(73c39badb3fd5b3eb4d1084b1fb22de6):
|
||||
langchain@0.3.11(e320b1d8e94e7308fefdef3743329630):
|
||||
dependencies:
|
||||
'@langchain/core': 0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
|
||||
'@langchain/openai': 0.3.17(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
|
||||
@@ -26448,7 +26456,7 @@ snapshots:
|
||||
onetime: 5.1.2
|
||||
signal-exit: 3.0.7
|
||||
|
||||
retry-axios@2.6.0(axios@1.8.3):
|
||||
retry-axios@2.6.0(axios@1.8.3(debug@4.4.0)):
|
||||
dependencies:
|
||||
axios: 1.8.3
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ packages:
|
||||
- cypress
|
||||
|
||||
catalog:
|
||||
'@n8n/typeorm': 0.3.20-12
|
||||
'@sentry/node': 8.52.1
|
||||
'@types/basic-auth': ^1.1.3
|
||||
'@types/express': ^5.0.1
|
||||
|
||||
Reference in New Issue
Block a user