refactor(core): Separate list query entities from request types (#15015)

This commit is contained in:
Iván Ovejero
2025-04-30 13:34:50 +02:00
committed by GitHub
parent b4a06aaff9
commit 442cd094ee
28 changed files with 120 additions and 135 deletions

View File

@@ -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 {

View File

@@ -27,11 +27,10 @@ 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, UserRequest } from '@/requests';
import { ListQuery, 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';

View File

@@ -33,12 +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 } from '@/requests';
import type { CredentialRequest, ListQuery } from '@/requests';
import { CredentialsTester } from '@/services/credentials-tester.service';
import { OwnershipService } from '@/services/ownership.service';
import { ProjectService } from '@/services/project.service.ee';
import { RoleService } from '@/services/role.service';
import type { ICredentialsDb, ListQuery, ScopesField } from '@/types-db';
import type { ICredentialsDb, ScopesField } from '@/types-db';
import { CredentialsFinderService } from './credentials-finder.service';

View File

@@ -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 '@/types-db';
import type { ListQuery } from '@/requests';
import { CredentialsEntity } from '../entities/credentials-entity';

View File

@@ -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 '@/types-db';
import type { ListQuery } from '@/requests';
import type { FolderWithWorkflowAndSubFolderCount } from '../entities/folder';
import { Folder } from '../entities/folder';

View File

@@ -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 '@/types-db';
import type { ListQuery } from '@/requests';
@Service()
export class TestDefinitionRepository extends Repository<TestDefinition> {

View File

@@ -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 '@/types-db';
import type { ListQuery } from '@/requests';
export type TestRunFinalResult = 'success' | 'error' | 'warning';

View File

@@ -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 '@/types-db';
import type { ListQuery } from '@/requests';
import { Project } from '../entities/project';
import { ProjectRelation } from '../entities/project-relation';

View File

@@ -13,7 +13,8 @@ import type {
} from '@n8n/typeorm';
import { PROJECT_ROOT } from 'n8n-workflow';
import type { ListQuery } from '@/types-db';
import type { ListQuery } from '@/requests';
import type { ListQueryDb } from '@/types-db';
import { FolderRepository } from './folder.repository';
import type { Folder, FolderWithWorkflowAndSubFolderCount } from '../entities/folder';
@@ -33,8 +34,8 @@ type WorkflowFolderUnionRow = {
};
export type WorkflowFolderUnionFull = (
| ListQuery.Workflow.Plain
| ListQuery.Workflow.WithSharing
| ListQueryDb.Workflow.Plain
| ListQueryDb.Workflow.WithSharing
| FolderWithWorkflowAndSubFolderCount
) & {
resource: ResourceType;
@@ -320,7 +321,7 @@ export class WorkflowRepository extends Repository<WorkflowEntity> {
private enrichDataWithExtras(
baseData: WorkflowFolderUnionRow[],
extraData: {
workflows: ListQuery.Workflow.WithSharing[] | ListQuery.Workflow.Plain[];
workflows: ListQueryDb.Workflow.WithSharing[] | ListQueryDb.Workflow.Plain[];
folders: Folder[];
},
): WorkflowFolderUnionFull[] {
@@ -343,8 +344,8 @@ export class WorkflowRepository extends Repository<WorkflowEntity> {
const query = this.getManyQuery(workflowIds, options);
const workflows = (await query.getMany()) as
| ListQuery.Workflow.Plain[]
| ListQuery.Workflow.WithSharing[];
| ListQueryDb.Workflow.Plain[]
| ListQueryDb.Workflow.WithSharing[];
return workflows;
}
@@ -357,7 +358,7 @@ export class WorkflowRepository extends Repository<WorkflowEntity> {
const query = this.getManyQuery(sharedWorkflowIds, options);
const [workflows, count] = (await query.getManyAndCount()) as [
ListQuery.Workflow.Plain[] | ListQuery.Workflow.WithSharing[],
ListQueryDb.Workflow.Plain[] | ListQueryDb.Workflow.WithSharing[],
number,
];

View File

@@ -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>,

View File

@@ -1,6 +1,5 @@
import type { MockedNodeItem } from '@/databases/entities/test-definition.ee';
import type { AuthenticatedRequest } from '@/requests';
import type { ListQuery } from '@/types-db';
import type { AuthenticatedRequest, ListQuery } from '@/requests';
// ----------------------------------
// /test-definitions

View File

@@ -3,8 +3,9 @@ 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 type { ListQueryDb } from '@/types-db';
import { sortByQueryMiddleware } from '../sort-by';
@@ -177,7 +178,7 @@ describe('List query middleware', () => {
});
describe('Query sort by', () => {
const validCases: Array<{ name: string; value: ListQuery.Workflow.SortOrder }> = [
const validCases: Array<{ name: string; value: ListQueryDb.Workflow.SortOrder }> = [
{
name: 'sorting by name asc',
value: 'name:asc',
@@ -236,7 +237,7 @@ describe('List query middleware', () => {
test.each(invalidCases)('should fail validation when $name', async ({ value }) => {
mockReq.query = {
sortBy: value as ListQuery.Workflow.SortOrder,
sortBy: value as ListQueryDb.Workflow.SortOrder,
};
await sortByQueryMiddleware(...args);

View File

@@ -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';

View File

@@ -1,6 +1,6 @@
import { type NextFunction, type Response } from 'express';
import type { ListQuery } from '@/types-db';
import type { ListQuery } from '@/requests';
import { filterListQueryMiddleware } from './filter';
import { paginationListQueryMiddleware } from './pagination';

View File

@@ -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';

View File

@@ -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';

View File

@@ -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';

View File

@@ -11,7 +11,8 @@ import type {
import type { Project } from '@/databases/entities/project';
import type { User } from '@/databases/entities/user';
import type { WorkflowHistory } from '@/databases/entities/workflow-history';
import type { ListQuery } from '@/types-db';
import type { ListQueryDb } from './types-db';
export type APIRequest<
RouteParams = {},
@@ -42,13 +43,35 @@ export type AuthenticatedRequest<
};
};
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;
};
}
// ----------------------------------
// list query
// ----------------------------------
export function hasSharing(
workflows: ListQuery.Workflow.Plain[] | ListQuery.Workflow.WithSharing[],
): workflows is ListQuery.Workflow.WithSharing[] {
workflows: ListQueryDb.Workflow.Plain[] | ListQueryDb.Workflow.WithSharing[],
): workflows is ListQueryDb.Workflow.WithSharing[] {
return workflows.some((w) => 'shared' in w);
}

View File

@@ -3,7 +3,10 @@ import { Service } from '@n8n/di';
import type { AnnotationTagEntity } from '@/databases/entities/annotation-tag-entity.ee';
import { AnnotationTagRepository } from '@/databases/repositories/annotation-tag.repository.ee';
import { validateEntity } from '@/generic-helpers';
import type { IAnnotationTagDb, IAnnotationTagWithCountDb } from '@/types-db';
type IAnnotationTagDb = Pick<AnnotationTagEntity, 'id' | 'name' | 'createdAt' | 'updatedAt'>;
type IAnnotationTagWithCountDb = IAnnotationTagDb & { usageCount: number };
type GetAllResult<T> = T extends { withUsageCount: true }
? IAnnotationTagWithCountDb[]

View File

@@ -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 '@/types-db';
import type { ListQuery } from '@/requests';
export interface SimpleFolderNode {
id: string;

View File

@@ -7,7 +7,7 @@ import { ProjectRepository } from '@/databases/repositories/project.repository';
import { SharedWorkflowRepository } from '@/databases/repositories/shared-workflow.repository';
import { UserRepository } from '@/databases/repositories/user.repository';
import { CacheService } from '@/services/cache/cache.service';
import type { ListQuery } from '@/types-db';
import type { ListQueryDb } from '@/types-db';
@Service()
export class OwnershipService {
@@ -57,18 +57,20 @@ export class OwnershipService {
}
addOwnedByAndSharedWith(
rawWorkflow: ListQuery.Workflow.WithSharing,
): ListQuery.Workflow.WithOwnedByAndSharedWith;
rawWorkflow: ListQueryDb.Workflow.WithSharing,
): ListQueryDb.Workflow.WithOwnedByAndSharedWith;
addOwnedByAndSharedWith(
rawCredential: ListQuery.Credentials.WithSharing,
): ListQuery.Credentials.WithOwnedByAndSharedWith;
rawCredential: ListQueryDb.Credentials.WithSharing,
): ListQueryDb.Credentials.WithOwnedByAndSharedWith;
addOwnedByAndSharedWith(
rawEntity: ListQuery.Workflow.WithSharing | ListQuery.Credentials.WithSharing,
): ListQuery.Workflow.WithOwnedByAndSharedWith | ListQuery.Credentials.WithOwnedByAndSharedWith {
rawEntity: ListQueryDb.Workflow.WithSharing | ListQueryDb.Credentials.WithSharing,
):
| ListQueryDb.Workflow.WithOwnedByAndSharedWith
| ListQueryDb.Credentials.WithOwnedByAndSharedWith {
const shared = rawEntity.shared;
const entity = rawEntity as
| ListQuery.Workflow.WithOwnedByAndSharedWith
| ListQuery.Credentials.WithOwnedByAndSharedWith;
| ListQueryDb.Workflow.WithOwnedByAndSharedWith
| ListQueryDb.Credentials.WithOwnedByAndSharedWith;
Object.assign(entity, {
homeProject: null,

View File

@@ -30,7 +30,7 @@ import {
WORKFLOW_SHARING_EDITOR_SCOPES,
WORKFLOW_SHARING_OWNER_SCOPES,
} from '@/permissions.ee/resource-roles';
import type { ListQuery, ScopesField } from '@/types-db';
import type { ListQueryDb, ScopesField } from '@/types-db';
export type RoleNamespace = 'global' | 'project' | 'credential' | 'workflow';
@@ -159,10 +159,10 @@ export class RoleService {
}
addScopes(
rawWorkflow: ListQuery.Workflow.WithSharing | ListQuery.Workflow.WithOwnedByAndSharedWith,
rawWorkflow: ListQueryDb.Workflow.WithSharing | ListQueryDb.Workflow.WithOwnedByAndSharedWith,
user: User,
userProjectRelations: ProjectRelation[],
): ListQuery.Workflow.WithScopes;
): ListQueryDb.Workflow.WithScopes;
addScopes(
rawCredential: CredentialsEntity,
user: User,
@@ -170,29 +170,29 @@ export class RoleService {
): CredentialsEntity & ScopesField;
addScopes(
rawCredential:
| ListQuery.Credentials.WithSharing
| ListQuery.Credentials.WithOwnedByAndSharedWith,
| ListQueryDb.Credentials.WithSharing
| ListQueryDb.Credentials.WithOwnedByAndSharedWith,
user: User,
userProjectRelations: ProjectRelation[],
): ListQuery.Credentials.WithScopes;
): ListQueryDb.Credentials.WithScopes;
addScopes(
rawEntity:
| CredentialsEntity
| ListQuery.Workflow.WithSharing
| ListQuery.Credentials.WithOwnedByAndSharedWith
| ListQuery.Credentials.WithSharing
| ListQuery.Workflow.WithOwnedByAndSharedWith,
| ListQueryDb.Workflow.WithSharing
| ListQueryDb.Credentials.WithOwnedByAndSharedWith
| ListQueryDb.Credentials.WithSharing
| ListQueryDb.Workflow.WithOwnedByAndSharedWith,
user: User,
userProjectRelations: ProjectRelation[],
):
| (CredentialsEntity & ScopesField)
| ListQuery.Workflow.WithScopes
| ListQuery.Credentials.WithScopes {
| ListQueryDb.Workflow.WithScopes
| ListQueryDb.Credentials.WithScopes {
const shared = rawEntity.shared;
const entity = rawEntity as
| (CredentialsEntity & ScopesField)
| ListQuery.Workflow.WithScopes
| ListQuery.Credentials.WithScopes;
| ListQueryDb.Workflow.WithScopes
| ListQueryDb.Credentials.WithScopes;
Object.assign(entity, {
scopes: [],

View File

@@ -1,5 +1,4 @@
import type { GlobalRole, Scope } from '@n8n/permissions';
import type express from 'express';
import type {
ICredentialsEncrypted,
IRunExecutionData,
@@ -13,7 +12,6 @@ import type {
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';
@@ -71,10 +69,6 @@ export type ITagDb = Pick<TagEntity, 'id' | 'name' | 'createdAt' | 'updatedAt'>;
export type ITagWithCountDb = ITagDb & UsageCount;
export type IAnnotationTagDb = Pick<AnnotationTagEntity, 'id' | 'name' | 'createdAt' | 'updatedAt'>;
export type IAnnotationTagWithCountDb = IAnnotationTagDb & UsageCount;
// Almost identical to editor-ui.Interfaces.ts
export interface IWorkflowDb extends IWorkflowBase {
triggerCount: number;
@@ -211,49 +205,7 @@ export namespace ExecutionSummaries {
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;
};
export namespace ListQueryDb {
/**
* Slim workflow returned from a list query operation.
*/

View File

@@ -8,8 +8,7 @@ import type {
IWorkflowBase,
} from 'n8n-workflow';
import type { AuthenticatedRequest } from '@/requests';
import type { ListQuery } from '@/types-db';
import type { AuthenticatedRequest, ListQuery } from '@/requests';
export declare namespace WorkflowRequest {
type CreateUpdatePayload = Partial<{

View File

@@ -27,6 +27,7 @@ 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 type { ListQuery } from '@/requests';
import { hasSharing } from '@/requests';
import { FolderService } from '@/services/folder.service';
import { OrchestrationService } from '@/services/orchestration.service';
@@ -34,7 +35,7 @@ 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 type { ListQueryDb } from '@/types-db';
import * as WorkflowHelpers from '@/workflow-helpers';
import { WorkflowFinderService } from './workflow-finder.service';
@@ -138,7 +139,7 @@ export class WorkflowService {
}
private async processSharedWorkflows(
workflows: ListQuery.Workflow.WithSharing[],
workflows: ListQueryDb.Workflow.WithSharing[],
options?: ListQuery.Options,
) {
const projectId = options?.filter?.projectId;
@@ -152,7 +153,7 @@ export class WorkflowService {
return workflows.map((workflow) => this.ownershipService.addOwnedByAndSharedWith(workflow));
}
private async addSharedRelation(workflows: ListQuery.Workflow.WithSharing[]): Promise<void> {
private async addSharedRelation(workflows: ListQueryDb.Workflow.WithSharing[]): Promise<void> {
const workflowIds = workflows.map((workflow) => workflow.id);
const relations = await this.sharedWorkflowRepository.getAllRelationsForWorkflows(workflowIds);
@@ -162,7 +163,7 @@ export class WorkflowService {
}
private async addUserScopes(
workflows: ListQuery.Workflow.Plain[] | ListQuery.Workflow.WithSharing[],
workflows: ListQueryDb.Workflow.Plain[] | ListQueryDb.Workflow.WithSharing[],
user: User,
) {
const projectRelations = await this.projectService.getProjectRelationsForUser(user);
@@ -173,7 +174,7 @@ export class WorkflowService {
}
private cleanupSharedField(
workflows: ListQuery.Workflow.Plain[] | ListQuery.Workflow.WithSharing[],
workflows: ListQueryDb.Workflow.Plain[] | ListQueryDb.Workflow.WithSharing[],
): void {
/*
This is to emulate the old behavior of removing the shared field as
@@ -187,7 +188,7 @@ export class WorkflowService {
private mergeProcessedWorkflows(
workflowsAndFolders: WorkflowFolderUnionFull[],
processedWorkflows: ListQuery.Workflow.Plain[] | ListQuery.Workflow.WithSharing[],
processedWorkflows: ListQueryDb.Workflow.Plain[] | ListQueryDb.Workflow.WithSharing[],
) {
const workflowMap = new Map(processedWorkflows.map((workflow) => [workflow.id, workflow]));

View File

@@ -9,7 +9,7 @@ import type { User } from '@/databases/entities/user';
import { ProjectRepository } from '@/databases/repositories/project.repository';
import { SharedCredentialsRepository } from '@/databases/repositories/shared-credentials.repository';
import { ProjectService } from '@/services/project.service.ee';
import type { ListQuery } from '@/types-db';
import type { ListQueryDb } from '@/types-db';
import { UserManagementMailer } from '@/user-management/email';
import { createWorkflow, shareWorkflowWithUsers } from '@test-integration/db/workflows';
@@ -134,13 +134,14 @@ describe('GET /credentials', () => {
expect(response.statusCode).toBe(200);
expect(response.body.data).toHaveLength(2); // owner retrieved owner cred and member cred
const ownerCredential: ListQuery.Credentials.WithOwnedByAndSharedWith = response.body.data.find(
(e: ListQuery.Credentials.WithOwnedByAndSharedWith) =>
const ownerCredential: ListQueryDb.Credentials.WithOwnedByAndSharedWith =
response.body.data.find(
(e: ListQueryDb.Credentials.WithOwnedByAndSharedWith) =>
e.homeProject?.id === ownerPersonalProject.id,
);
const memberCredential: ListQuery.Credentials.WithOwnedByAndSharedWith =
const memberCredential: ListQueryDb.Credentials.WithOwnedByAndSharedWith =
response.body.data.find(
(e: ListQuery.Credentials.WithOwnedByAndSharedWith) =>
(e: ListQueryDb.Credentials.WithOwnedByAndSharedWith) =>
e.homeProject?.id === member1PersonalProject.id,
);
@@ -205,7 +206,7 @@ describe('GET /credentials', () => {
expect(response.statusCode).toBe(200);
expect(response.body.data).toHaveLength(1); // member retrieved only member cred
const [member1Credential]: [ListQuery.Credentials.WithOwnedByAndSharedWith] =
const [member1Credential]: [ListQueryDb.Credentials.WithOwnedByAndSharedWith] =
response.body.data;
validateMainCredentialData(member1Credential);
@@ -536,7 +537,8 @@ describe('GET /credentials/:id', () => {
expect(firstResponse.statusCode).toBe(200);
const firstCredential: ListQuery.Credentials.WithOwnedByAndSharedWith = firstResponse.body.data;
const firstCredential: ListQueryDb.Credentials.WithOwnedByAndSharedWith =
firstResponse.body.data;
validateMainCredentialData(firstCredential);
expect(firstCredential.data).toBeUndefined();
@@ -593,7 +595,7 @@ describe('GET /credentials/:id', () => {
const response1 = await authOwnerAgent.get(`/credentials/${savedCredential.id}`).expect(200);
const credential: ListQuery.Credentials.WithOwnedByAndSharedWith = response1.body.data;
const credential: ListQueryDb.Credentials.WithOwnedByAndSharedWith = response1.body.data;
validateMainCredentialData(credential);
expect(credential.data).toBeUndefined();
@@ -617,7 +619,7 @@ describe('GET /credentials/:id', () => {
.query({ includeData: true })
.expect(200);
const credential2: ListQuery.Credentials.WithOwnedByAndSharedWith = response2.body.data;
const credential2: ListQueryDb.Credentials.WithOwnedByAndSharedWith = response2.body.data;
validateMainCredentialData(credential);
expect(credential2.data).toBeDefined(); // Instance owners should be capable of editing all credentials
@@ -645,7 +647,8 @@ describe('GET /credentials/:id', () => {
.get(`/credentials/${savedCredential.id}`)
.expect(200);
const firstCredential: ListQuery.Credentials.WithOwnedByAndSharedWith = firstResponse.body.data;
const firstCredential: ListQueryDb.Credentials.WithOwnedByAndSharedWith =
firstResponse.body.data;
validateMainCredentialData(firstCredential);
expect(firstCredential.data).toBeUndefined();
expect(firstCredential).toMatchObject({
@@ -676,7 +679,7 @@ describe('GET /credentials/:id', () => {
.query({ includeData: true })
.expect(200);
const secondCredential: ListQuery.Credentials.WithOwnedByAndSharedWith =
const secondCredential: ListQueryDb.Credentials.WithOwnedByAndSharedWith =
secondResponse.body.data;
validateMainCredentialData(secondCredential);
expect(secondCredential.data).toBeDefined();
@@ -1359,7 +1362,7 @@ describe('PUT /:credentialId/transfer', () => {
);
});
function validateMainCredentialData(credential: ListQuery.Credentials.WithOwnedByAndSharedWith) {
function validateMainCredentialData(credential: ListQueryDb.Credentials.WithOwnedByAndSharedWith) {
expect(typeof credential.name).toBe('string');
expect(typeof credential.type).toBe('string');
expect(credential.homeProject).toBeDefined();

View File

@@ -15,7 +15,7 @@ import { CredentialsRepository } from '@/databases/repositories/credentials.repo
import { ProjectRepository } from '@/databases/repositories/project.repository';
import { SharedCredentialsRepository } from '@/databases/repositories/shared-credentials.repository';
import { CredentialsTester } from '@/services/credentials-tester.service';
import type { ListQuery } from '@/types-db';
import type { ListQueryDb } from '@/types-db';
import {
decryptCredentialData,
@@ -74,7 +74,7 @@ beforeEach(async () => {
sharedCredentialsRepository = Container.get(SharedCredentialsRepository);
});
type GetAllResponse = { body: { data: ListQuery.Credentials.WithOwnedByAndSharedWith[] } };
type GetAllResponse = { body: { data: ListQueryDb.Credentials.WithOwnedByAndSharedWith[] } };
// ----------------------------------------
// GET /credentials - fetch all credentials
@@ -92,7 +92,7 @@ describe('GET /credentials', () => {
expect(response.body.data.length).toBe(2); // owner retrieved owner cred and member cred
const savedCredentialsIds = [savedOwnerCredentialId, savedMemberCredentialId];
response.body.data.forEach((credential: ListQuery.Credentials.WithOwnedByAndSharedWith) => {
response.body.data.forEach((credential: ListQueryDb.Credentials.WithOwnedByAndSharedWith) => {
validateMainCredentialData(credential);
expect('data' in credential).toBe(false);
expect(savedCredentialsIds).toContain(credential.id);
@@ -1502,7 +1502,7 @@ const INVALID_PAYLOADS = [
undefined,
];
function validateMainCredentialData(credential: ListQuery.Credentials.WithOwnedByAndSharedWith) {
function validateMainCredentialData(credential: ListQueryDb.Credentials.WithOwnedByAndSharedWith) {
const { name, type, sharedWithProjects, homeProject, isManaged } = credential;
expect(typeof name).toBe('string');
@@ -1522,7 +1522,9 @@ function validateMainCredentialData(credential: ListQuery.Credentials.WithOwnedB
}
}
function validateCredentialWithNoData(credential: ListQuery.Credentials.WithOwnedByAndSharedWith) {
function validateCredentialWithNoData(
credential: ListQueryDb.Credentials.WithOwnedByAndSharedWith,
) {
validateMainCredentialData(credential);
expect('data' in credential).toBe(false);

View File

@@ -13,7 +13,7 @@ import type { WorkflowFolderUnionFull } from '@/databases/repositories/workflow.
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
import { License } from '@/license';
import { ProjectService } from '@/services/project.service.ee';
import type { ListQuery } from '@/types-db';
import type { ListQueryDb } from '@/types-db';
import { EnterpriseWorkflowService } from '@/workflows/workflow.service.ee';
import { createFolder } from '@test-integration/db/folders';
@@ -641,7 +641,7 @@ describe('GET /workflows', () => {
});
const found = response.body.data.find(
(w: ListQuery.Workflow.WithOwnership) => w.name === 'First',
(w: ListQueryDb.Workflow.WithOwnership) => w.name === 'First',
);
expect(found.nodes).toBeUndefined();
@@ -1458,7 +1458,7 @@ describe('GET /workflows?includeFolders=true', () => {
});
const found = response.body.data.find(
(w: ListQuery.Workflow.WithOwnership) => w.name === 'First',
(w: ListQueryDb.Workflow.WithOwnership) => w.name === 'First',
);
expect(found.nodes).toBeUndefined();